home readme diff tree note docs

0commit 08b79058f5f92dcd52452c2c18571a5b1cca25b4
1Author: lakefox <mason@lakefox.net>
2Date:   Sat Apr 11 10:30:56 2026 -0600
3
4    Removed variable length registers
5
6diff --git a/Makefile b/Makefile
7index df9f26c..8aa1b3d 100755
8--- a/Makefile
9+++ b/Makefile
10@@ -1,6 +1,6 @@
11 # --- Variables ---
12-CCFLAGS = -std=c23 -O3 -lm
13-#CCFLAGS = -Wall -Wextra -std=c23 -g -O0 -fsanitize=address,undefined -fno-omit-frame-pointer -lm
14+#CCFLAGS = -std=c23 -O3 -lm
15+CCFLAGS = -Wall -Wextra -std=c23 -g -O0 -fsanitize=address,undefined -fno-omit-frame-pointer -lm
16 CC = clang
17 
18 .PHONY: all clean all_tests
19@@ -62,7 +62,7 @@ debug_css_units:
20 debug_unit_debug:
21 	@clear
22 	make run_unit_value_playground
23-	gdb $(GDB_FLAGS) -ex "b 147" -ex "run" -ex "print *units@units_len" build/unit_value_playground
24+	gdb $(GDB_FLAGS) -ex "b 149" -ex "run" -ex "print *units@units_len" build/unit_value_playground
25 
26 
27 quiet_%: GDB_FLAGS = --batch
28diff --git a/include/grim.h b/include/grim.h
29index b14402e..6855771 100755
30--- a/include/grim.h
31+++ b/include/grim.h
32@@ -87,7 +87,7 @@ typedef enum {
33 		HYPOT, LOG, EXP, ABS, SIGN, SIN, COS, TAN, ASIN, ACOS, ATAN, ATAN2, VAR_FUNC,
34 		BLUR, BRIGHTNESS, CONTRAST, DROP_SHADOW, GRAYSCALE, HUE_ROTATE, INVERT, 
35 		OPACITY, SEPIA, SATURATE, ATTR, TYPE, ENV, IF, FUNC, LET, RETURN, SET,
36-		AT, EMPTY, APPEND, WHILE, PRINT, LENGTH, CAPACITY, DEF, RANGE, MAP,
37+		AT, EMPTY, APPEND, WHILE, PRINT, LENGTH, CAPACITY, DEF, RANGE, DATE,
38 		
39 		// Easing Functions
40 		EASING_FUNCTION, LINEAR_EASING_FUNCTION, LINEAR, EASE, EASE_IN, EASE_OUT, EASE_IN_OUT, CUBIC_BEZIER_FUNCTION, 
41@@ -204,9 +204,9 @@ char* INNER_HTML(Node* node, char** buffer, size_t* size, int depth);
42 
43 void ADD_CLASS(Node* n, char* value);
44 
45-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);
46+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, char* value);
47 
48-float unit_value(struct Slot stack[], int register_size, struct Unit* gnits, int units_len);
49+float unit_value(struct Slot stack[], struct Unit* gnits, int units_len);
50 
51 void ADD_STACK_VALUE(struct Slot stack[], int index, struct Unit* units, int units_len);
52 
53diff --git a/maps/functions.gperf b/maps/functions.gperf
54index cb5cf71..ae9236f 100644
55--- a/maps/functions.gperf
56+++ b/maps/functions.gperf
57@@ -96,5 +96,5 @@ append, APPEND
58 def, DEF
59 while, WHILE
60 range, RANGE
61-map, MAP
62+date, DATE
63 %%
64diff --git a/playground/css_unit.c b/playground/css_unit.c
65index 060142e..fe45625 100644
66--- a/playground/css_unit.c
67+++ b/playground/css_unit.c
68@@ -30,11 +30,10 @@ void benchmark_get_unit(char* value) {
69 
70 
71 	int stack_len = 0;
72-	int max_register_size = 0;
73 
74 	for (int i = 0; i < iterations; i++) {
75 		units_len = 0;
76-		get_unit(&units, &cap, &units_len, &vars, &vars_len, &vars_cap, &funcs, &funcs_len, &funcs_cap, &stack_len, &max_register_size, value);
77+		get_unit(&units, &cap, &units_len, &vars, &vars_len, &vars_cap, &funcs, &funcs_len, &funcs_cap, &stack_len, value);
78 	}
79 
80 	free(units);
81@@ -55,7 +54,7 @@ void benchmark_get_unit(char* value) {
82 	       (total_time / iterations) * 1000000);
83 }
84 
85-void test_get_unit(char* ustr, struct Unit* known_units, int known_units_len, int stack_size, int known_register_size) {
86+void test_get_unit(char* ustr, struct Unit* known_units, int known_units_len, int stack_size) {
87 	int cap = 10;
88 	struct Unit *units = malloc(sizeof(struct Unit) * cap);
89 	int units_len = 0;
90@@ -69,9 +68,8 @@ void test_get_unit(char* ustr, struct Unit* known_units, int known_units_len, in
91 	int funcs_len = 0;
92 
93 	int stack_len = 0;
94-	int max_register_size = 0;
95 
96-	get_unit(&units, &cap, &units_len, &vars, &vars_len, &vars_cap, &funcs, &funcs_len, &funcs_cap, &stack_len, &max_register_size, ustr);
97+	get_unit(&units, &cap, &units_len, &vars, &vars_len, &vars_cap, &funcs, &funcs_len, &funcs_cap, &stack_len, ustr);
98 
99 	printf("-------------- CASE ----------------\n");
100 
101@@ -83,13 +81,6 @@ void test_get_unit(char* ustr, struct Unit* known_units, int known_units_len, in
102 		error = true;
103 	}
104 
105-	if (max_register_size != known_register_size) {
106-		printf("| \n");
107-		printf("| REGISTER assertion failed on test case \"%s\": %d != %d\n", ustr, max_register_size, known_register_size);
108-		printf("| \n");
109-		error = true;
110-	}
111-
112 	if (stack_len != stack_size) {
113 		printf("| \n");
114 		printf("| STACK assertion failed on test case \"%s\": %d != %d\n", ustr, stack_len, stack_size);
115@@ -139,13 +130,12 @@ int main() {
116 	int funcs_len = 0;
117 
118 	int stack_len = 0;
119-	int max_register_size = 0;
120 
121-	char* ustr = "let(x empty(3)) ((length(x) == 3) && (capacity(x) == 3))";
122+	char* ustr = "let(x 10) set(x (x * 15)) pow(x 2)";
123 
124-	get_unit(&units, &cap, &units_len, &vars, &vars_len, &vars_cap, &funcs, &funcs_len, &funcs_cap, &stack_len, &max_register_size, ustr);
125+	get_unit(&units, &cap, &units_len, &vars, &vars_len, &vars_cap, &funcs, &funcs_len, &funcs_cap, &stack_len, ustr);
126 
127-	printf("Stack Size: %d Register Size: %d\n", stack_len, max_register_size);
128+	printf("Stack Size: %d\n", stack_len);
129 
130 	free(units);
131 	free(vars);
132@@ -160,19 +150,19 @@ int main() {
133 
134 		test_get_unit("1 + 1",
135 			(struct Unit[]){{NUMBER, 1}, {NUMBER, 1}, {ADD, 2}},
136-			3, 0, 2
137+			3, 0
138 		);
139 		test_get_unit("23px * 5678.7%", 
140 			(struct Unit[]){{PX, 23}, {PERCENT, 5678.7f}, {MULT, 2}},
141-			3, 0, 2
142+			3, 0
143 		);
144 		test_get_unit("calc(23px * size)",
145-			(struct Unit[]){{PX, 23}, {VAR, 0}, {MULT, 2}, {CALC, 1}},
146-			4, 0, 3
147+			(struct Unit[]){{PX, 23}, {REG, 1095}, {MULT, 2}, {CALC, 1}},
148+			4, 0
149 		);
150 		test_get_unit("(let(x 10px) set(x 30px) (let(x 50px) print(x)) print(x))", 
151 			(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}}, 
152-			15, 2, 14
153+			15, 2
154 		);
155 		test_get_unit("((let(x 10px) set(x x * 2%) print(x)) (let(y 10px) set(y y * 2) print(y)))", (struct Unit[]){ 
156 				{PTR, 0}, {PX, 10}, {LET, 2},
157@@ -184,28 +174,28 @@ int main() {
158 				{VAR, 0}, {PRINT, 1},
159 			{GROUP, 3}, 
160 		{GROUP, 2}}
161-			, 23, 1, 22);
162+			, 23, 1);
163 		test_get_unit("(let(x :name \"john doe\" :age 27))", 
164 			(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}}, 
165-			14, 1, 13
166+			14, 1
167 		);
168 		test_get_unit("(if((style(--scheme) == dark) calc(#eeeeee == '1')))", 
169 			(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}}, 
170-			11, 0, 10
171+			11, 0
172 		);
173 
174 		test_get_unit("(if((style(--scheme) == dark) calc(#eeeeee == '1') print(123)))", 
175 			(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}}, 
176-			14, 0, 13
177+			14, 0
178 		);
179 
180 		test_get_unit("(if((style(--scheme) == dark) calc(#eeeeee == calc(123)) print(123)))", 
181 			(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}}, 
182-			15, 0, 14
183+			15, 0
184 		);
185 		test_get_unit("let(height 10) def(x (name age) print(name age height 1 2 3)) x(1 1)", 
186 			(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}}, 
187-			15, 1, 14
188+			15, 1
189 		);
190 
191 	}
192diff --git a/playground/unit_value.c b/playground/unit_value.c
193index 2501860..ca273fb 100644
194--- a/playground/unit_value.c
195+++ b/playground/unit_value.c
196@@ -26,9 +26,8 @@ void benchmark_unit_value(char* value) {
197 	int funcs_len = 0;
198 
199 	int stack_len = 4;
200-	int max_register_size = 0;
201 
202-	get_unit(&units, &cap, &units_len, &vars, &vars_len, &vars_cap, &funcs, &funcs_len, &funcs_cap, &stack_len, &max_register_size, value);
203+	get_unit(&units, &cap, &units_len, &vars, &vars_len, &vars_cap, &funcs, &funcs_len, &funcs_cap, &stack_len, value);
204 
205 	if (stack_len < 1) {
206 		stack_len = 1;
207@@ -48,7 +47,7 @@ void benchmark_unit_value(char* value) {
208 	clock_gettime(CLOCK_MONOTONIC, &start);
209 
210 	for (int i = 0; i < iterations; i++) {
211-		v += (double)unit_value(&stack, max_register_size, units, units_len);
212+		v += (double)unit_value(&stack, units, units_len);
213 	}
214 	
215 	// Get end time
216@@ -93,9 +92,8 @@ void test_unit_value(char* ustr, float value) {
217 
218 
219 	int stack_len = 4;
220-	int max_register_size = 0;
221 
222-	get_unit(&units, &cap, &units_len, &vars, &vars_len, &vars_cap, &funcs, &funcs_len, &funcs_cap, &stack_len, &max_register_size, ustr);
223+	get_unit(&units, &cap, &units_len, &vars, &vars_len, &vars_cap, &funcs, &funcs_len, &funcs_cap, &stack_len, ustr);
224 
225 	if (stack_len < 1) {
226 		stack_len = 1;
227@@ -109,7 +107,7 @@ void test_unit_value(char* ustr, float value) {
228 	ADD_STACK_VALUE(&stack, 2, (struct Unit[]){{NUMBER, 16}}, 1);
229 	ADD_STACK_VALUE(&stack, 3, (struct Unit[]){{NUMBER, 192}}, 1);
230 
231-	float v = unit_value(&stack, max_register_size, units, units_len);
232+	float v = unit_value(&stack, units, units_len);
233 
234 	if (v != value) {
235 		printf("| \n");
236@@ -146,13 +144,12 @@ int main() {
237 	int funcs_len = 0;
238 
239 	int stack_len = 0;
240-	int max_register_size = 0;
241 
242-	char* ustr = "1 + 1";
243+	char* ustr = "let(a 0) while(range(1000) (set(a (a + 1)))) a";
244 
245-	get_unit(&units, &cap, &units_len, &vars, &vars_len, &vars_cap, &funcs, &funcs_len, &funcs_cap, &stack_len, &max_register_size, ustr);
246+	get_unit(&units, &cap, &units_len, &vars, &vars_len, &vars_cap, &funcs, &funcs_len, &funcs_cap, &stack_len, ustr);
247 
248-	printf("Stack Size: %d Registers: %d Unit Length: %d\n", stack_len, max_register_size, units_len);
249+	printf("Stack Size: %d Unit Length: %d\n", stack_len, units_len);
250 
251 	if (stack_len < 1) {
252 		stack_len = 1;
253@@ -161,7 +158,7 @@ int main() {
254 	struct Slot stack[stack_len];
255 	memset(stack, 0, sizeof(stack));
256 
257-	float v = unit_value(&stack, max_register_size, units, units_len);
258+	float v = unit_value(&stack, units, units_len);
259 
260 	for (int i = 0; i < stack_len; i++) {
261 		free(stack[i].data);
262@@ -180,7 +177,7 @@ int main() {
263 
264 
265 	if (true) {
266-		benchmark_unit_value(ustr);
267+//		benchmark_unit_value(ustr);
268 
269 		test_unit_value("1 + 1", 2);
270 		test_unit_value("pow(10 2)", 100);
271diff --git a/src/grim.c b/src/grim.c
272index 95af631..ec67b40 100755
273--- a/src/grim.c
274+++ b/src/grim.c
275@@ -459,8 +459,8 @@ void ADD_STACK_VALUE(struct Slot stack[], int index, struct Unit* units, int uni
276 	}
277 }
278 
279-float unit_value(struct Slot stack[], int register_size, struct Unit* units, int units_len) {
280-	struct Unit registers[register_size];
281+float unit_value(struct Slot stack[], struct Unit* units, int units_len) {
282+	static struct Unit registers[256];
283 	int register_len = 0;
284 
285 	for (int i = 0; i < units_len; i++) {
286@@ -757,14 +757,11 @@ float unit_value(struct Slot stack[], int register_size, struct Unit* units, int
287 			}
288 			case PRINT: {
289 				printf("> ");
290-				bool last_char = false;
291 				for (int j = idx; j < idx+(int)unit.value; j++) {
292 					if (registers[j].type == CHAR) {
293 						printf("%c", (char)registers[j].value);
294-						last_char = true;
295 					} else {
296 						printf(" ");
297-						last_char = false;
298 						if (registers[j].type == BOOL) {
299 							if (registers[j].value == 0) {
300 								printf("false ");
301diff --git a/src/parser.c b/src/parser.c
302index 14bf694..5d13fdf 100755
303--- a/src/parser.c
304+++ b/src/parser.c
305@@ -131,7 +131,7 @@ int get_func(KeyValue** func_ptr, int* len, char func[MAX_STR_LEN]) {
306 	return -1;
307 }
308 
309-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) {
310+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, char* value) {
311 	char buffer[MAX_STR_LEN];
312 	int buffer_len = 0;
313 
314@@ -148,10 +148,6 @@ void get_unit(struct Unit** units, int* cap, int* units_len, char** vars, int* v
315 
316 	int size = strlen(value);
317 
318-	if (*max_register_size < 2) {
319-		*max_register_size = 2; // Default 2 for math operations
320-	}
321-
322 	for (int i = 0; i < size; i++) {
323 		char v = value[i];
324 		if (v == '\\' && !escaped) escaped = true;
325@@ -286,7 +282,7 @@ void get_unit(struct Unit** units, int* cap, int* units_len, char** vars, int* v
326 			int before_count = *units_len;
327 			int before_vars_len = *vars_len;
328 
329-			get_unit(units, cap, units_len, vars, vars_len, vars_cap, funcs, funcs_len, funcs_cap, stack_len, max_register_size, args);
330+			get_unit(units, cap, units_len, vars, vars_len, vars_cap, funcs, funcs_len, funcs_cap, stack_len, args);
331 			free(args);
332 
333 
334@@ -318,17 +314,13 @@ void get_unit(struct Unit** units, int* cap, int* units_len, char** vars, int* v
335 
336 			placeholder.value = child_count;
337 
338-			if (c > *max_register_size) {
339-				*max_register_size = c;
340-			}
341-
342 			if (placeholder.type == SET) {
343 				if (indexes[0] - 1 > 0 && (*units)[indexes[0] - 1].type == AT) {
344 					placeholder.value = (placeholder.value - 1) + (*units)[indexes[0] - 1].value;
345 					memmove((*units) + (indexes[0] - 1), (*units) + indexes[0], (*units_len - indexes[0]) * sizeof(struct Unit));
346 					*units_len -= 1;
347 				}
348-			}
349+			} 
350 
351 			write_unit(units, units_len, cap, placeholder);
352 
353@@ -339,9 +331,7 @@ void get_unit(struct Unit** units, int* cap, int* units_len, char** vars, int* v
354 				placeholder.type == CAPACITY ||
355 				placeholder.type == AT) {
356 				(*units)[before_count].type = PTR;
357-			}	
358-
359-			if (placeholder.type == IF) {
360+			} else if (placeholder.type == IF) {
361 				if (child_count == 2) {
362 					// Just if no else
363 					// Move back 1
364@@ -369,8 +359,6 @@ void get_unit(struct Unit** units, int* cap, int* units_len, char** vars, int* v
365 					(*units_len)++;
366 				}
367 			} else if (placeholder.type == DEF) {
368-				float func_index = (*units)[indexes[2]].value;
369-
370 				for (int j = indexes[0]; j < *units_len; j++) {
371 					if ((*units)[j].type == REG) {
372 						for (int k = indexes[1]; k < indexes[0]; k++) {
373@@ -451,7 +439,6 @@ void get_unit(struct Unit** units, int* cap, int* units_len, char** vars, int* v
374 				}
375 
376 				int count = as_pos-before_count;
377-				int start = (*units_len - 1)-placeholder.value; // -1 because *units_len stores next postition
378 
379 				struct Unit range = (*units)[*units_len-1];
380 				struct Unit start_value = (*units)[before_count];