home
readme
diff
tree
note
docs
0commit 2da8f1bed6fc07a11eecd6e2ed8585fdb013982a
1Author: lakefox <mason@lakefox.net>
2Date: Thu Apr 2 11:16:03 2026 -0600
3
4 Wrath functions
5
6diff --git a/Makefile b/Makefile
7index 6050f75..c9a7370 100755
8--- a/Makefile
9+++ b/Makefile
10@@ -48,16 +48,29 @@ TEST_BINARIES = build/html_node_test build/css_selector_test \
11 all_tests: $(TEST_BINARIES)
12 @for test in $(TEST_BINARIES); do \
13 echo "Running $$test..."; \
14- $$test --skip-benchmarks; \
15+ $$test; \
16 done
17
18-# This target clears the screen, builds the specific test/playground, and runs it
19-run_%: build/%
20+# --- Debug ---
21+GDB_FLAGS ?=
22+
23+debug_css_units:
24 @clear
25- @echo "--- Running $* ---"
26- @./build/$* --skip-benchmarks
27+ make run_css_unit_playground
28+ gdb $(GDB_FLAGS) -ex "b 146" -ex "run" -ex "print *units@units_len" build/css_unit_playground
29+
30+debug_unit_debug:
31+ @clear
32+ make run_unit_value_playground
33+ gdb $(GDB_FLAGS) -ex "b 146" -ex "run" -ex "print *units@units_len" build/unit_value_playground
34+
35+
36+quiet_%: GDB_FLAGS = --batch
37+quiet_%: %
38+ @true
39
40-bench_%: build/%
41+# This target clears the screen, builds the specific test/playground, and runs it
42+run_%: build/%
43 @clear
44 @echo "--- Running $* ---"
45 @./build/$*
46diff --git a/include/grim.h b/include/grim.h
47index 69756a2..62ceba9 100755
48--- a/include/grim.h
49+++ b/include/grim.h
50@@ -79,7 +79,7 @@ typedef enum {
51 NEAREST, UP, DOWN, TO_ZERO,
52
53 // Keyword
54- SCREEN, TOKEN, NO_SUPPORT, IMAGE, BOOL, VAR, PTR, TAG, CHAR, JUMP, FREE,
55+ SCREEN, TOKEN, NO_SUPPORT, IMAGE, BOOL, VAR, PTR, TAG, CHAR, JUMP, FREE, REG, ARG,
56
57 FUNC_START,
58 // General Functions
59@@ -87,7 +87,7 @@ typedef enum {
60 HYPOT, LOG, EXP, ABS, SIGN, SIN, COS, TAN, ASIN, ACOS, ATAN, ATAN2, VAR_FUNC,
61 BLUR, BRIGHTNESS, CONTRAST, DROP_SHADOW, GRAYSCALE, HUE_ROTATE, INVERT,
62 OPACITY, SEPIA, SATURATE, ATTR, TYPE, ENV, IF, FUNC, LET, RETURN, SET,
63- AT, EMPTY, APPEND, WHILE, PRINT, LENGTH, CAPACITY,
64+ AT, EMPTY, APPEND, WHILE, PRINT, LENGTH, CAPACITY, DEF,
65
66 // Easing Functions
67 EASING_FUNCTION, LINEAR_EASING_FUNCTION, LINEAR, EASE, EASE_IN, EASE_OUT, EASE_IN_OUT, CUBIC_BEZIER_FUNCTION,
68@@ -109,7 +109,7 @@ typedef enum {
69
70 // Logic
71 AND, OR, NOT, ONLY, COMMA,
72- NON_FUNC_PADDING
73+ CUSTOM_FUNCS
74 } UnitType;
75
76 struct Unit_Vector {
77@@ -169,6 +169,12 @@ typedef struct {
78 int size;
79 } ParsedSelector;
80
81+typedef struct {
82+ char* key;
83+ int value;
84+} KeyValue;
85+
86+
87 ParsedSelector parseSelectorParts(const char*);
88
89
90@@ -198,9 +204,9 @@ char* INNER_HTML(Node* node, char** buffer, size_t* size, int depth);
91
92 void ADD_CLASS(Node* n, char* value);
93
94-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);
95+void get_unit(struct Unit** units, int* cap, int* units_len, char** vars, int* vars_len, int* vars_cap, KeyValue** funcs, int* funcs_len, int* funcs_cap, int* stack_len, int* max_register_size, char* value);
96
97-float unit_value(struct Slot stack[], int stack_size, int register_size, struct Unit* gnits, int units_len);
98+float unit_value(struct Slot stack[], int register_size, struct Unit* gnits, int units_len);
99
100 void ADD_STACK_VALUE(struct Slot stack[], int index, struct Unit* units, int units_len);
101
102diff --git a/maps/functions.gperf b/maps/functions.gperf
103index 1352a4d..4562394 100644
104--- a/maps/functions.gperf
105+++ b/maps/functions.gperf
106@@ -93,4 +93,5 @@ empty, EMPTY
107 length, LENGTH
108 capacity, CAPACITY
109 append, APPEND
110+def, DEF
111 %%
112diff --git a/playground/css_unit.c b/playground/css_unit.c
113index 371b9d4..732a8f8 100644
114--- a/playground/css_unit.c
115+++ b/playground/css_unit.c
116@@ -24,16 +24,26 @@ void benchmark_get_unit(char* value) {
117 char *vars = malloc(MAX_STR_LEN * cap);
118 int vars_len = 0;
119
120+ int funcs_cap = 0;
121+ KeyValue *funcs = {};
122+ int funcs_len = 0;
123+
124+
125 int stack_len = 0;
126 int max_register_size = 0;
127
128 for (int i = 0; i < iterations; i++) {
129 units_len = 0;
130- get_unit(&units, &cap, &units_len, &vars, &vars_len, &vars_cap, &stack_len, &max_register_size, value);
131+ get_unit(&units, &cap, &units_len, &vars, &vars_len, &vars_cap, &funcs, &funcs_len, &funcs_cap, &stack_len, &max_register_size, value);
132 }
133
134 free(units);
135 free(vars);
136+ for (int i = 0; i < funcs_len; i++) {
137+ free(funcs[i].key);
138+ }
139+ free(funcs);
140+
141
142 // Get end time
143 clock_gettime(CLOCK_MONOTONIC, &end);
144@@ -51,37 +61,51 @@ void test_get_unit(char* ustr, struct Unit* known_units, int known_units_len, in
145 int units_len = 0;
146
147 int vars_cap = 0;
148- char **vars = NULL;
149+ char *vars = NULL;
150 int vars_len = 0;
151
152+ int funcs_cap = 0;
153+ KeyValue *funcs = {};
154+ int funcs_len = 0;
155+
156 int stack_len = 0;
157 int max_register_size = 0;
158
159- get_unit(&units, &cap, &units_len, &vars, &vars_len, &vars_cap, &stack_len, &max_register_size, ustr);
160+ get_unit(&units, &cap, &units_len, &vars, &vars_len, &vars_cap, &funcs, &funcs_len, &funcs_cap, &stack_len, &max_register_size, ustr);
161
162 bool error = false;
163 if (units_len != known_units_len) {
164- fprintf(stderr, "UNITS assertion failed on test case \"%s\": %d != %d\n", ustr, units_len, known_units_len);
165+ printf("| \n");
166+ printf("| UNITS assertion failed on test case \"%s\": %d != %d\n", ustr, units_len, known_units_len);
167+ printf("| \n");
168 error = true;
169 }
170
171 if (max_register_size != known_register_size) {
172- fprintf(stderr, "REGISTER assertion failed on test case \"%s\": %d != %d\n", ustr, max_register_size, known_register_size);
173+ printf("| \n");
174+ printf("| REGISTER assertion failed on test case \"%s\": %d != %d\n", ustr, max_register_size, known_register_size);
175+ printf("| \n");
176 error = true;
177 }
178
179 if (stack_len != stack_size) {
180- fprintf(stderr, "STACK assertion failed on test case \"%s\": %d != %d\n", ustr, stack_len, stack_size);
181+ printf("| \n");
182+ printf("| STACK assertion failed on test case \"%s\": %d != %d\n", ustr, stack_len, stack_size);
183+ printf("| \n");
184 error = true;
185 }
186
187 for (int i = 0; i < units_len; i++) {
188 if (units[i].type != known_units[i].type) {
189- fprintf(stderr, "TYPE assertion failed on unit %d of test case \"%s\": %d != %d\n", i, ustr, units[i].type, known_units[i].type);
190+ printf("| \n");
191+ printf("| TYPE assertion failed on unit %d of test case \"%s\": %d != %d\n", i, ustr, units[i].type, known_units[i].type);
192+ printf("| \n");
193 error = true;
194 }
195 if (units[i].value != known_units[i].value) {
196- fprintf(stderr, "VALUE assertion failed on unit %d of test case \"%s\": %f != %f\n", i, ustr, units[i].value, known_units[i].value);
197+ printf("| \n");
198+ printf("| VALUE assertion failed on unit %d of test case \"%s\": %f != %f\n", i, ustr, units[i].value, known_units[i].value);
199+ printf("| \n");
200 error = true;
201 }
202 }
203@@ -92,6 +116,11 @@ void test_get_unit(char* ustr, struct Unit* known_units, int known_units_len, in
204
205 free(units);
206 free(vars);
207+ for (int i = 0; i < funcs_len; i++) {
208+ free(funcs[i].key);
209+ }
210+ free(funcs);
211+
212 }
213
214 int main() {
215@@ -103,20 +132,29 @@ int main() {
216 char **vars = NULL;
217 int vars_len = 0;
218
219+ int funcs_cap = 0;
220+ KeyValue *funcs = {};
221+ int funcs_len = 0;
222+
223 int stack_len = 0;
224 int max_register_size = 0;
225
226- char* ustr = "(let(x :name \"john doe\" :age 27))";
227+ char* ustr = "let(height 10) def(x (age name) (age + height * name)) x(4 x(5 x(6 x(7 8))))";
228
229- get_unit(&units, &cap, &units_len, &vars, &vars_len, &vars_cap, &stack_len, &max_register_size, ustr);
230+ get_unit(&units, &cap, &units_len, &vars, &vars_len, &vars_cap, &funcs, &funcs_len, &funcs_cap, &stack_len, &max_register_size, ustr);
231
232- printf("Stack Size: %d\n", stack_len);
233+ printf("Stack Size: %d Register Size: %d\n", stack_len, max_register_size);
234
235 free(units);
236 free(vars);
237
238- if (true) {
239- benchmark_get_unit(ustr);
240+ for (int i = 0; i < funcs_len; i++) {
241+ free(funcs[i].key);
242+ }
243+ free(funcs);
244+
245+ if (false) {
246+// benchmark_get_unit(ustr);
247
248 test_get_unit("1 + 1",
249 (struct Unit[]){{NUMBER, 1}, {NUMBER, 1}, {ADD, 2}},
250@@ -127,12 +165,12 @@ int main() {
251 3, 0, 2
252 );
253 test_get_unit("calc(23px * size)",
254- (struct Unit[]){{PX, 23}, {VAR, -1}, {MULT, 2}, {CALC, 1}},
255- 4, 0, 3
256+ (struct Unit[]){{PX, 23}, {VAR, 0}, {MULT, 2}, {CALC, 1}},
257+ 4, 1, 2
258 );
259 test_get_unit("(let(x 10px) set(x 30px) (let(x 50px) print(x)) print(x))",
260 (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}},
261- 15, 2, 14
262+ 15, 2, 4
263 );
264 test_get_unit("((let(x 10px) set(x x * 2%) print(x)) (let(y 10px) set(y y * 2) print(y)))", (struct Unit[]){
265 {PTR, 0}, {PX, 10}, {LET, 2},
266@@ -144,24 +182,29 @@ int main() {
267 {VAR, 0}, {PRINT, 1},
268 {GROUP, 3},
269 {GROUP, 2}}
270- , 23, 1, 22);
271+ , 23, 1, 3);
272 test_get_unit("(let(x :name \"john doe\" :age 27))",
273 (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}},
274- 14, 1, 13
275+ 14, 1, 12
276 );
277 test_get_unit("(if((style(--scheme) == dark) calc(#eeeeee == '1')))",
278- (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}},
279- 11, 0, 10
280+ (struct Unit[]){{VAR, 0}, {CUSTOM_FUNCS, 1}, {VAR, 0}, {EQ, 2}, {GROUP, 1}, {IF, 6}, {HEX, 2.19425599e-38}, {CHAR, 49}, {EQ, 2}, {CALC, 1}, {GROUP, 1}},
281+ 11, 1, 2
282 );
283
284 test_get_unit("(if((style(--scheme) == dark) calc(#eeeeee == '1') print(123)))",
285- (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}},
286- 14, 0, 13
287+ (struct Unit[]){{VAR, 0}, {CUSTOM_FUNCS, 1}, {VAR, 0}, {EQ, 2}, {GROUP, 1}, {IF, 6}, {HEX, 2.19425599e-38}, {CHAR, 49}, {EQ, 2}, {CALC, 1}, {JUMP, 3}, {NUMBER, 123}, {PRINT, 1}, {GROUP, 3}},
288+ 14, 1, 3
289 );
290
291 test_get_unit("(if((style(--scheme) == dark) calc(#eeeeee == calc(123)) print(123)))",
292- (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}},
293- 15, 0, 14
294+ (struct Unit[]){{VAR, 0}, {CUSTOM_FUNCS, 1}, {VAR, 0}, {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}},
295+ 15, 1, 3
296+ );
297+ test_get_unit("let(height 10) def(x (name age) print(name age height 1 2 3)) x(1 1)",
298+ (struct Unit[]){{PTR, 0}, {NUMBER, 10}, {LET, 2}, {DEF, 11}, {REG, 0}, {REG, 1}, {VAR, 0}, {NUMBER, 1}, {NUMBER, 2}, {NUMBER, 3}, {PRINT, 6}, {JUMP, 2}, {NUMBER, 1}, {NUMBER, 1}, {CUSTOM_FUNCS+4, 2}},
299+ 15, 3, 6
300 );
301+
302 }
303 }
304diff --git a/playground/syntax.wr b/playground/syntax.wr
305index 834307b..1c6b2de 100644
306--- a/playground/syntax.wr
307+++ b/playground/syntax.wr
308@@ -200,4 +200,28 @@ Context -> width -> screen -> etc
309 let(x list(256))
310 set(at(x 0) "str")
311
312+
313+ -- XML
314+ def(x (name age first_or_last)
315+ `<person>
316+ <name type="${option(first_or_last "first" "last")}">${name}</name>
317+ <age>${clamp(age 0 100)}</age>
318+ </person>`
319+ )
320+
321+ let(p1 x(name("John") age(12) first_or_last("first")))
322+ let(p2 x("Mary" 99 "first"))
323+
324+ let(people p1)
325+ append(people p2)
326+
327+ print($(at(p1 1) "name[type]")) -- first
328+
329+ -- Functions
330+ def(uppercase (
331+ map(value ($1 + 60))
332+ ))
333+
334+ print(uppercase(value("test")))
335+
336 )
337diff --git a/playground/unit_value.c b/playground/unit_value.c
338index 251b03c..5bd83ad 100644
339--- a/playground/unit_value.c
340+++ b/playground/unit_value.c
341@@ -21,10 +21,14 @@ void benchmark_unit_value(char* value) {
342 char **vars = NULL;
343 int vars_len = 0;
344
345+ int funcs_cap = 0;
346+ KeyValue *funcs = {};
347+ int funcs_len = 0;
348+
349 int stack_len = 4;
350 int max_register_size = 0;
351
352- get_unit(&units, &cap, &units_len, &vars, &vars_len, &vars_cap, &stack_len, &max_register_size, value);
353+ get_unit(&units, &cap, &units_len, &vars, &vars_len, &vars_cap, &funcs, &funcs_len, &funcs_cap, &stack_len, &max_register_size, value);
354
355 if (stack_len < 1) {
356 stack_len = 1;
357@@ -44,7 +48,7 @@ void benchmark_unit_value(char* value) {
358 clock_gettime(CLOCK_MONOTONIC, &start);
359
360 for (int i = 0; i < iterations; i++) {
361- v += (double)unit_value(&stack, stack_len, max_register_size, units, units_len);
362+ v += (double)unit_value(&stack, max_register_size, units, units_len);
363 }
364
365 // Get end time
366@@ -58,6 +62,11 @@ void benchmark_unit_value(char* value) {
367 free(stack[i].data);
368 }
369
370+ for (int i = 0; i < funcs_len; i++) {
371+ free(funcs[i].key);
372+ }
373+ free(funcs);
374+
375
376 // Calculate time difference in seconds
377 double total_time = (end.tv_sec - start.tv_sec) + (end.tv_nsec - start.tv_nsec) / 1e9;
378@@ -75,10 +84,15 @@ void test_unit_value(char* ustr, float value) {
379 char **vars = NULL;
380 int vars_len = 0;
381
382+ int funcs_cap = 0;
383+ KeyValue *funcs = {};
384+ int funcs_len = 0;
385+
386+
387 int stack_len = 4;
388 int max_register_size = 0;
389
390- get_unit(&units, &cap, &units_len, &vars, &vars_len, &vars_cap, &stack_len, &max_register_size, ustr);
391+ get_unit(&units, &cap, &units_len, &vars, &vars_len, &vars_cap, &funcs, &funcs_len, &funcs_cap, &stack_len, &max_register_size, ustr);
392
393 if (stack_len < 1) {
394 stack_len = 1;
395@@ -92,10 +106,12 @@ void test_unit_value(char* ustr, float value) {
396 ADD_STACK_VALUE(&stack, 2, (struct Unit[]){{NUMBER, 16}}, 1);
397 ADD_STACK_VALUE(&stack, 3, (struct Unit[]){{NUMBER, 192}}, 1);
398
399- float v = unit_value(&stack, stack_len, max_register_size, units, units_len);
400+ float v = unit_value(&stack, max_register_size, units, units_len);
401
402 if (v != value) {
403- printf("FAILED test \"%s\" with value: %f (Expected: %f)\n", ustr, v, value);
404+ printf("| \n");
405+ printf("| FAILED test \"%s\" with value: %f (Expected: %f)\n", ustr, v, value);
406+ printf("| \n");
407 } else {
408 printf("PASSED test \"%s\"\n", ustr);
409 }
410@@ -106,6 +122,11 @@ void test_unit_value(char* ustr, float value) {
411 free(stack[i].data);
412 }
413
414+ for (int i = 0; i < funcs_len; i++) {
415+ free(funcs[i].key);
416+ }
417+ free(funcs);
418+
419 }
420
421 int main() {
422@@ -117,12 +138,16 @@ int main() {
423 char **vars = NULL;
424 int vars_len = 0;
425
426+ int funcs_cap = 0;
427+ KeyValue *funcs = {};
428+ int funcs_len = 0;
429+
430 int stack_len = 0;
431 int max_register_size = 0;
432
433- char* ustr = "let(x 10px 20px 30px) set(at(x 1) 90px) if(at(x 1) != 90px, 1 + 1, 5 + 5)";
434+ char* ustr = "let(height 10) def(x (name age) (age + height * name)) x(4 x(5 x(6 x(7 8))))";
435
436- get_unit(&units, &cap, &units_len, &vars, &vars_len, &vars_cap, &stack_len, &max_register_size, ustr);
437+ get_unit(&units, &cap, &units_len, &vars, &vars_len, &vars_cap, &funcs, &funcs_len, &funcs_cap, &stack_len, &max_register_size, ustr);
438
439 printf("Stack Size: %d Registers: %d Unit Length: %d\n", stack_len, max_register_size, units_len);
440
441@@ -133,7 +158,7 @@ int main() {
442 struct Slot stack[stack_len];
443 memset(stack, 0, sizeof(stack));
444
445- float v = unit_value(&stack, stack_len, max_register_size, units, units_len);
446+ float v = unit_value(&stack, max_register_size, units, units_len);
447
448 for (int i = 0; i < stack_len; i++) {
449 free(stack[i].data);
450@@ -145,8 +170,14 @@ int main() {
451 free(units);
452 free(vars);
453
454+ for (int i = 0; i < funcs_len; i++) {
455+ free(funcs[i].key);
456+ }
457+ free(funcs);
458+
459+
460 if (true) {
461- //benchmark_unit_value(ustr);
462+ benchmark_unit_value(ustr);
463
464 test_unit_value("1 + 1", 2);
465 test_unit_value("pow(10 2)", 100);
466@@ -164,6 +195,10 @@ int main() {
467 test_unit_value("let(x 10px 20px 30px) set(at(x 1) 90px) at(x 1) == 90px", 1);
468 test_unit_value("let(x 10px 20px 30px) set(at(x 1) 90px) if(at(x 1) != 90px, 1 + 1, 5 + 5)", 5);
469 test_unit_value("let(x 10px 20px 30px) set(at(x 1) 90px) if(at(x 1) == 90px, 1 + 1)", 1);
470+ test_unit_value("let(x empty(3)) ((length(x) == 3) && (capacity(x) == 3))", 1);
471+ test_unit_value("let(height 10) def(x (age name) (age + height * name)) x(4 x(5 x(6 x(7 8))))", 456960);
472+ test_unit_value("let(height 10) def(x () (21 + 3)) x()", 24);
473+ test_unit_value("let(height 10) def(x (name age) (age + height * name)) x(4 x(5 x(6 x(7 8))))", 16560);
474
475 // cases for all rel units and every function
476 }
477diff --git a/src/grim.c b/src/grim.c
478index 89aab68..16dde23 100755
479--- a/src/grim.c
480+++ b/src/grim.c
481@@ -459,7 +459,7 @@ void ADD_STACK_VALUE(struct Slot stack[], int index, struct Unit* units, int uni
482 }
483 }
484
485-float unit_value(struct Slot stack[], int stack_size, int register_size, struct Unit* units, int units_len) {
486+float unit_value(struct Slot stack[], int register_size, struct Unit* units, int units_len) {
487 struct Unit registers[register_size];
488 int register_len = 0;
489
490@@ -470,15 +470,6 @@ float unit_value(struct Slot stack[], int stack_size, int register_size, struct
491 int idx = (register_len-(int)unit.value);
492 if (idx < 0) idx = 0;
493
494-/*
495- printf("############ Frame: %d ##############\n", i);
496- printf("IDX: %d UV: %f\n", idx, unit.value);
497-
498- for (int j = 0; j < register_len; j++) {
499- printf("R%d: %f\n", j, registers[j].value);
500- }
501-*/
502-
503 switch (type) {
504 // DEG, TURN are not length values but are treated as generic units (PX)
505 case DEG:
506@@ -853,36 +844,39 @@ float unit_value(struct Slot stack[], int stack_size, int register_size, struct
507 break;
508 }
509 case EMPTY: {
510- for (int j = 0; j < unit.value; j++) {
511- struct Unit e;
512- e.type = FREE;
513- e.value = 0;
514- registers[register_len++] = e;
515- }
516+ registers[idx].type = FREE;
517 break;
518 }
519 case LET: {
520- if (registers[idx].value > -1) {
521- if (unit.value == 2) {
522- stack[(int)registers[idx].value].length = 1;
523- stack[(int)registers[idx].value].capacity = 0;
524- stack[(int)registers[idx].value].value = registers[idx + 1];
525- } else {
526- if (stack[(int)registers[idx].value].capacity < unit.value || stack[(int)registers[idx].value].capacity/2 > unit.value) {
527- if (stack[(int)registers[idx].value].capacity > 0) {
528- free(stack[(int)registers[idx].value].data);
529- }
530- stack[(int)registers[idx].value].data = malloc(unit.value * sizeof(struct Unit));
531- stack[(int)registers[idx].value].capacity = unit.value - 1; // This includes the var def
532+ if (unit.value == 2 && registers[idx + 1].type != FREE) {
533+ stack[(int)registers[idx].value].length = 1;
534+ stack[(int)registers[idx].value].capacity = 0;
535+ stack[(int)registers[idx].value].value = registers[idx + 1];
536+ } else {
537+ int items = 0;
538+ for (int j = idx + 1; j < register_len; j++) {
539+ if (registers[j].type == FREE) {
540+ items += (int)registers[j].value;
541+ } else {
542+ items++;
543+ }
544+ }
545+ if (stack[(int)registers[idx].value].capacity < items || stack[(int)registers[idx].value].capacity/2 > items) {
546+ if (stack[(int)registers[idx].value].capacity > 0) {
547+ free(stack[(int)registers[idx].value].data);
548 }
549+ stack[(int)registers[idx].value].data = malloc(items * sizeof(struct Unit));
550+ stack[(int)registers[idx].value].capacity = items;
551+ stack[(int)registers[idx].value].length = items;
552+ }
553
554- stack[(int)registers[idx].value].length = 0;
555+ int offset = 0;
556
557- for (int j = idx+1; j < idx+(int)unit.value; j++) {
558- if (registers[j].type != FREE) {
559- stack[(int)registers[idx].value].length++;
560- stack[(int)registers[idx].value].data[(j-1)-idx] = registers[j];
561- }
562+ for (int j = idx+1; j < idx+(int)unit.value; j++) {
563+ if (registers[j].type == FREE) {
564+ offset += (int)registers[j].value - 1;
565+ } else {
566+ stack[(int)registers[idx].value].data[((j-1)-idx)+offset] = registers[j];
567 }
568 }
569 }
570@@ -890,33 +884,36 @@ float unit_value(struct Slot stack[], int stack_size, int register_size, struct
571 break;
572 }
573 case SET: {
574- if (registers[idx].value > -1) {
575- if (unit.value == 3) {
576- if (stack[(int)registers[idx].value].length == 1) {
577- if (stack[(int)registers[idx].value].capacity > 0) {
578- free(stack[(int)registers[idx].value].data);
579- }
580- stack[(int)registers[idx].value].data = malloc((int)registers[idx + 1].value * sizeof(struct Unit));
581- stack[(int)registers[idx].value].capacity = (int)registers[idx + 1].value;
582- stack[(int)registers[idx].value].data[0] = stack[(int)registers[idx].value].value; // Add the prevous value
583+ if (unit.value == 3) {
584+ if (stack[(int)registers[idx].value].length == 1) {
585+ if (stack[(int)registers[idx].value].capacity > 0) {
586+ free(stack[(int)registers[idx].value].data);
587 }
588- // AT
589- if (stack[(int)registers[idx].value].capacity >= registers[idx+1].value) {
590- stack[(int)registers[idx].value].data[(int)registers[idx + 1].value] = registers[idx + 2];
591+ stack[(int)registers[idx].value].data = malloc((int)registers[idx + 1].value * sizeof(struct Unit));
592+ stack[(int)registers[idx].value].capacity = (int)registers[idx + 1].value;
593+ stack[(int)registers[idx].value].data[0] = stack[(int)registers[idx].value].value; // Add the prevous value
594+ }
595+ // AT
596+ if (stack[(int)registers[idx].value].capacity >= registers[idx+1].value) {
597+ // If set(at(x 0) empty(15)) it will just place NUMBER 15
598+ if (registers[idx + 2].type == FREE) {
599+ registers[idx + 2].type = NUMBER;
600 }
601- } else {
602- stack[(int)registers[idx].value].value = registers[idx + 1];
603+ stack[(int)registers[idx].value].data[(int)registers[idx + 1].value] = registers[idx + 2];
604+ }
605+ } else {
606+ if (registers[idx + 1].type == FREE) {
607+ registers[idx + 1].type = NUMBER;
608 }
609+ stack[(int)registers[idx].value].value = registers[idx + 1];
610 }
611
612 register_len = idx;
613 break;
614 }
615 case AT: {
616- if (registers[idx].value > -1) {
617- if (stack[(int)registers[idx].value].length > registers[idx+1].value) {
618- registers[idx] = stack[(int)registers[idx].value].data[(int)registers[idx+1].value];
619- }
620+ if (stack[(int)registers[idx].value].length > registers[idx+1].value) {
621+ registers[idx] = stack[(int)registers[idx].value].data[(int)registers[idx+1].value];
622 }
623
624 register_len = idx + 1;
625@@ -937,6 +934,14 @@ float unit_value(struct Slot stack[], int stack_size, int register_size, struct
626 }
627 break;
628 }
629+ case DEF: {
630+ i = unit.value; // Skip the function
631+ break;
632+ }
633+ case REG: {
634+ registers[register_len++] = units[(int)unit.value];
635+ break;
636+ }
637 case LENGTH: {
638 registers[idx].type = NUMBER;
639 registers[idx].value = (float)stack[(int)registers[idx].value].length;
640@@ -1010,7 +1015,27 @@ float unit_value(struct Slot stack[], int stack_size, int register_size, struct
641 register_len = idx + 1;
642 break;
643 default:
644- registers[register_len++] = unit;
645+ if (unit.type < CUSTOM_FUNCS) {
646+ registers[register_len++] = unit;
647+ } else {
648+ int index = (unit.type - CUSTOM_FUNCS) - 1;
649+ units[(int)units[index].value].value = (float)((i) - (int)units[index].value); // Set the jump to return to the next instruction
650+
651+ for (int j = 0; j < (int)unit.value; j++) {
652+ units[index+1+j] = registers[((register_len)-(int)unit.value)+j];
653+ }
654+
655+
656+ if (unit.value == 0) {
657+ if (register_len > 0) {
658+ register_len -= 1;
659+ }
660+ i = index+1;
661+ } else {
662+ register_len -= (int)unit.value;
663+ i = index+(int)unit.value+1; // Add unit.value to skip past ARG's
664+ }
665+ }
666 break;
667 }
668
669diff --git a/src/parser.c b/src/parser.c
670index 7b534d6..d375cf1 100755
671--- a/src/parser.c
672+++ b/src/parser.c
673@@ -106,7 +106,32 @@ int write_var(char** vars_ptr, int* len, int* cap, char var[MAX_STR_LEN]) {
674 return *len-1;
675 }
676
677-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) {
678+int write_func(KeyValue** func_ptr, int* len, int* cap, char func[MAX_STR_LEN], int index) {
679+ if (*len >= *cap) {
680+ int new_cap = (*cap <= 0) ? 8 : (*cap * 2);
681+ KeyValue* next = realloc(*func_ptr, sizeof(KeyValue) * new_cap);
682+ if (!next) {
683+ fprintf(stderr, "Out of memory\n");
684+ exit(1);
685+ }
686+ *func_ptr = next;
687+ *cap = new_cap;
688+ }
689+ (*func_ptr)[*len] = (KeyValue){strdup(func), index};
690+ (*len)++;
691+ return *len-1;
692+}
693+
694+int get_func(KeyValue** func_ptr, int* len, char func[MAX_STR_LEN]) {
695+ for (int i = 0; i < *len; i++) {
696+ if (strcmp((*func_ptr)[i].key, func) == 0) {
697+ return (*func_ptr)[i].value;
698+ }
699+ }
700+ return -1;
701+}
702+
703+void get_unit(struct Unit** units, int* cap, int* units_len, char** vars, int* vars_len, int* vars_cap, KeyValue** funcs, int* funcs_len, int* funcs_cap, int* stack_len, int* max_register_size, char* value) {
704 char buffer[MAX_STR_LEN];
705 int buffer_len = 0;
706
707@@ -134,7 +159,7 @@ void get_unit(struct Unit** units, int* cap, int* units_len, char** vars, int* v
708 if (inQuotes && v == quoteType) {
709 bool hasOP = false;
710 struct Unit op;
711- if ((*units_len) > 1 && (*units)[(*units_len)-1].type >= OP_START && (*units)[(*units_len)-1].value != 2) {
712+ if ((*units_len) > 1 && (*units)[(*units_len)-1].type >= OP_START && (*units)[(*units_len)-1].type < CUSTOM_FUNCS && (*units)[(*units_len)-1].value != 2) {
713 hasOP = true;
714 op.type = (*units)[(*units_len)-1].type;
715 op.value = 2;
716@@ -229,7 +254,7 @@ void get_unit(struct Unit** units, int* cap, int* units_len, char** vars, int* v
717
718 bool hasOP = false; // We need to move operators to the back so we save it here and add it at the end
719 struct Unit op;
720- if ((*units_len) > 1 && (*units)[(*units_len)-1].type >= OP_START && (*units)[(*units_len)-1].value != 2) {
721+ if ((*units_len) > 1 && (*units)[(*units_len)-1].type >= OP_START && (*units)[(*units_len)-1].type < CUSTOM_FUNCS && (*units)[(*units_len)-1].value != 2) {
722 hasOP = true;
723 op.type = (*units)[(*units_len)-1].type;
724 op.value = 2;
725@@ -245,13 +270,13 @@ void get_unit(struct Unit** units, int* cap, int* units_len, char** vars, int* v
726 } else {
727 const struct FuncMap* fm = find_func(name, name_len);
728 if (fm == NULL) {
729- placeholder.type = FUNC;
730+ placeholder.type = (float)CUSTOM_FUNCS+(float)get_func(funcs, funcs_len, name)+1;
731 } else {
732 placeholder.type = fm->type;
733 }
734 }
735
736- if (placeholder.type == LET) {
737+ if (placeholder.type == LET || placeholder.type == DEF) {
738 write_unit(units, units_len, cap, placeholder);
739 *units_len -= 1;
740 }
741@@ -259,7 +284,7 @@ void get_unit(struct Unit** units, int* cap, int* units_len, char** vars, int* v
742 int before_count = *units_len;
743 int before_vars_len = *vars_len;
744
745- get_unit(units, cap, units_len, vars, vars_len, vars_cap, stack_len, max_register_size, args);
746+ get_unit(units, cap, units_len, vars, vars_len, vars_cap, funcs, funcs_len, funcs_cap, stack_len, max_register_size, args);
747 free(args);
748
749
750@@ -269,23 +294,18 @@ void get_unit(struct Unit** units, int* cap, int* units_len, char** vars, int* v
751 *vars_len = before_vars_len;
752 }
753
754- int reg_count = *units_len - before_count;
755-
756- if (reg_count > *max_register_size) {
757- *max_register_size = reg_count;
758- }
759-
760 float child_count = 0;
761 float depth = 0;
762
763- int indexes[*units_len-before_count];
764+ int c = *units_len-before_count;
765+ if (c < 1) c = 1;
766+ int indexes[c];
767 int indexes_len = 0;
768
769 for (int j = *units_len-1; j >= before_count; j--) {
770 if ((*units)[j].type >= FUNC_START) {
771 depth += (*units)[j].value;
772 }
773-
774 if (depth == 0) {
775 child_count++;
776 indexes[indexes_len++] = j;
777@@ -296,6 +316,10 @@ void get_unit(struct Unit** units, int* cap, int* units_len, char** vars, int* v
778
779 placeholder.value = child_count;
780
781+ if (c > *max_register_size) {
782+ *max_register_size = c;
783+ }
784+
785 if (placeholder.type == SET) {
786 if (indexes[0] - 1 > 0 && (*units)[indexes[0] - 1].type == AT) {
787 placeholder.value = (placeholder.value - 1) + (*units)[indexes[0] - 1].value;
788@@ -325,11 +349,11 @@ void get_unit(struct Unit** units, int* cap, int* units_len, char** vars, int* v
789
790 memmove((*units) + indexes[0], (*units) + indexes[0] - 1, (*units_len - indexes[0]) * sizeof(struct Unit));
791 (*units)[indexes[0]].type = IF;
792- (*units)[indexes[0]].value = reg_count - indexes[0] + 1;
793+ (*units)[indexes[0]].value = (*units_len-before_count) - indexes[0] + 1;
794 } else if (child_count == 3) {
795 // if else
796 // Move back 1 and add a jump at the end of the conditional logic
797- if ((*cap) < (indexes[2] + 20) * sizeof(struct Unit)) {
798+ if ((unsigned long)(*cap) < (indexes[2] + 20) * sizeof(struct Unit)) {
799 *units = realloc(*units, sizeof(struct Unit) * (*cap * 2));
800 }
801
802@@ -343,6 +367,27 @@ void get_unit(struct Unit** units, int* cap, int* units_len, char** vars, int* v
803
804 (*units_len)++;
805 }
806+ } else if (placeholder.type == DEF) {
807+ float func_index = (*units)[indexes[2]].value;
808+
809+ for (int j = indexes[0]; j < *units_len; j++) {
810+ if ((*units)[j].type == REG) {
811+ for (int k = indexes[1]; k < indexes[0]; k++) {
812+ if ((*units)[k].type == REG && (*units)[j].value == (*units)[k].value) {
813+ (*units)[j].value = k;
814+ }
815+ }
816+ }
817+ }
818+
819+ for (int k = indexes[1]; k < indexes[0]; k++) {
820+ (*units)[k].type = ARG;
821+ }
822+ (*units)[indexes[2]].type = DEF;
823+ (*units)[indexes[2]].value = *units_len - 2;
824+
825+ (*units)[*units_len-2].type = JUMP; // This is for the calling function to use to jump itself back to its prevous position
826+ *units_len -= 1;
827 }
828
829 if (hasOP) {
830@@ -454,13 +499,16 @@ void get_unit(struct Unit** units, int* cap, int* units_len, char** vars, int* v
831 } else {
832 unit.type = VAR;
833
834+
835 if (((*units_len) < *cap) && (*units)[(*units_len)].type == LET) {
836 unit.value = write_var(vars, vars_len, vars_cap, buffer);
837
838 if (unit.value + 1 > *stack_len) {
839 *stack_len = unit.value + 1;
840 }
841- } else {
842+ } else if (((*units_len) < *cap) && (*units)[(*units_len)].type == DEF) {
843+ write_func(funcs, funcs_len, funcs_cap, buffer, *units_len);
844+ } else{
845 bool var_found = false;
846 for (int j = *vars_len-1; j >= 0; j--) {
847 if (strcmp(&(*vars)[j * MAX_STR_LEN], buffer) == 0) {
848@@ -471,8 +519,13 @@ void get_unit(struct Unit** units, int* cap, int* units_len, char** vars, int* v
849 }
850
851 if (!var_found) {
852- unit.value = -1;
853- }
854+ unit.type = REG;
855+ int tag_value = 0;
856+ for (int j = 1; j < buffer_len; j++) {
857+ tag_value += buffer[j]*j;
858+ }
859+
860+ unit.value = tag_value; }
861 }
862 }
863 } else {
864@@ -485,7 +538,7 @@ void get_unit(struct Unit** units, int* cap, int* units_len, char** vars, int* v
865 }
866 }
867
868- if ((*units_len) > 1 && (*units)[(*units_len)-1].type >= OP_START && (*units)[(*units_len)-1].value != 2) {
869+ if ((*units_len) > 1 && (*units)[(*units_len)-1].type >= OP_START && (*units)[(*units_len)-1].type < CUSTOM_FUNCS && (*units)[(*units_len)-1].value != 2) {
870 struct Unit u = (*units)[(*units_len)-1];
871 u.value = 2;
872 (*units_len) -= 1;
873@@ -522,7 +575,7 @@ void get_unit(struct Unit** units, int* cap, int* units_len, char** vars, int* v
874 // media queries [[selector_index, index_to_media_query_in_selectors]]
875 /*
876 void css_parser(SymbolTable* sym, char* input, int size, int** basemap, Unit** selectors, Style* styles, Query* queries) {
877-
878+
879 }
880 */
881 /*