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 /*