home
readme
diff
tree
note
docs
0commit 60c72d0452854f10ad171d712c9ae7d98f5415e9
1Author: lakefox <mason@lakefox.net>
2Date: Thu Feb 26 19:11:15 2026 -0700
3
4 RPN added to parser
5
6diff --git a/include/grim.h b/include/grim.h
7index 76dadf6..08d8c61 100755
8--- a/include/grim.h
9+++ b/include/grim.h
10@@ -188,6 +188,6 @@ char* INNER_HTML(Node* node, char** buffer, size_t* size, int depth);
11
12 void ADD_CLASS(Node* n, char* value);
13
14-void get_unit(struct Unit** units, int* cap, int* units_len, char** vars, int* vars_len, int* vars_cap, int* stack_len, char* value);
15+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);
16
17 #endif // NODE_H
18diff --git a/playground/css_unit.c b/playground/css_unit.c
19index 5262d00..63aef74 100644
20--- a/playground/css_unit.c
21+++ b/playground/css_unit.c
22@@ -25,10 +25,11 @@ void benchmark_get_unit(char* value) {
23 int vars_len = 0;
24
25 int stack_len = 0;
26+ int max_register_size = 0;
27
28 for (int i = 0; i < iterations; i++) {
29 units_len = 0;
30- get_unit(&units, &cap, &units_len, &vars, &vars_len, &vars_cap, &stack_len, value);
31+ get_unit(&units, &cap, &units_len, &vars, &vars_len, &vars_cap, &stack_len, &max_register_size, value);
32 }
33
34 free(units);
35@@ -44,7 +45,7 @@ void benchmark_get_unit(char* value) {
36 (total_time / iterations) * 1000000);
37 }
38
39-void test_get_unit(char* ustr, struct Unit* known_units, int known_units_len, int stack_size) {
40+void test_get_unit(char* ustr, struct Unit* known_units, int known_units_len, int stack_size, int known_register_size) {
41 int cap = 10;
42 struct Unit *units = malloc(sizeof(struct Unit) * cap);
43 int units_len = 0;
44@@ -54,13 +55,20 @@ void test_get_unit(char* ustr, struct Unit* known_units, int known_units_len, in
45 int vars_len = 0;
46
47 int stack_len = 0;
48+ int max_register_size = 0;
49
50- get_unit(&units, &cap, &units_len, &vars, &vars_len, &vars_cap, &stack_len, ustr);
51-
52-
53- assert(units_len == known_units_len);
54+ get_unit(&units, &cap, &units_len, &vars, &vars_len, &vars_cap, &stack_len, &max_register_size, ustr);
55
56 bool error = false;
57+ if (units_len != known_units_len) {
58+ fprintf(stderr, "UNITS assertion failed on test case \"%s\": %d != %d\n", ustr, units_len, known_units_len);
59+ error = true;
60+ }
61+
62+ if (max_register_size != known_register_size) {
63+ fprintf(stderr, "REGISTER assertion failed on test case \"%s\": %d != %d\n", ustr, max_register_size, known_register_size);
64+ error = true;
65+ }
66
67 if (stack_len != stack_size) {
68 fprintf(stderr, "STACK assertion failed on test case \"%s\": %d != %d\n", ustr, stack_len, stack_size);
69@@ -96,10 +104,11 @@ int main() {
70 int vars_len = 0;
71
72 int stack_len = 0;
73+ int max_register_size = 0;
74
75- char* ustr = "((let(x 10px) set(x x * 2%) print(x)) (let(y 10px) set(y y * 2) print(y)))";
76+ char* ustr = "(let(x 10px) set(x 30px) (let(x 50px) print(x)) print(x))";
77
78- get_unit(&units, &cap, &units_len, &vars, &vars_len, &vars_cap, &stack_len, ustr);
79+ get_unit(&units, &cap, &units_len, &vars, &vars_len, &vars_cap, &stack_len, &max_register_size, ustr);
80
81 printf("Stack Size: %d\n", stack_len);
82
83@@ -109,20 +118,21 @@ int main() {
84 if (true) {
85 benchmark_get_unit(ustr);
86
87- test_get_unit("1 + 1", (struct Unit[]){{NUMBER, 1}, {ADD, 0}, {NUMBER, 1}}, 3, 0);
88- test_get_unit("23px * 5678.7%", (struct Unit[]){{PX, 23}, {MULT, 0}, {PERCENT, 5678.7f}}, 3, 0);
89- test_get_unit("calc(23px * size)", (struct Unit[]){{CALC, 3}, {PX, 23}, {MULT, 0}, {VAR, -1}}, 4, 0);
90- test_get_unit("(let(x 10px) set(x 30px) (let(x 50px) print(x)) print(x))", (struct Unit[]){{GROUP, 14}, {LET, 2}, {VAR, 0}, {PX, 10}, {SET, 2}, {VAR, 0}, {PX, 30}, {GROUP, 5}, {LET, 2}, {VAR, 1}, {PX, 50}, {PRINT, 1}, {VAR, 1}, {PRINT, 1}, {VAR, 0}}, 15, 2);
91- test_get_unit("((let(x 10px) set(x x * 2%) print(x)) (let(y 10px) set(y y * 2) print(y)))", (struct Unit[]){{GROUP, 22},
92+ test_get_unit("1 + 1", (struct Unit[]){{NUMBER, 1}, {NUMBER, 1}, {ADD, 0}}, 3, 0, 2);
93+ test_get_unit("23px * 5678.7%", (struct Unit[]){{PX, 23}, {PERCENT, 5678.7f}, {MULT, 0}}, 3, 0, 2);
94+ test_get_unit("calc(23px * size)", (struct Unit[]){{PX, 23}, {VAR, -1}, {MULT, 0}, {CALC, 3}}, 4, 0, 3);
95+ 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, 5}, {VAR, 0}, {PRINT, 1}, {GROUP, 14}}, 15, 2, 14);
96+ test_get_unit("((let(x 10px) set(x x * 2%) print(x)) (let(y 10px) set(y y * 2) print(y)))", (struct Unit[]){
97+ {VAR, 0}, {PX, 10}, {LET, 2},
98+ {VAR, 0}, {VAR, 0}, {PERCENT, 2}, {MULT, 0}, {SET, 4},
99+ {VAR, 0}, {PRINT, 1},
100 {GROUP, 10},
101- {LET, 2}, {VAR, 0}, {PX, 10},
102- {SET, 4}, {VAR, 0}, {VAR, 0}, {MULT, 0}, {PERCENT, 2},
103- {PRINT, 1}, {VAR, 0},
104+ { VAR, 0}, {PX, 10}, {LET, 2},
105+ {VAR, 0}, {VAR, 0}, {NUMBER, 2}, {MULT, 0}, {SET, 4},
106+ {VAR, 0}, {PRINT, 1},
107 {GROUP, 10},
108- {LET, 2}, { VAR, 0}, {PX, 10},
109- {SET, 4}, {VAR, 0}, {VAR, 0}, {MULT, 0}, {NUMBER, 2},
110- {PRINT, 1}, {VAR, 0}}
111- , 23, 1);
112- test_get_unit("(let(x :name \"john doe\" :age 27))", (struct Unit[]){{GROUP, 14.0f}, {LET, 13}, {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}}, 15, 1);
113+ {GROUP, 22}}
114+ , 23, 1, 22);
115+ 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, 14}}, 15, 1, 14);
116 }
117 }
118diff --git a/src/grim.c b/src/grim.c
119index 7529c5d..9ecb714 100755
120--- a/src/grim.c
121+++ b/src/grim.c
122@@ -448,21 +448,22 @@ Range getNextUnit(const std::vector<Unit>& units, size_t& offset, size_t end) {
123 // HEAP: [width, height, em, dpi]
124 // HEAP LAYOUT: VAR
125
126-float unit_value(struct Units[]** stack, struct Unit_Vector** units, int start, int end) {
127- UnitType result_type = NUMBER;
128- float result_value = 0;
129-
130- UnitType op = ADD;
131-
132- UnitType iv_type = NUMBER;
133- float iv_value = 0
134+float unit_value(struct Units[]** stack, int register_size, int heap_size, struct Unit** units, int* units_len) {
135+ struct Unit** heap[heap_size];
136+ int heap[heap_size] = {0};
137+ struct Unit registers[register_size] = {0};
138+
139+ // Pre-alloc
140+ for (int i = 0; i < heap_size; i++) {
141+ heap[8] = malloc(sizeof(struct Unit) * 32);
142+ }
143
144-Init the heap, the stack will be passed for preset values
145-
146- for (int i = start; i < end; i++) {
147+ for (int i = 0; i < heap_size; i++) {
148 struct Unit unit = units.units[i];
149 UnitType type = unit.type;
150
151+
152+ if (value range to put to register)
153 switch (type) {
154 case ADD:
155 case SUB:
156@@ -532,7 +533,7 @@ Init the heap, the stack will be passed for preset values
157 case RIC:
158 case RLH: {
159 iv.type = NUMBER;
160- iv.value = unit.value*heap.units[2].value;
161+ iv.value = unit.value*stack[2].value;
162 break;
163 }
164 case EX:
165@@ -584,9 +585,16 @@ Init the heap, the stack will be passed for preset values
166 iv.value = unit.value*heap.units[0].value;
167 break;
168 }
169+
170+
171+
172+
173+
174+if func range
175+
176 case GROUP: {
177 Snapshot s = m.save();
178- iv = UnitValue(m, units, i+1, i+1+unit.value);
179+ iv = UnitValue(m, units, i+1, i+1+unit.value);
180 i += unit.value;
181 m.restore(s);
182 break;
183@@ -931,7 +939,7 @@ Init the heap, the stack will be passed for preset values
184 break;
185 }
186 case ATTR: {
187- Range args[3];
188+ Range args[3];
189 int found = 0;
190 size_t start = i + 1;
191 size_t end = i + 1 + unit.value;
192@@ -1030,7 +1038,7 @@ Init the heap, the stack will be passed for preset values
193 }
194
195
196- i += unit.value;
197+ i += unit.value;
198 break;
199 }
200 case LET: {
201@@ -1170,7 +1178,7 @@ Init the heap, the stack will be passed for preset values
202
203
204
205- Range r = m.get(units[i+1].value);
206+ Range r = m.get(units[i+1].value);
207 iv = {NUMBER, (float)r.end-(float)r.start};
208
209 i += unit.value;
210@@ -1244,7 +1252,11 @@ Init the heap, the stack will be passed for preset values
211 }
212 }
213
214- return result;
215+ for (int i = 0; i < heap_size; i++) {
216+ free(heap[i]);
217+ }
218+
219+ return registers[0];
220 }
221
222 // Used for root node without a parent
223diff --git a/src/parser.c b/src/parser.c
224index 2608ea0..8b15503 100755
225--- a/src/parser.c
226+++ b/src/parser.c
227@@ -106,7 +106,7 @@ int write_var(char** vars_ptr, int* len, int* cap, char var[MAX_STR_LEN]) {
228 return *len-1;
229 }
230
231-void get_unit(struct Unit** units, int* cap, int* units_len, char** vars, int* vars_len, int* vars_cap, int* stack_len, char* value) {
232+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) {
233 char buffer[MAX_STR_LEN];
234 int buffer_len = 0;
235
236@@ -123,6 +123,10 @@ void get_unit(struct Unit** units, int* cap, int* units_len, char** vars, int* v
237
238 int size = strlen(value);
239
240+ if (*max_register_size < 2) {
241+ *max_register_size = 2; // Default 2 for math operations
242+ }
243+
244 for (int i = 0; i < size; i++) {
245 char v = value[i];
246 if (v == '\\' && !escaped) escaped = true;
247@@ -218,35 +222,45 @@ void get_unit(struct Unit** units, int* cap, int* units_len, char** vars, int* v
248
249 args[args_len] = '\0';
250
251- int function_idx = *units_len;
252 struct Unit placeholder = {0};
253
254 if (name_len == 0) {
255 placeholder.type = GROUP;
256 } else {
257 const struct FuncMap* fm = find_func(name, name_len);
258- placeholder.type = fm->type;
259+ if (fm == NULL) {
260+ placeholder.type = FUNC;
261+ } else {
262+ placeholder.type = fm->type;
263+ }
264 }
265
266- write_unit(units, units_len, cap, placeholder);
267+ if (placeholder.type == LET) {
268+ write_unit(units, units_len, cap, placeholder);
269+ *units_len -= 1;
270+ }
271 int before_count = *units_len;
272 int before_vars_len = *vars_len;
273
274- get_unit(units, cap, units_len, vars, vars_len, vars_cap, stack_len, args);
275+ get_unit(units, cap, units_len, vars, vars_len, vars_cap, stack_len, max_register_size, args);
276 free(args);
277
278+
279+ // Reset the vars_len to remove any new vars created in the prevous scope
280+ // unless let was called
281 if (placeholder.type != LET) {
282 *vars_len = before_vars_len;
283 }
284
285 int child_count = *units_len - before_count;
286
287- // Reset the vars_len to remove any new vars created in the prevous scope
288- struct Unit final_unit;
289- final_unit.type = placeholder.type;
290- final_unit.value = (float)child_count;
291+ if (child_count > *max_register_size) {
292+ *max_register_size = child_count;
293+ }
294
295- (*units)[function_idx] = final_unit;
296+ placeholder.value = (float)child_count;
297+
298+ write_unit(units, units_len, cap, placeholder);
299
300 buffer[0] = '\0';
301 buffer_len = 0;
302@@ -353,7 +367,7 @@ void get_unit(struct Unit** units, int* cap, int* units_len, char** vars, int* v
303 } else {
304 unit.type = VAR;
305
306- if (((*units_len)-1 >= 1) && (*units)[(*units_len)-1].type == LET) {
307+ if (((*units_len) < *cap) && (*units)[(*units_len)].type == LET) {
308 unit.value = write_var(vars, vars_len, vars_cap, buffer);
309
310 if (unit.value + 1 > *stack_len) {
311@@ -384,7 +398,26 @@ void get_unit(struct Unit** units, int* cap, int* units_len, char** vars, int* v
312 }
313 }
314
315- write_unit(units, units_len, cap, unit);
316+ if ((*units_len) > 1 && ((*units)[(*units_len)-1].type == MULT ||
317+ (*units)[(*units_len)-1].type == ADD ||
318+ (*units)[(*units_len)-1].type == SUB ||
319+ (*units)[(*units_len)-1].type == DIV ||
320+ (*units)[(*units_len)-1].type == LT ||
321+ (*units)[(*units_len)-1].type == GT ||
322+ (*units)[(*units_len)-1].type == LE ||
323+ (*units)[(*units_len)-1].type == GE ||
324+ (*units)[(*units_len)-1].type == EQ ||
325+ (*units)[(*units_len)-1].type == AND ||
326+ (*units)[(*units_len)-1].type == OR ||
327+ (*units)[(*units_len)-1].type == NOT
328+ )) {
329+ struct Unit u = (*units)[(*units_len)-1];
330+ (*units_len) -= 1;
331+ write_unit(units, units_len, cap, unit);
332+ write_unit(units, units_len, cap, u);
333+ } else {
334+ write_unit(units, units_len, cap, unit);
335+ }
336 buffer[0] = '\0';
337 buffer_len = 0;
338 } else if (inQuotes) {