home
readme
diff
tree
note
docs
0commit 512a088701c72825340ba257a5f5f26d652139d0
1Author: lakefox <mason@lakefox.net>
2Date: Sat Mar 14 20:38:50 2026 -0600
3
4 Wrath will run some code!
5
6diff --git a/Makefile b/Makefile
7index 551455a..a1e11cb 100755
8--- a/Makefile
9+++ b/Makefile
10@@ -71,6 +71,9 @@ build/html_parser_playground: playground/html_parser.c build/grim.o build/parser
11 build/css_unit_playground: playground/css_unit.c build/grim.o build/parser.o | build
12 ${CC} ${CCFLAGS} -Iinclude/ playground/css_unit.c build/grim.o build/parser.o -o build/css_unit_playground
13
14+build/unit_value_playground: playground/unit_value.c build/grim.o build/parser.o | build
15+ ${CC} ${CCFLAGS} -Iinclude/ playground/unit_value.c build/grim.o build/parser.o -o build/unit_value_playground
16+
17
18
19 # --- Prebuild ---
20diff --git a/include/grim.h b/include/grim.h
21index c5406ec..3cb8510 100755
22--- a/include/grim.h
23+++ b/include/grim.h
24@@ -79,7 +79,7 @@ typedef enum {
25 NEAREST, UP, DOWN, TO_ZERO,
26
27 // Keyword
28- SCREEN, TOKEN, NO_SUPPORT, IMAGE, STRING, BOOL, VAR, NONOP, ELSE, TAG, CHAR, JUMP,
29+ SCREEN, TOKEN, NO_SUPPORT, IMAGE, BOOL, VAR, PTR, TAG, CHAR, JUMP, FREE,
30
31 FUNC_START,
32 // General Functions
33@@ -87,7 +87,7 @@ typedef enum {
34 HYPOT, LOG, EXP, ABS, SIGN, SIN, COS, TAN, ASIN, ACOS, ATAN, ATAN2, VAR_FUNC,
35 BLUR, BRIGHTNESS, CONTRAST, DROP_SHADOW, GRAYSCALE, HUE_ROTATE, INVERT,
36 OPACITY, SEPIA, SATURATE, ATTR, TYPE, ENV, IF, FUNC, LET, RETURN, SET,
37- LIST, AT, EMPTY, INSERT, SIZE, WHILE, PRINT,
38+ AT, EMPTY, APPEND, WHILE, PRINT, LENGTH, CAPACITY,
39
40 // Easing Functions
41 EASING_FUNCTION, LINEAR_EASING_FUNCTION, LINEAR, EASE, EASE_IN, EASE_OUT, EASE_IN_OUT, CUBIC_BEZIER_FUNCTION,
42@@ -104,7 +104,8 @@ typedef enum {
43 URL, IMAGE_SET, CROSS_FADE, ELEMENT, GROUP, GRADIENT,
44
45 // Operator
46- EQ, LT, GT, LE, GE, ADD, SUB, MULT, DIV,
47+ OP_START,
48+ EQ = OP_START, LT, GT, LE, GE, ADD, SUB, MULT, DIV,
49
50 // Logic
51 AND, OR, NOT, ONLY, COMMA,
52@@ -122,6 +123,12 @@ struct Unit {
53 float value;
54 };
55
56+struct Slot {
57+ struct Unit* data;
58+ int length;
59+ int capacity;
60+};
61+
62 typedef struct {
63 char key[MAX_STR_LEN];
64 char value[MAX_STR_LEN];
65@@ -192,4 +199,6 @@ void ADD_CLASS(Node* n, char* value);
66
67 void get_unit(struct Unit** units, int* cap, int* units_len, char** vars, int* vars_len, int* vars_cap, int* stack_len, int* max_register_size, char* value);
68
69+float unit_value(struct Slot stack[], int stack_size, int register_size, struct Unit* units, int units_len);
70+
71 #endif // NODE_H
72diff --git a/maps/functions.gperf b/maps/functions.gperf
73index 4fd0710..1352a4d 100644
74--- a/maps/functions.gperf
75+++ b/maps/functions.gperf
76@@ -88,9 +88,9 @@ type, TYPE
77 env, ENV
78 if, IF
79 print, PRINT
80-list, LIST
81 at, AT
82 empty, EMPTY
83-insert, INSERT
84-size, SIZE
85+length, LENGTH
86+capacity, CAPACITY
87+append, APPEND
88 %%
89diff --git a/maps/match.gperf b/maps/match.gperf
90index bbb5494..c8a69d9 100644
91--- a/maps/match.gperf
92+++ b/maps/match.gperf
93@@ -31,7 +31,6 @@ or, OR
94 not, NOT
95 "!=", NOT
96 only, ONLY
97-else, ELSE
98 infinity, INF
99 -infinity, NEGINF
100 NaN, NaN
101diff --git a/playground/css_unit.c b/playground/css_unit.c
102index 7902943..371b9d4 100644
103--- a/playground/css_unit.c
104+++ b/playground/css_unit.c
105@@ -106,7 +106,7 @@ int main() {
106 int stack_len = 0;
107 int max_register_size = 0;
108
109- char* ustr = "(if(style(--scheme) == dark #eeeeee))";
110+ char* ustr = "(let(x :name \"john doe\" :age 27))";
111
112 get_unit(&units, &cap, &units_len, &vars, &vars_len, &vars_cap, &stack_len, &max_register_size, ustr);
113
114@@ -116,24 +116,52 @@ int main() {
115 free(vars);
116
117 if (true) {
118- //benchmark_get_unit(ustr);
119-
120- test_get_unit("1 + 1", (struct Unit[]){{NUMBER, 1}, {NUMBER, 1}, {ADD, 2}}, 3, 0, 2);
121- test_get_unit("23px * 5678.7%", (struct Unit[]){{PX, 23}, {PERCENT, 5678.7f}, {MULT, 2}}, 3, 0, 2);
122- test_get_unit("calc(23px * size)", (struct Unit[]){{PX, 23}, {VAR, -1}, {MULT, 2}, {CALC, 1}}, 4, 0, 3);
123- test_get_unit("(let(x 10px) set(x 30px) (let(x 50px) print(x)) print(x))", (struct Unit[]){{VAR, 0}, {PX, 10}, {LET, 2}, {VAR, 0}, {PX, 30}, {SET, 2}, {VAR, 1}, {PX, 50}, {LET, 2}, {VAR, 1}, {PRINT, 1}, {GROUP, 2}, {VAR, 0}, {PRINT, 1}, {GROUP, 4}}, 15, 2, 14);
124- // test_get_unit("(min(x 10px) set(x 30px) (min(x 50px) print(x)) print(x))", (struct Unit[]){{VAR, -1}, {PX, 10}, {MIN, 2}, {VAR, -1}, {PX, 30}, {SET, 2}, {VAR, -1}, {PX, 50}, {MIN, 2}, {VAR, -1}, {PRINT, 1}, {GROUP, 2}, {VAR, -1}, {PRINT, 1}, {GROUP, 4}}, 15, 0, 14);
125+ benchmark_get_unit(ustr);
126+
127+ test_get_unit("1 + 1",
128+ (struct Unit[]){{NUMBER, 1}, {NUMBER, 1}, {ADD, 2}},
129+ 3, 0, 2
130+ );
131+ test_get_unit("23px * 5678.7%",
132+ (struct Unit[]){{PX, 23}, {PERCENT, 5678.7f}, {MULT, 2}},
133+ 3, 0, 2
134+ );
135+ test_get_unit("calc(23px * size)",
136+ (struct Unit[]){{PX, 23}, {VAR, -1}, {MULT, 2}, {CALC, 1}},
137+ 4, 0, 3
138+ );
139+ test_get_unit("(let(x 10px) set(x 30px) (let(x 50px) print(x)) print(x))",
140+ (struct Unit[]){{PTR, 0}, {PX, 10}, {LET, 2}, {PTR, 0}, {PX, 30}, {SET, 2}, {PTR, 1}, {PX, 50}, {LET, 2}, {VAR, 1}, {PRINT, 1}, {GROUP, 2}, {VAR, 0}, {PRINT, 1}, {GROUP, 4}},
141+ 15, 2, 14
142+ );
143 test_get_unit("((let(x 10px) set(x x * 2%) print(x)) (let(y 10px) set(y y * 2) print(y)))", (struct Unit[]){
144- {VAR, 0}, {PX, 10}, {LET, 2},
145- {VAR, 0}, {VAR, 0}, {PERCENT, 2}, {MULT, 2}, {SET, 2},
146+ {PTR, 0}, {PX, 10}, {LET, 2},
147+ {PTR, 0}, {VAR, 0}, {PERCENT, 2}, {MULT, 2}, {SET, 2},
148 {VAR, 0}, {PRINT, 1},
149 {GROUP, 3},
150- { VAR, 0}, {PX, 10}, {LET, 2},
151- {VAR, 0}, {VAR, 0}, {NUMBER, 2}, {MULT, 2}, {SET, 2},
152+ { PTR, 0}, {PX, 10}, {LET, 2},
153+ {PTR, 0}, {VAR, 0}, {NUMBER, 2}, {MULT, 2}, {SET, 2},
154 {VAR, 0}, {PRINT, 1},
155 {GROUP, 3},
156 {GROUP, 2}}
157 , 23, 1, 22);
158- test_get_unit("(let(x :name \"john doe\" :age 27))", (struct Unit[]){{VAR, 0}, {TAG, 1035}, {STRING, 8}, {CHAR, 106}, {CHAR, 111}, {CHAR, 104}, {CHAR, 110}, {CHAR, 32}, {CHAR, 100}, {CHAR, 111}, {CHAR, 101}, {TAG, 606}, {NUMBER, 27}, {LET, 13}, {GROUP, 1}}, 15, 1, 14);
159+ test_get_unit("(let(x :name \"john doe\" :age 27))",
160+ (struct Unit[]){{PTR, 0}, {TAG, 1035}, {CHAR, 106}, {CHAR, 111}, {CHAR, 104}, {CHAR, 110}, {CHAR, 32}, {CHAR, 100}, {CHAR, 111}, {CHAR, 101}, {TAG, 606}, {NUMBER, 27}, {LET, 12}, {GROUP, 1}},
161+ 14, 1, 13
162+ );
163+ test_get_unit("(if((style(--scheme) == dark) calc(#eeeeee == '1')))",
164+ (struct Unit[]){{VAR, -1}, {FUNC, 1}, {VAR, -1}, {EQ, 2}, {GROUP, 1}, {IF, 5}, {HEX, 2.19425599e-38}, {CHAR, 49}, {EQ, 2}, {CALC, 1}, {GROUP, 1}},
165+ 11, 0, 10
166+ );
167+
168+ test_get_unit("(if((style(--scheme) == dark) calc(#eeeeee == '1') print(123)))",
169+ (struct Unit[]){{VAR, -1}, {FUNC, 1}, {VAR, -1}, {EQ, 2}, {GROUP, 1}, {IF, 6}, {HEX, 2.19425599e-38}, {CHAR, 49}, {EQ, 2}, {CALC, 1}, {JUMP, 3}, {NUMBER, 123}, {PRINT, 1}, {GROUP, 3}},
170+ 14, 0, 13
171+ );
172+
173+ test_get_unit("(if((style(--scheme) == dark) calc(#eeeeee == calc(123)) print(123)))",
174+ (struct Unit[]){{VAR, -1}, {FUNC, 1}, {VAR, -1}, {EQ, 2}, {GROUP, 1}, {IF, 7}, {HEX, 2.19425599e-38}, {NUMBER, 123}, {CALC, 1}, {EQ, 2}, {CALC, 1}, {JUMP, 3}, {NUMBER, 123}, {PRINT, 1}, {GROUP, 3}},
175+ 15, 0, 14
176+ );
177 }
178 }
179diff --git a/playground/syntax.wr b/playground/syntax.wr
180index 7fd64d2..834307b 100644
181--- a/playground/syntax.wr
182+++ b/playground/syntax.wr
183@@ -156,4 +156,48 @@ Context -> width -> screen -> etc
184 NUM 0, NUM 10, RANGE 2, SCOPE 1, PRINT 1, GROUP 1, FOR 2
185
186
187+
188+ let(x (
189+ name(19)
190+ age("john")
191+ )
192+
193+ get(x, age)
194+
195+ let(x :name 19
196+ :age "john"
197+ )
198+
199+ let(x 19 pad("john", 20))
200+
201+ set(at(y 0) x)
202+
203+ TAG 1223, NUMBER 19, GROUP 2, TAG 453, CHAR 23, CHAR 34, CHAR 89, CHAR 32, STRING 4, GROUP 2, LET 3
204+
205+ let(x (
206+ (:name 19)
207+ (:age "john")
208+ (:chidlren (
209+ (
210+ (:name 19)
211+ (:age "john")
212+ )
213+ ))
214+ )
215+ )
216+
217+ let(x (
218+ :name 19
219+ :age john
220+ :children
221+ :name 18
222+ :age "Mike"
223+ :children
224+ :etc..
225+
226+ ))
227+
228+ let(x list(256))
229+ set(at(x 0) "str")
230+
231 )
232diff --git a/playground/unit_value.c b/playground/unit_value.c
233new file mode 100644
234index 0000000..f86853e
235--- /dev/null
236+++ b/playground/unit_value.c
237@@ -0,0 +1,64 @@
238+#define _POSIX_C_SOURCE 199309L
239+#include <stdio.h>
240+#include <stdlib.h>
241+#include <time.h>
242+#include <string.h>
243+#include <assert.h>
244+
245+#include "../include/grim.h"
246+#include "../include/parser.h"
247+
248+void benchmark_unit_value(char* value) {
249+ struct timespec start, end;
250+
251+ int iterations = 10000;
252+
253+ // Get start time
254+ clock_gettime(CLOCK_MONOTONIC, &start);
255+
256+
257+ // Get end time
258+ clock_gettime(CLOCK_MONOTONIC, &end);
259+
260+ // Calculate time difference in seconds
261+ double total_time = (end.tv_sec - start.tv_sec) + (end.tv_nsec - start.tv_nsec) / 1e9;
262+ printf("Average execution time: %.9f seconds (%f us)\n",
263+ total_time / iterations,
264+ (total_time / iterations) * 1000000);
265+}
266+
267+void test_unit_value(char* ustr, struct Unit* known_units, int known_units_len, int stack_size, int known_register_size) {
268+}
269+
270+int main() {
271+ int cap = 10;
272+ struct Unit *units = malloc(sizeof(struct Unit) * cap);
273+ int units_len = 0;
274+
275+ int vars_cap = 0;
276+ char **vars = NULL;
277+ int vars_len = 0;
278+
279+ int stack_len = 0;
280+ int max_register_size = 0;
281+
282+ char* ustr = "max(10 1)";
283+
284+ get_unit(&units, &cap, &units_len, &vars, &vars_len, &vars_cap, &stack_len, &max_register_size, ustr);
285+
286+ printf("Stack Size: %d Registers: %d Unit Length: %d\n", stack_len, max_register_size, units_len);
287+
288+ struct Slot stack[stack_len || 1];
289+
290+ float v = unit_value(&stack, stack_len, max_register_size, units, units_len);
291+
292+ printf("Value: %f\n", v);
293+
294+ free(units);
295+ free(vars);
296+
297+ if (true) {
298+ //benchmark_unit_value(ustr);
299+
300+ }
301+}
302diff --git a/playground/unitvalue.cc b/playground/unitvalue.cc
303deleted file mode 100644
304index 5d63723..0000000
305--- a/playground/unitvalue.cc
306+++ /dev/null
307@@ -1,63 +0,0 @@
308-#include "../include/grim.h"
309-#include "../include/parser.h"
310-#include <string>
311-#include <sstream>
312-#include <vector>
313-#include <iostream>
314-
315-int main() {
316- /*std::string html = "<!DOCTYPE html>"
317- "<html>"
318- "<head>"
319- "<title>This is a simple test</title>"
320- "<link rel=\"stylesheet\" href=\'tests/style.css\'/>"
321- "<style>h1 {background: red;}</style>"
322- "</head>"
323- "<body>"
324- "<h1 id=\"h1Tag\">Header</h1>"
325- "<p id=\"paragraph\" class=\"class1 class2\">This is some text for a simple test</p>"
326- "<div contenteditable=\"true\">"
327- "<p>this is a only child</p>"
328- "</div>"
329- "<input type=\"text\" checked required/>"
330- "<ul>"
331- "<li>one</li>"
332- "<li>two</li>"
333- "<li>three</li>"
334- "<li>four</li>"
335- "</ul>"
336- "<input type=\"radio\" checked required/>"
337- "<input type=\"text\" readonly/>"
338- "<input type=\"text\" disabled/>"
339- "<textarea></textarea>"
340- "<textarea readonly></textarea>"
341- "<textarea disabled></textarea>"
342- "</body>"
343- "</html>";
344-
345-
346- std::stringstream ss(html);
347-
348- Window window = createWindow();
349- window.parseHTML(ss);
350-
351- Node document = window.document;
352-
353- document.cacheWidth(1000);
354- document.cacheHeight(700);
355- document.cacheEM(16);*/
356-
357- SymbolTable sym{};
358-
359- Memory m;
360- // Preset width, height, and em
361- m.push_back(sym.get("width"),{UnitType::NUMBER, 1000.0f});
362- m.push_back(sym.get("height"),{UnitType::NUMBER, 700.0f});
363- m.push_back(sym.get("em"),{UnitType::NUMBER, 16.0f});
364-
365- std::vector<Unit> units = getUnit("list(x 1 7 3 4 5) list(y 7 8 x 9 0) at(at(y 2) 4)", &sym);
366-
367- Unit u = UnitValue(m, units, 0, units.size());
368-
369- std::cout << "Value: " << u.value << std::endl;
370-}
371diff --git a/src/grim.c b/src/grim.c
372index b88c795..93b92fd 100755
373--- a/src/grim.c
374+++ b/src/grim.c
375@@ -423,49 +423,28 @@ std::vector<std::string> parseNodeParts(Node* node) {
376 return parts;
377 }
378
379+*/
380+
381 // +------------------------------------------------------+
382 // |(7tygl) Query matching |
383 // +------------------------------------------------------+
384 // testQuery tries to calculate if the query (ie a media query or
385 // container query) applies to the node passed
386
387-Range getNextUnit(const std::vector<Unit>& units, size_t& offset, size_t end) {
388- if (offset >= end) return {0, 0}; // Done
389-
390- size_t start = offset;
391- const Unit& unit = units[offset];
392-
393- if (unit.type > FUNC_START) {
394- // Range is the function unit + its body
395- size_t argEnd = offset + unit.value + 1;
396- offset = argEnd; // Move offset past this function for next time
397- return {start, argEnd};
398- } else {
399- offset += 1; // Move offset to next unit
400- return {start, start + 1};
401- }
402-}
403-
404 // HEAP: [width, height, em, dpi]
405 // HEAP LAYOUT: VAR
406
407-float unit_value(struct Units[]** stack, int register_size, int heap_size, struct Unit** units, int* units_len) {
408- struct Unit** heap[heap_size];
409- int heap[heap_size] = {0};
410-
411- struct Unit registers[register_size] = {0};
412+float unit_value(struct Slot stack[], int stack_size, int register_size, struct Unit* units, int units_len) {
413+ struct Unit registers[register_size];
414 int register_len = 0;
415
416- // Pre-alloc
417- for (int i = 0; i < heap_size; i++) {
418- heap[8] = malloc(sizeof(struct Unit) * 32);
419- }
420-
421 for (int i = 0; i < units_len; i++) {
422- struct Unit unit = units.units[i];
423+ printf("%d\n", i);
424+ struct Unit unit = units[i];
425 UnitType type = unit.type;
426
427- int idx = register_len-unit.value;
428+ int idx = (register_len-unit.value) || 0;
429+ printf("IDX: %d Reg Len: %d Unit: %f\n", idx, register_len, unit.value);
430
431 switch (type) {
432 // DEG, TURN are not length values but are treated as generic units (PX)
433@@ -474,38 +453,38 @@ float unit_value(struct Units[]** stack, int register_size, int heap_size, struc
434 case NUMBER:
435 // NUMBER is any untyped numbers "2". Treat as a pixel
436 case PX: {
437- register[register_len].type = NUMBER;
438- register[register_len++].value = unit.value;
439+ registers[register_len].type = NUMBER;
440+ registers[register_len++].value = unit.value;
441 break;
442 }
443 case CM: {
444- register[register_len].type = NUMBER;
445- register[register_len++].value = unit.value*37.8f;
446+ registers[register_len].type = NUMBER;
447+ registers[register_len++].value = unit.value*37.8f;
448 break;
449 }
450 case MM: {
451- register[register_len].type = NUMBER;
452- register[register_len++].value = unit.value*3.78f;
453+ registers[register_len].type = NUMBER;
454+ registers[register_len++].value = unit.value*3.78f;
455 break;
456 }
457 case Q: {
458- register[register_len].type = NUMBER;
459- register[register_len++].value = unit.value*0.94f;
460+ registers[register_len].type = NUMBER;
461+ registers[register_len++].value = unit.value*0.94f;
462 break;
463 }
464 case IN: {
465- register[register_len].type = NUMBER;
466- register[register_len++].value = unit.value*96.0f;
467+ registers[register_len].type = NUMBER;
468+ registers[register_len++].value = unit.value*96.0f;
469 break;
470 }
471 case PC: {
472- register[register_len].type = NUMBER;
473- register[register_len++].value = unit.value*16.0f;
474+ registers[register_len].type = NUMBER;
475+ registers[register_len++].value = unit.value*16.0f;
476 break;
477 }
478 case PT: {
479- register[register_len].type = NUMBER;
480- register[register_len++].value = unit.value*1.3f;
481+ registers[register_len].type = NUMBER;
482+ registers[register_len++].value = unit.value*1.3f;
483 break;
484 }
485 case EM:
486@@ -519,20 +498,20 @@ float unit_value(struct Units[]** stack, int register_size, int heap_size, struc
487 case RCH:
488 case RIC:
489 case RLH: {
490- register[register_len].type = NUMBER;
491- register[register_len++].value = unit.value*stack[2].value;
492+ registers[register_len].type = NUMBER;
493+ registers[register_len++].value = unit.value*stack[2].data[0].value;
494 break;
495 }
496 case EX:
497 case REX: {
498- register[register_len].type = NUMBER;
499- register[register_len++].value = unit.value*(heap.units[2].value*0.5f);
500+ registers[register_len].type = NUMBER;
501+ registers[register_len++].value = unit.value*(stack[2].data[0].value*0.5f);
502 break;
503 }
504 case CQH:
505 case VH: {
506- register[register_len].type = NUMBER;
507- register[register_len++].value = heap.units[1].value*(unit.value*0.01f);
508+ registers[register_len].type = NUMBER;
509+ registers[register_len++].value = stack[1].data[0].value*(unit.value*0.01f);
510 break;
511 }
512 case CQW:
513@@ -540,50 +519,51 @@ float unit_value(struct Units[]** stack, int register_size, int heap_size, struc
514 case CQB:
515 case PERCENT:
516 case VW: {
517- register[register_len].type = NUMBER;
518- register[register_len++].value = heap.units[0].value*(unit.value*0.01f);
519+ registers[register_len].type = NUMBER;
520+ registers[register_len++].value = stack[0].data[0].value*(unit.value*0.01f);
521 break;
522 }
523 case VMAX:
524 case CQMAX: {
525- register[register_len].type = NUMBER;
526+ registers[register_len].type = NUMBER;
527 // 0: width
528 // 1: height
529- if (heap.units[0].value > heap.units[1].value) {
530- register[register_len++].value = unit.value*heap.units[0].value;
531+ if (stack[0].data[0].value > stack[1].data[0].value) {
532+ registers[register_len++].value = unit.value*stack[0].data[0].value;
533 } else {
534- register[register_len++].value = unit.value*heap.units[1].value;
535+ registers[register_len++].value = unit.value*stack[1].data[0].value;
536 }
537 break;
538 }
539 case VMIN:
540 case CQMIN: {
541- register[register_len].type = NUMBER;
542- if (heap.units[0].value < heap.units[1].value) {
543- register[register_len++].value = unit.value*heap.units[0].value;
544+ registers[register_len].type = NUMBER;
545+ if (stack[0].data[0].value < stack[1].data[0].value) {
546+ registers[register_len++].value = unit.value*stack[0].data[0].value;
547 } else {
548- register[register_len++].value = unit.value*heap.units[1].value;
549+ registers[register_len++].value = unit.value*stack[1].data[0].value;
550 }
551 break;
552 }
553 case VB:
554 case VI: {
555- register[register_len].type = NUMBER;
556- register[register_len++].value = unit.value*heap.units[0].value;
557+ registers[register_len].type = NUMBER;
558+ registers[register_len++].value = unit.value*stack[0].data[0].value;
559 break;
560 }
561- case GROUP:
562- case CALC: {
563+ case CALC:
564+ case GROUP: {
565 // Take the last computed value in the group and move it to the front
566- registers[idx] = registers[register_len-1];
567- register_len = idx;
568+ registers[idx] = registers[register_len];
569+
570+ register_len = idx-(int)unit.value;
571 break;
572 }
573 case MIN: {
574 registers[idx].type = NUMBER;
575
576 for (int j = idx+1; j < register_len; j++) {
577- if (registers[idx] > registers[j]) {
578+ if (registers[idx].value > registers[j].value) {
579 registers[idx] = registers[j];
580 }
581 }
582@@ -594,7 +574,7 @@ float unit_value(struct Units[]** stack, int register_size, int heap_size, struc
583 registers[idx].type = NUMBER;
584
585 for (int j = idx+1; j < register_len; j++) {
586- if (registers[idx] < registers[j]) {
587+ if (registers[idx].value < registers[j].value) {
588 registers[idx] = registers[j];
589 }
590 }
591@@ -604,11 +584,11 @@ float unit_value(struct Units[]** stack, int register_size, int heap_size, struc
592 case CLAMP: {
593 if (unit.value == 3) {
594 // if idx+1 (val) is greater than idx+2 (max)
595- if (registers[idx+1] > registers[idx+2]) {
596+ if (registers[idx+1].value > registers[idx+2].value) {
597 // set idx (min also the return value) to idx+2 (max)
598 registers[idx] = registers[idx+2];
599 // if idx+1 > idx (min) then set idx (return) to idx+1 (val)
600- } else if (registers[idx+1] > registers[idx]) {
601+ } else if (registers[idx+1].value > registers[idx].value) {
602 registers[idx] = registers[idx+1];
603 }
604 // if the value is less than idx (min) then idx (return) remains the same
605@@ -661,38 +641,38 @@ float unit_value(struct Units[]** stack, int register_size, int heap_size, struc
606 break;
607 }
608 case SIN: {
609- register[idx].value = sinf(register[idx].value);
610+ registers[idx].value = sinf(registers[idx].value);
611 registers[idx].type = NUMBER;
612 break;
613 }
614 case COS: {
615- register[idx].value = cosf(register[idx].value);
616+ registers[idx].value = cosf(registers[idx].value);
617 registers[idx].type = NUMBER;
618 break;
619 }
620 case TAN: {
621- register[idx].value = tanf(register[idx].value);
622+ registers[idx].value = tanf(registers[idx].value);
623 registers[idx].type = NUMBER;
624 break;
625 }
626 case ASIN: {
627- register[idx].value = asinf(register[idx].value);
628+ registers[idx].value = asinf(registers[idx].value);
629 registers[idx].type = NUMBER;
630 break;
631 }
632 case ACOS: {
633- register[idx].value = acosf(register[idx].value);
634+ registers[idx].value = acosf(registers[idx].value);
635 registers[idx].type = NUMBER;
636 break;
637 }
638 case ATAN: {
639- register[idx].value = atanf(register[idx].value);
640+ registers[idx].value = atanf(registers[idx].value);
641 registers[idx].type = NUMBER;
642 break;
643 }
644 case ATAN2: {
645 if (unit.value == 2) {
646- register[idx].value = atan2f(register[idx].value, register[idx + 2].value);
647+ registers[idx].value = atan2f(registers[idx].value, registers[idx + 2].value);
648 }
649
650 registers[idx].type = NUMBER;
651@@ -701,7 +681,7 @@ float unit_value(struct Units[]** stack, int register_size, int heap_size, struc
652 }
653 case POW: {
654 if (unit.value == 2) {
655- register[idx].value = powf(register[idx].value, register[idx + 2].value);
656+ registers[idx].value = powf(registers[idx].value, registers[idx + 2].value);
657 }
658
659 registers[idx].type = NUMBER;
660@@ -709,14 +689,14 @@ float unit_value(struct Units[]** stack, int register_size, int heap_size, struc
661 break;
662 }
663 case SQRT: {
664- register[idx].value = sqrtf(register[idx].value);
665+ registers[idx].value = sqrtf(registers[idx].value);
666 registers[idx].type = NUMBER;
667 break;
668 }
669 case HYPOT: {
670 float v = 0;
671
672- for (float j = idx; j < register_len; j++) {
673+ for (int j = idx; j < register_len; j++) {
674 v += registers[j].value * registers[j].value;
675 }
676
677@@ -738,12 +718,12 @@ float unit_value(struct Units[]** stack, int register_size, int heap_size, struc
678 break;
679 }
680 case EXP: {
681- register[idx].value = expf(register[idx].value);
682+ registers[idx].value = expf(registers[idx].value);
683 registers[idx].type = NUMBER;
684 break;
685 }
686 case ABS: {
687- register[idx].value = absf(register[idx].value);
688+ registers[idx].value = fabsf(registers[idx].value);
689 registers[idx].type = NUMBER;
690 break;
691 }
692@@ -763,12 +743,12 @@ float unit_value(struct Units[]** stack, int register_size, int heap_size, struc
693 // ATTR and VAR_FUNC don't need to get the value of the VAR only check to see if its
694 // been replaced, if not provide a default
695 if (registers[idx].type == VAR) {
696- if (units.value > 2) {
697+ if (unit.value > 2) {
698 registers[idx] = registers[idx + 2];
699 }
700 }
701- if (units.value > 1) {
702- registers[idx] = registers[idx + 1].type;
703+ if (unit.value > 1) {
704+ registers[idx].type = registers[idx + 1].type;
705 }
706 register_len = idx;
707 break;
708@@ -778,7 +758,7 @@ float unit_value(struct Units[]** stack, int register_size, int heap_size, struc
709 }
710 case VAR_FUNC: {
711 if (registers[idx].type == VAR) {
712- if (units.value > 1) {
713+ if (unit.value > 1) {
714 registers[idx] = registers[idx + 1];
715 }
716 }
717@@ -788,266 +768,186 @@ float unit_value(struct Units[]** stack, int register_size, int heap_size, struc
718 case VAR: {
719 if (registers[idx].type == VAR) {
720 if (registers[idx].value > -1) {
721- registers[idx].value = stack[registers[idx].value];
722+ if (stack[(int)registers[idx].value].length > 0) {
723+ registers[register_len++] = stack[(int)registers[idx].value].data[0];
724+ } else {
725+ registers[register_len++].type = NUMBER;
726+ registers[register_len++].value = 0.0f;
727+ }
728 }
729 }
730
731 break;
732 }
733+ case PTR: {
734+ registers[register_len++] = unit;
735+ break;
736+
737+ }
738 case PRINT: {
739 printf("> %f", registers[idx].value);
740 break;
741 }
742+ case JUMP: {
743+ i += unit.value;
744+ }
745 case IF: {
746- Range args[4]; // condition trueval else falseval
747- int found = 0;
748- size_t start = i + 1;
749- size_t end = i + 1 + unit.value;
750-
751- while (start < end) {
752- args[found++] = getNextUnit(units, start, end);
753+ // All the if statement need to do is to check if the last register is false. If it is then it will jump the amount of the value
754+ // if it is true it will continue over it. If there is a else once the program hits the JUMP it will skip else
755+ if (!registers[idx].value) {
756+ i += unit.value;
757 }
758-
759- bool condition = UnitValue(m, units, args[0].start, args[0].end).value;
760-
761- if (condition) {
762- iv = UnitValue(m, units, args[1].start, args[1].end);
763- } else {
764- UnitType u = units[args[2].start].type;
765- if (u == ELSE) {
766- iv = UnitValue(m, units, args[3].start, args[3].end);
767- } else {
768- iv = UnitValue(m, units, args[2].start, args[2].end);
769- }
770- }
771-
772-
773- i += unit.value;
774 break;
775 }
776- case LET: {
777- Unit u = UnitValue(m, units, i + 2, i + 1 + unit.value);
778- m.push_back(units[i+1].value, u);
779-
780- i += unit.value;
781+ case EMPTY: {
782+ for (int j = 0; j < unit.value; j++) {
783+ struct Unit e;
784+ e.type = FREE;
785+ e.value = 0;
786+ registers[register_len++] = e;
787+ }
788 break;
789 }
790- case SET: {
791- if (units[i + 1].type == VAR) {
792- Range r = m.get(units[i + 1].value);
793- Unit u = UnitValue(m, units, i + 2, i + 1 + unit.value);
794-
795- // r.end is the length
796- if (r.end > 0) { // need to write over
797- heap.units[r.start] = u;
798- }
799- } else if (units[i + 1].type == AT && units[i + 2].type == VAR) {
800- // Set at in a list
801- Range r = m.get(units[i+2].value);
802-
803-
804-
805- // same at at()
806- // for tagged props pad with TEST 0 values
807-
808-
809+ case LET: {
810+ if (stack[(int)registers[idx].value].capacity < unit.value || stack[(int)registers[idx].value].capacity/2 > unit.value) {
811+ free(stack[(int)registers[idx].value].data);
812+ stack[(int)registers[idx].value].data = malloc(unit.value * sizeof(struct Unit));
813+ stack[(int)registers[idx].value].capacity = unit.value;
814+ }
815
816+ stack[(int)registers[idx].value].length = 0;
817
818- if (r.end > 0) {
819- Unit p = UnitValue(m, units, i + 2, i + 1 + units[i+2].value);
820- Unit u = UnitValue(m, units, i + 2, i + 1 + unit.value);
821- heap.units[r.start + p.value] = u;
822+ for (int j = idx; j < idx+unit.value; j++) {
823+ if (registers[j].type != FREE) {
824+ stack[(int)registers[idx].value].length++;
825+ stack[(int)registers[idx].value].data[j-idx] = registers[j];
826 }
827 }
828-
829- i += unit.value;
830+ register_len = idx;
831 break;
832- }
833- case LIST: {
834-
835-
836-
837-
838-
839- // This needs to deference all values and store them
840- // also needs to add a LIST length marker
841- // needs to support
842- //list(x :name empty(10)
843- // :age empty(3)
844- //)
845- // fill with TEST 0 so when at is ran it can trim the value because TEST is not valid
846-
847-
848-
849-
850-
851-
852- if (units[i + 2].type == EMPTY) {
853- Unit emptyCount = UnitValue(m, units, i+3, i + 3 +units[i + 2].value);
854- m.alloc(units[i+1].value, emptyCount.value);
855+ }
856+ case SET: {
857+ if (unit.value == 3) {
858+ // AT
859+ if (stack[(int)registers[idx].value].capacity >= registers[idx+1].value) {
860+ stack[(int)registers[idx].value].data[(int)registers[idx + 1].value] = registers[idx + 2];
861+ }
862 } else {
863- m.push(units[i+1].value, units, i+2, i+1+unit.value);
864+ stack[(int)registers[idx].value].data[0] = registers[idx + 1];
865 }
866
867- i += unit.value;
868+ register_len = idx;
869 break;
870- }
871+ }
872 case AT: {
873- Range r = m.get(units[i+1].value);
874-
875- if (r.end > 0) {
876- Unit index = UnitValue(m, units, i + 1, i + 1 + unit.value);
877-
878- std::cout << r.start + index.value << std::endl;
879-
880-
881-
882-
883- // this needs to use getNextUnit to find the correct unit
884- // also need to find tags
885-
886-
887-
888-
889-
890-
891- iv = heap.units[r.start + index.value];
892+ if (stack[(int)registers[idx].value].length > registers[idx+1].value) {
893+ registers[idx] = stack[(int)registers[idx].value].data[(int)registers[idx+1].value];
894 }
895
896- i += unit.value;
897+ register_len = idx;
898 break;
899 }
900- case INSERT: {
901- Range listRange = m.get(units[i+1].value);
902- size_t size = listRange.end-listRange.start;
903-
904- Range ri = m.get(units[i+3].value);
905-
906- size_t offset = i + 2;
907- Range iRange = getNextUnit(units, offset, i + 1 + unit.value);
908- Unit index = UnitValue(m, units, iRange.start, iRange.end);
909-
910-
911-
912-
913-
914-
915-
916- // this will also need to use getNextUnit to find the next value
917- // will also have to support finding tags
918-
919-
920-
921-
922-
923-
924-
925-
926-
927- if (ri.end-ri.start + index.value < size) {
928- std::copy(heap.units.begin() + ri.start, heap.units.begin() + ri.end, heap.units.begin()+listRange.start + index.value);
929+ case APPEND: {
930+ if (stack[(int)registers[idx].value].capacity > stack[(int)registers[idx].value].length) {
931+ stack[(int)registers[idx].value].data[stack[(int)registers[idx].value].length++] = registers[idx];
932 } else {
933- std::cerr << "Cannot insert data at index: " << index.value << " list size: " << size << " data to be inserted: " << ri.end-ri.start << std::endl;
934+ stack[(int)registers[idx].value].capacity *= 2;
935+ struct Unit* ptr = realloc(stack[(int)registers[idx].value].data, stack[(int)registers[idx].value].capacity * sizeof(struct Unit));
936+ if (ptr) {
937+ stack[(int)registers[idx].value].data = ptr;
938+ stack[(int)registers[idx].value].data[stack[(int)registers[idx].value].length++] = registers[idx];
939+ } else {
940+ stack[(int)registers[idx].value].capacity /= 2;
941+ }
942 }
943-
944- i += unit.value;
945 break;
946 }
947- case SIZE: {
948-
949-
950-
951- // this can just return the value of LIST
952-
953-
954-
955-
956- Range r = m.get(units[i+1].value);
957- iv = {NUMBER, (float)r.end-(float)r.start};
958-
959- i += unit.value;
960+ case LENGTH: {
961+ registers[idx].type = NUMBER;
962+ registers[idx].value = (float)stack[(int)registers[idx].value].length;
963+ register_len = idx;
964+ break;
965+ }
966+ case CAPACITY: {
967+ registers[idx].type = NUMBER;
968+ registers[idx].value = (float)stack[(int)registers[idx].value].capacity;
969+ register_len = idx;
970 break;
971 }
972-
973-
974-
975-
976-
977-
978 case ADD:
979- result.type = NUMBER;
980- result.value += iv.value;
981- op = NONOP;
982+ registers[idx].type = NUMBER;
983+ registers[idx].value += registers[idx+1].value;
984+ register_len = idx;
985+ printf("ADD: %f, IDX: %f\n", registers[idx], idx);
986 break;
987 case SUB:
988- result.type = NUMBER;
989- result.value -= iv.value;
990- op = NONOP;
991+ registers[idx].type = NUMBER;
992+ registers[idx].value -= registers[idx+1].value;
993+ register_len = idx;
994 break;
995 case DIV:
996- result.type = NUMBER;
997- result.value /= iv.value;
998- op = NONOP;
999+ registers[idx].type = NUMBER;
1000+ registers[idx].value /= registers[idx+1].value;
1001+ register_len = idx;
1002 break;
1003 case MULT:
1004- result.type = NUMBER;
1005- result.value *= iv.value;
1006- op = NONOP;
1007+ registers[idx].type = NUMBER;
1008+ registers[idx].value *= registers[idx+1].value;
1009+ register_len = idx;
1010 break;
1011 case LT:
1012- result.type = BOOL;
1013- result.value = result.value < iv.value;
1014- op = NONOP;
1015+ registers[idx].type = BOOL;
1016+ registers[idx].value = registers[idx].value < registers[idx + 1].value;
1017+ register_len = idx;
1018 break;
1019 case GT:
1020- result.type = BOOL;
1021- result.value = result.value > iv.value;
1022- op = NONOP;
1023+ registers[idx].type = BOOL;
1024+ registers[idx].value = registers[idx].value > registers[idx + 1].value;
1025+ register_len = idx;
1026 break;
1027 case LE:
1028- result.type = BOOL;
1029- result.value = result.value <= iv.value;
1030- op = NONOP;
1031+ registers[idx].type = BOOL;
1032+ registers[idx].value = registers[idx].value <= registers[idx + 1].value;
1033+ register_len = idx;
1034 break;
1035 case GE:
1036- result.type = BOOL;
1037- result.value = result.value >= iv.value;
1038- op = NONOP;
1039+ registers[idx].type = BOOL;
1040+ registers[idx].value = registers[idx].value >= registers[idx + 1].value;
1041+ register_len = idx;
1042 break;
1043 case EQ:
1044- result.type = BOOL;
1045- result.value = result.value == iv.value;
1046- op = NONOP;
1047+ registers[idx].type = BOOL;
1048+ registers[idx].value = registers[idx].value == registers[idx + 1].value;
1049+ register_len = idx;
1050 break;
1051 case AND:
1052- result.type = BOOL;
1053- result.value = result.value && iv.value;
1054- op = NONOP;
1055+ registers[idx].type = BOOL;
1056+ registers[idx].value = registers[idx].value && registers[idx + 1].value;
1057+ register_len = idx;
1058 break;
1059 case OR:
1060- result.type = BOOL;
1061- result.value = result.value || iv.value;
1062- op = NONOP;
1063+ registers[idx].type = BOOL;
1064+ registers[idx].value = registers[idx].value || registers[idx + 1].value;
1065+ register_len = idx;
1066 break;
1067 case NOT:
1068- result.type = BOOL;
1069- result.value = !iv.value;
1070- op = NONOP;
1071+ registers[idx].type = BOOL;
1072+ registers[idx].value = !registers[idx].value;
1073+ register_len = idx;
1074 break;
1075 default:
1076- result = iv;
1077+ registers[register_len++] = unit;
1078 }
1079 }
1080
1081- for (int i = 0; i < heap_size; i++) {
1082- free(heap[i]);
1083+ for (int i = 0; i < stack_size; i++) {
1084+ free(stack[i].data);
1085 }
1086
1087- return registers[0];
1088+ return registers[0].value;
1089 }
1090-
1091+/*
1092 // Used for root node without a parent
1093-std::vector<Node> EMPTY_NODE_CHILDREN_VECTOR;
1094
1095 // node: The node you are checking the selector against
1096 // selector: output of parseSelector
1097diff --git a/src/parser.c b/src/parser.c
1098index 5f680b0..eef3bee 100755
1099--- a/src/parser.c
1100+++ b/src/parser.c
1101@@ -132,11 +132,14 @@ void get_unit(struct Unit** units, int* cap, int* units_len, char** vars, int* v
1102 if (v == '\\' && !escaped) escaped = true;
1103 if (!escaped && (v == '"' || v == '\'') && parenDepth == 0) {
1104 if (inQuotes && v == quoteType) {
1105- struct Unit unit;
1106- unit.type = STRING;
1107- unit.value = str_buffer_len;
1108- write_unit(units, units_len, cap, unit);
1109-
1110+ bool hasOP = false;
1111+ struct Unit op;
1112+ if ((*units_len) > 1 && (*units)[(*units_len)-1].type >= OP_START) {
1113+ hasOP = true;
1114+ op.type = (*units)[(*units_len)-1].type;
1115+ op.value = 2;
1116+ (*units_len) -= 1;
1117+ }
1118 for (int j = 0; j < str_buffer_len; j++) {
1119 struct Unit unit;
1120 unit.type = CHAR;
1121@@ -144,6 +147,10 @@ void get_unit(struct Unit** units, int* cap, int* units_len, char** vars, int* v
1122 write_unit(units, units_len, cap, unit);
1123 }
1124
1125+ if (hasOP) {
1126+ write_unit(units, units_len, cap, op);
1127+ }
1128+
1129 str_buffer[0] = '\0';
1130 str_buffer_len = 0;
1131 inQuotes = false;
1132@@ -220,6 +227,15 @@ void get_unit(struct Unit** units, int* cap, int* units_len, char** vars, int* v
1133 // on LET add the word to the vars list
1134 // on SET reverse index the array
1135
1136+ bool hasOP = false; // We need to move operators to the back so we save it here and add it at the end
1137+ struct Unit op;
1138+ if ((*units_len) > 1 && (*units)[(*units_len)-1].type >= OP_START) {
1139+ hasOP = true;
1140+ op.type = (*units)[(*units_len)-1].type;
1141+ op.value = 2;
1142+ (*units_len) -= 1;
1143+ }
1144+
1145 args[args_len] = '\0';
1146
1147 struct Unit placeholder = {0};
1148@@ -261,6 +277,9 @@ void get_unit(struct Unit** units, int* cap, int* units_len, char** vars, int* v
1149
1150 float child_count = 0;
1151 float depth = 0;
1152+
1153+ int indexes[*units_len-before_count];
1154+ int indexes_len = 0;
1155
1156 for (int j = *units_len-1; j >= before_count; j--) {
1157 if ((*units)[j].type >= FUNC_START) {
1158@@ -269,6 +288,7 @@ void get_unit(struct Unit** units, int* cap, int* units_len, char** vars, int* v
1159
1160 if (depth == 0) {
1161 child_count++;
1162+ indexes[indexes_len++] = j;
1163 } else {
1164 depth--;
1165 }
1166@@ -276,8 +296,57 @@ void get_unit(struct Unit** units, int* cap, int* units_len, char** vars, int* v
1167
1168 placeholder.value = child_count;
1169
1170+ if (placeholder.type == SET) {
1171+ if (indexes[0] - 1 > 0 && (*units)[indexes[0] - 1].type == AT) {
1172+ placeholder.value = (placeholder.value - 1) + (*units)[indexes[0] - 1].value;
1173+ memmove((*units) + (*units_len-reg_count) + indexes[0] - 1, (*units) + (*units_len-reg_count) + indexes[0], *units_len * sizeof(struct Unit));
1174+ *units_len -= 1;
1175+ }
1176+ }
1177+
1178 write_unit(units, units_len, cap, placeholder);
1179
1180+ // Turn VARS to PTR's if the calling function needs the address not the value
1181+ if (placeholder.type == LET ||
1182+ placeholder.type == SET ||
1183+ placeholder.type == AT) {
1184+ (*units)[before_count].type = PTR;
1185+ }
1186+
1187+ if (placeholder.type == IF) {
1188+ if (child_count == 2) {
1189+ // Just if no else
1190+ // Move back 1
1191+ if (sizeof(units) / sizeof(struct Unit) < ((*units_len)-indexes[1]) * sizeof(struct Unit)) {
1192+ *units = realloc(*units, sizeof(struct Unit) * (*cap * 2));
1193+ }
1194+
1195+ memmove((*units) + (*units_len-reg_count) + indexes[0], (*units) + (*units_len-reg_count) + indexes[0] - 1, *units_len * sizeof(struct Unit));
1196+ (*units)[indexes[0]].type = IF;
1197+ (*units)[indexes[0]].value = reg_count -indexes[0] + 1;
1198+ } else if (child_count == 3) {
1199+ // if else
1200+ // Move back 1 and add a jump at the end of the conditional logic
1201+ if ((*cap) < (indexes[2] + 20) * sizeof(struct Unit)) {
1202+ *units = realloc(*units, sizeof(struct Unit) * (*cap * 2));
1203+ }
1204+
1205+ memmove((*units) + (*units_len-reg_count) + indexes[1], (*units) + (*units_len-reg_count) + indexes[1] - 1, *units_len * sizeof(struct Unit));
1206+ (*units)[indexes[1]].type = IF;
1207+ (*units)[indexes[1]].value = (indexes[0] - indexes[1]) + 2; // Add one for the jump and one for the if
1208+
1209+ memmove((*units) + (*units_len-reg_count) + indexes[0], (*units) + (*units_len-reg_count) + indexes[0] - 1, *units_len * sizeof(struct Unit));
1210+ (*units)[indexes[0] + 1].type = JUMP;
1211+ (*units)[indexes[0] + 1].value = (*units_len-indexes[0]);
1212+
1213+ (*units_len)++;
1214+ }
1215+ }
1216+
1217+ if (hasOP) {
1218+ write_unit(units, units_len, cap, op);
1219+ }
1220+
1221 buffer[0] = '\0';
1222 buffer_len = 0;
1223 } else if ((!inQuotes && (v == ',' || isspace(v))) || i >= size - 1) {
1224@@ -414,19 +483,7 @@ void get_unit(struct Unit** units, int* cap, int* units_len, char** vars, int* v
1225 }
1226 }
1227
1228- if ((*units_len) > 1 && ((*units)[(*units_len)-1].type == MULT ||
1229- (*units)[(*units_len)-1].type == ADD ||
1230- (*units)[(*units_len)-1].type == SUB ||
1231- (*units)[(*units_len)-1].type == DIV ||
1232- (*units)[(*units_len)-1].type == LT ||
1233- (*units)[(*units_len)-1].type == GT ||
1234- (*units)[(*units_len)-1].type == LE ||
1235- (*units)[(*units_len)-1].type == GE ||
1236- (*units)[(*units_len)-1].type == EQ ||
1237- (*units)[(*units_len)-1].type == AND ||
1238- (*units)[(*units_len)-1].type == OR ||
1239- (*units)[(*units_len)-1].type == NOT
1240- )) {
1241+ if ((*units_len) > 1 && (*units)[(*units_len)-1].type >= OP_START) {
1242 struct Unit u = (*units)[(*units_len)-1];
1243 u.value = 2;
1244 (*units_len) -= 1;