home
readme
diff
tree
note
docs
0commit 6e818205bbedccc9abc7d124248f851af294f3c0
1Author: lakefox <mason@lakefox.net>
2Date: Wed Feb 18 20:23:57 2026 -0700
3
4 removed SymbolTable
5
6diff --git a/include/grim.h b/include/grim.h
7index 4534c11..28fb868 100755
8--- a/include/grim.h
9+++ b/include/grim.h
10@@ -9,7 +9,6 @@
11 #define MAX_GROUPS 16
12 #define MAX_STR_LEN 128
13 #define MAX_ATTRS 16
14-#define MAX_SYMBOLS 4096
15
16 typedef enum {
17 // Color
18@@ -108,6 +107,12 @@ typedef enum {
19 NON_FUNC_PADDING
20 } UnitType;
21
22+struct Unit_Vector {
23+ struct Unit** units;
24+ int* cap;
25+ int* length;
26+};
27+
28 struct Unit {
29 UnitType type;
30 float value;
31@@ -152,31 +157,19 @@ struct Snapshot {
32 };
33 */
34
35-typedef struct {
36- char* string;
37- uint32_t hash;
38- int id;
39-} SymbolEntry;
40-
41-typedef struct {
42- SymbolEntry* entries;
43- const char** strings;
44-
45- int capacity;
46- int count;
47-} SymbolTable;
48-
49 typedef struct {
50 char key[MAX_STR_LEN];
51 char value[MAX_STR_LEN];
52 } Attribute;
53
54-typedef int Symbol;
55+typedef struct {
56+ char value[MAX_STR_LEN];
57+} Class;
58
59 typedef struct Node {
60- Symbol tag_name;
61- Symbol id;
62- Symbol* class_list;
63+ char tag_name[MAX_STR_LEN];
64+ char id[MAX_STR_LEN];
65+ Class* class_list;
66 int classes_count;
67
68 // Attributes
69@@ -205,14 +198,8 @@ typedef struct {
70
71 ParsedSelector parseSelectorParts(const char*);
72
73-void SET_TAG_NAME(SymbolTable*, Node*, char*);
74-
75-int intern_string(SymbolTable* st, const char* str);
76-
77-const char* symbol_lookup_string(SymbolTable* st, int id);
78
79-
80-Node* CREATE_ELEMENT(SymbolTable* sym, const char* value);
81+Node* CREATE_ELEMENT(const char* value);
82
83 void APPEND_CHILD(Node* parent, Node* child);
84
85@@ -220,29 +207,25 @@ void SET_ATTRIBUTE(Node* n, char* key, char* value);
86
87 const char* GET_ATTRIBUTE(Node* n, char* key);
88
89-void SET_TAG_NAME(SymbolTable* sym, Node* n, char* value);
90+void SET_TAG_NAME(Node* n, char* value);
91
92-const char* GET_TAG_NAME(SymbolTable* sym, Node* n);
93+const char* GET_TAG_NAME(Node* n);
94
95-void SET_ID(SymbolTable* sym, Node* n, char* value);
96+void SET_ID(Node* n, char* value);
97
98-const char* GET_ID(SymbolTable* sym, Node* n);
99+const char* GET_ID(Node* n);
100
101 void SET_INNERTEXT(Node* n, char* value);
102
103 char* GET_INNERTEXT(Node* n);
104
105-SymbolTable* create_symbol_table(int capacity);
106-
107-void FREE_SYMBOL_TABLE(SymbolTable* st);
108-
109 void FREE_NODE(Node* n);
110
111-char* INNER_HTML(SymbolTable* sym, Node* node, char** buffer, size_t* size, int depth);
112+char* INNER_HTML(Node* node, char** buffer, size_t* size, int depth);
113
114-void ADD_CLASS(SymbolTable* sym, Node* n, char* value);
115+void ADD_CLASS(Node* n, char* value);
116
117-void get_unit(SymbolTable* sym, struct Unit** units, int* cap, int* unit_len, char* value);
118+void get_unit(struct Unit** units, int* cap, int* unit_len, char* value);
119
120 /*
121 bool testSelector(Node*, std::vector<std::vector<std::string>>);
122diff --git a/include/parser.h b/include/parser.h
123index a26ba1f..6079a6a 100755
124--- a/include/parser.h
125+++ b/include/parser.h
126@@ -3,6 +3,6 @@
127 #define PARSER_H
128
129 // Declare the parsing functions
130-void html_parser(SymbolTable*, Node*, char*, int);
131+void html_parser(Node*, char*, int);
132
133 #endif
134diff --git a/playground/html_parser.c b/playground/html_parser.c
135index 3c91e6f..be47a1b 100644
136--- a/playground/html_parser.c
137+++ b/playground/html_parser.c
138@@ -33,7 +33,7 @@ char* read_file_to_string(const char* filename) {
139 }
140
141
142-void benchmark_html_parser(SymbolTable* sym, const char* file) {
143+void benchmark_html_parser(const char* file) {
144 struct timespec start, end;
145
146 int iterations = 10000;
147@@ -42,8 +42,8 @@ void benchmark_html_parser(SymbolTable* sym, const char* file) {
148 clock_gettime(CLOCK_MONOTONIC, &start);
149
150 for (int i = 0; i < iterations; i++) {
151- Node* root = CREATE_ELEMENT(sym, "root");
152- html_parser(sym, root, file, strlen(file));
153+ Node* root = CREATE_ELEMENT("root");
154+ html_parser(root, file, strlen(file));
155
156 FREE_NODE(root);
157 }
158@@ -59,25 +59,23 @@ void benchmark_html_parser(SymbolTable* sym, const char* file) {
159 }
160
161 int main() {
162- SymbolTable* sym = create_symbol_table(4096);
163- Node* root = CREATE_ELEMENT(sym, "root");
164+ Node* root = CREATE_ELEMENT("root");
165
166 char* file = read_file_to_string("./tests/index.html");
167
168- html_parser(sym, root, file, strlen(file));
169+ html_parser(root, file, strlen(file));
170
171 size_t size = 10000;
172 char* html = calloc(size, sizeof(char));
173
174- INNER_HTML(sym, root, &html, &size, 0);
175+ INNER_HTML(root, &html, &size, 0);
176
177 printf("%s\n", html);
178
179
180- benchmark_html_parser(sym, file);
181+ benchmark_html_parser(file);
182
183 free(html);
184 free(file);
185- FREE_SYMBOL_TABLE(sym);
186 FREE_NODE(root);
187 }
188diff --git a/src/grim.c b/src/grim.c
189index 56ec0db..979e6ce 100755
190--- a/src/grim.c
191+++ b/src/grim.c
192@@ -27,63 +27,11 @@
193 // | (p98ym) Utils |
194 // +---------------------------------------------------+
195
196-#define FNV_OFFSET_BASIS 2166136261U
197-#define FNV_PRIME 16777619U
198-
199-uint32_t hash_string(const char* str) {
200- uint32_t hash = FNV_OFFSET_BASIS;
201- while (*str) {
202- hash ^= (uint8_t)*str++;
203- hash *= FNV_PRIME;
204- }
205- return hash;
206-}
207-
208-SymbolTable* create_symbol_table(int capacity) {
209- SymbolTable* st = malloc(sizeof(SymbolTable));
210- st->capacity = capacity;
211- st->count = 0;
212- st->entries = calloc(capacity, sizeof(SymbolEntry));
213- st->strings = calloc(capacity, sizeof(char*));
214- return st;
215-}
216-
217-int intern_string(SymbolTable* st, const char* str) {
218- uint32_t hash = hash_string(str);
219- int index = hash % st->capacity;
220-
221- // Linear Probing: Find the string or an empty slot
222- while (st->entries[index].string != NULL) {
223- if (st->entries[index].hash == hash && strcmp(st->entries[index].string, str) == 0) {
224- return st->entries[index].id; // Found existing
225- }
226- index = (index + 1) % st->capacity; // Move to next slot
227- }
228-
229- char* duplicated_str = strdup(str);
230-
231- int new_id = st->count++;
232-
233- // Not found, add new entry
234- st->entries[index].string = duplicated_str;
235- st->entries[index].hash = hash;
236- st->entries[index].id = new_id;
237-
238- st->strings[new_id] = duplicated_str;
239- return st->entries[index].id;
240-}
241-
242-const char* symbol_lookup_string(SymbolTable* st, int id) {
243- if (id < 0 || id >= st->count) return "";
244- return st->strings[id];
245-}
246-
247-Node* CREATE_ELEMENT(SymbolTable* sym, const char* value) {
248+Node* CREATE_ELEMENT(const char* value) {
249 Node* el = malloc(sizeof(Node));
250 memset(el, 0, sizeof(Node));
251- el->tag_name = intern_string(sym, value);
252+ strcpy(el->tag_name, value);
253 el->innertext = NULL;
254- el->id = -1;
255 return el;
256 }
257
258@@ -104,18 +52,6 @@ void FREE_NODE(Node* n) {
259 free(n);
260 }
261
262-void FREE_SYMBOL_TABLE(SymbolTable* st) {
263- if (!st) return;
264-
265- for (int i = 0; i < st->count; i++) {
266- free((void*)st->strings[i]);
267- }
268-
269- free(st->entries);
270- free(st->strings);
271- free(st);
272-}
273-
274 void APPEND_CHILD(Node* parent, Node* child) {
275 child->parent = parent;
276 if (!parent->first_child) {
277@@ -150,7 +86,7 @@ void append_to_buffer(char** buffer, size_t* size, const char* text) {
278 strcat(*buffer, text);
279 }
280
281-char* INNER_HTML(SymbolTable* sym, Node* node, char** buffer, size_t* size, int depth) {
282+char* INNER_HTML(Node* node, char** buffer, size_t* size, int depth) {
283 char temp[1024];
284
285 char tabs[depth+1];
286@@ -160,11 +96,11 @@ char* INNER_HTML(SymbolTable* sym, Node* node, char** buffer, size_t* size, int
287 }
288 tabs[depth] = '\0';
289
290- sprintf(temp, "%s<%s", tabs, symbol_lookup_string(sym, node->tag_name));
291+ sprintf(temp, "%s<%s", tabs, node->tag_name);
292 append_to_buffer(buffer, size, temp);
293
294- if (node->id > -1) {
295- sprintf(temp, " id=\"%s\"", symbol_lookup_string(sym, node->id));
296+ if (strlen(node->id) > 0) {
297+ sprintf(temp, " id=\"%s\"", node->id);
298 append_to_buffer(buffer, size, temp);
299 }
300
301@@ -178,7 +114,7 @@ char* INNER_HTML(SymbolTable* sym, Node* node, char** buffer, size_t* size, int
302 if (node->classes_count > 0) {
303 append_to_buffer(buffer, size, " class=\"");
304 for (int i = 0; i < node->classes_count; i++) {
305- append_to_buffer(buffer, size, symbol_lookup_string(sym, node->class_list[i]));
306+ append_to_buffer(buffer, size, node->class_list[i].value);
307 }
308 append_to_buffer(buffer, size, "\"");
309 }
310@@ -192,11 +128,11 @@ char* INNER_HTML(SymbolTable* sym, Node* node, char** buffer, size_t* size, int
311 Node* child = node->first_child;
312
313 while (child) {
314- INNER_HTML(sym, child, buffer, size, depth+1);
315+ INNER_HTML(child, buffer, size, depth+1);
316 child = child->next_sibling;
317 }
318
319- sprintf(temp, "%s</%s>\n", tabs, symbol_lookup_string(sym, node->tag_name));
320+ sprintf(temp, "%s</%s>\n", tabs, node->tag_name);
321 append_to_buffer(buffer, size, temp);
322 }
323
324@@ -229,20 +165,20 @@ const char* GET_ATTRIBUTE(Node* n, char* key) {
325 return "";
326 }
327
328-void SET_TAG_NAME(SymbolTable* sym, Node* n, char* value) {
329- n->tag_name = intern_string(sym, value);
330+void SET_TAG_NAME(Node* n, char* value) {
331+ strcpy(n->tag_name, value);
332 }
333
334-const char* GET_TAG_NAME(SymbolTable* sym, Node* n) {
335- return symbol_lookup_string(sym, n->tag_name);
336+const char* GET_TAG_NAME(Node* n) {
337+ return n->tag_name;
338 }
339
340-void SET_ID(SymbolTable* sym, Node* n, char* value) {
341- n->id = intern_string(sym, value);
342+void SET_ID(Node* n, char* value) {
343+ strcpy(n->id, value);
344 }
345
346-const char* GET_ID(SymbolTable* sym, Node* n) {
347- return symbol_lookup_string(sym, n->id);
348+const char* GET_ID(Node* n) {
349+ return n->id;
350 }
351
352 void SET_INNERTEXT(Node* n, char* value) {
353@@ -258,25 +194,21 @@ char* GET_INNERTEXT(Node* n) {
354 return n->innertext;
355 }
356
357-void ADD_CLASS(SymbolTable* sym, Node* n, char* value) {
358- int class = intern_string(sym, value);
359-
360+void ADD_CLASS(Node* n, char* value) {
361 for (int i = 0; i < n->classes_count; i++) {
362- if (n->class_list[i] == class) {
363+ if (strcmp(n->class_list[i].value, value) == 0) {
364 return;
365 }
366 }
367
368- n->class_list[n->classes_count++] = class;
369+ strcpy(n->class_list[n->classes_count++].value, value);
370 }
371
372-void REMOVE_CLASS(SymbolTable* sym, Node* n, char* value) {
373- int class = intern_string(sym, value);
374-
375+void REMOVE_CLASS(Node* n, char* value) {
376 for (int i = 0; i < n->classes_count; i++) {
377- if (n->class_list[i] == class) {
378+ if (strcmp(n->class_list[i].value, value) == 0) {
379 n->classes_count -= 1;
380- memmove(&n->class_list[i], &n->class_list[i+1], (n->classes_count-i)*sizeof(Symbol));
381+ memmove(&n->class_list[i], &n->class_list[i+1], (n->classes_count-i)*MAX_STR_LEN);
382 return;
383 }
384 }
385@@ -496,103 +428,13 @@ std::vector<std::string> parseNodeParts(Node* node) {
386 // testQuery tries to calculate if the query (ie a media query or
387 // container query) applies to the node passed
388
389-bool testQuery(Node* node, std::vector<std::vector<std::string>> parts) {
390- // Takes a fully parsed selector. If it is a at-rule even multiple,
391- // the at-rule tag must but the first.
392-
393-
394-Just a ref
395-bool result = false;
396-for (auto& condition : conditions) {
397- result = result || evaluateSingleQuery(condition, windowProps);
398-}
399-
400-
401-also not can only be at the start
402-
403-
404- Window* w = node->window;
405-
406- std::string tag = parts[0][0];
407- parts[0].erase(parts[0].begin());
408-
409- if (tag == "@media") {
410- for (size_t i = 0; i < parts.size(); i++) {
411- bool prev = false;
412- bool match = false;
413- for (size_t j = 0; j < parts[i].size(); j++) {
414- if (parts[i][j] == "and") {
415-
416- }
417- }
418- }
419- }
420-
421- return true;
422-}
423-
424-
425- at-rules consist of "query's" the are tre or false given the stat of the window.
426- executeQuery runs the non-logic (and, or etc..) and returns the value of the
427- executed query.
428-
429-
430-std::unordered_map<std::string, Media> MediaLookup {
431- {"all", Media::All},
432- {"print", Media::Print},
433- {"screen", Media::Screen},
434- {"none", Media::None},
435- {"hover", Media::Hover},
436- {"fine", Media::Fine},
437- {"coarse", Media::Coarse},
438- {"landscape", Media::Landscape},
439- {"portrait", Media::Portrait},
440- {"light", Media::Light},
441- {"dark", Media::Dark},
442- {"no-preference", Media::NoPreference},
443- {"more", Media::More},
444- {"less", Media::Less},
445- {"reduce", Media::Reduce},
446- {"fast", Media::Fast},
447- {"slow", Media::Slow},
448-};
449-
450-// Media queries like @media (hover: hover) are written like @media (hover)
451-bool executeQuery(Window* w, std::string p) {
452- Context c;
453- c.id = window->symbol_table.get("all");
454- c.type = UnitType::BOOL;
455- c.value = w->getMedia() == Media::All;
456- c.previous = nullptr;
457-
458-
459-
460- std::vector<Unit> parsed = getUnit();
461- add the Units to the end and set the indexes
462-
463-
464-
465- // Lookup keyword
466- if (p == "all") {
467- matches = w->getMedia() == Media::All;
468- } else if (p == "print") {
469- matches = w->getMedia() == Media::Print;
470- } else if (p == "screen") {
471- matches = w->getMedia() == Media::Screen;
472- }
473- }
474- }
475- return matches;
476-}
477-
478-
479 Range getNextUnit(const std::vector<Unit>& units, size_t& offset, size_t end) {
480 if (offset >= end) return {0, 0}; // Done
481
482 size_t start = offset;
483 const Unit& unit = units[offset];
484
485- if (unit.type > UnitType::FUNC_START) {
486+ if (unit.type > FUNC_START) {
487 // Range is the function unit + its body
488 size_t argEnd = offset + unit.value + 1;
489 offset = argEnd; // Move offset past this function for next time
490@@ -604,156 +446,158 @@ Range getNextUnit(const std::vector<Unit>& units, size_t& offset, size_t end) {
491 }
492
493 // HEAP: [width, height, em, dpi]
494+// HEAP LAYOUT: VAR
495
496-Unit UnitValue(Memory& m, std::vector<Unit>& units, size_t start, size_t end) {
497- Unit result{};
498- result.type = UnitType::NUMBER;
499- result.value = 0.0f;
500- UnitType op = UnitType::ADD;
501+float unit_value(struct Unit_Vector** heap, struct Unit_Vector** units, int start, int end) {
502+ struct Unit result = {NUMBER, 0.0f};
503+ UnitType op = ADD;
504
505- Unit iv;
506+ struct Unit iv;
507+
508+ // Will normally be 0 unless data is added to the heap before hand
509+ int heap_ptr = heap.length;
510
511- for (size_t i = start; i < end; i++) {
512- Unit unit = units[i];
513+ for (int i = start; i < end; i++) {
514+ struct Unit unit = units.units[i];
515 UnitType type = unit.type;
516
517 switch (type) {
518- case UnitType::ADD:
519- case UnitType::SUB:
520- case UnitType::DIV:
521- case UnitType::MULT:
522- case UnitType::LT:
523- case UnitType::LE:
524- case UnitType::GT:
525- case UnitType::GE:
526- case UnitType::EQ:
527- case UnitType::AND:
528- case UnitType::OR:
529- case UnitType::NOT:
530- case UnitType::ONLY: {
531+ case ADD:
532+ case SUB:
533+ case DIV:
534+ case MULT:
535+ case LT:
536+ case LE:
537+ case GT:
538+ case GE:
539+ case EQ:
540+ case AND:
541+ case OR:
542+ case NOT:
543+ case ONLY: {
544 op = type;
545 continue;
546 }
547 // DEG, TURN are not length values but are treated as generic units (PX)
548- case UnitType::DEG:
549- case UnitType::TURN:
550- case UnitType::NUMBER:
551+ case DEG:
552+ case TURN:
553+ case NUMBER:
554 // NUMBER is any untyped numbers "2". Treat as a pixel
555- case UnitType::PX: {
556- iv.type = UnitType::NUMBER;
557+ case PX: {
558+ iv.type = NUMBER;
559 iv.value = unit.value;
560 break;
561 }
562- case UnitType::CM: {
563- iv.type = UnitType::NUMBER;
564+ case CM: {
565+ iv.type = NUMBER;
566 iv.value = unit.value*37.8f;
567 break;
568 }
569- case UnitType::MM: {
570- iv.type = UnitType::NUMBER;
571+ case MM: {
572+ iv.type = NUMBER;
573 iv.value = unit.value*3.78f;
574 break;
575 }
576- case UnitType::Q: {
577- iv.type = UnitType::NUMBER;
578+ case Q: {
579+ iv.type = NUMBER;
580 iv.value = unit.value*0.94f;
581 break;
582 }
583- case UnitType::IN: {
584- iv.type = UnitType::NUMBER;
585+ case IN: {
586+ iv.type = NUMBER;
587 iv.value = unit.value*96.0f;
588 break;
589 }
590- case UnitType::PC: {
591- iv.type = UnitType::NUMBER;
592+ case PC: {
593+ iv.type = NUMBER;
594 iv.value = unit.value*16.0f;
595 break;
596 }
597- case UnitType::PT: {
598- iv.type = UnitType::NUMBER;
599+ case PT: {
600+ iv.type = NUMBER;
601 iv.value = unit.value*1.3f;
602 break;
603 }
604- case UnitType::EM:
605- case UnitType::REM:
606- case UnitType::CAP:
607+ case EM:
608+ case REM:
609+ case CAP:
610 // Technically wrong but fonts aren't loaded before this is ran
611- case UnitType::CH:
612- case UnitType::IC:
613- case UnitType::LH:
614- case UnitType::RCAP:
615- case UnitType::RCH:
616- case UnitType::RIC:
617- case UnitType::RLH: {
618- iv.type = UnitType::NUMBER;
619- iv.value = unit.value*m.heap[2].value;
620+ case CH:
621+ case IC:
622+ case LH:
623+ case RCAP:
624+ case RCH:
625+ case RIC:
626+ case RLH: {
627+ iv.type = NUMBER;
628+ iv.value = unit.value*heap.units[2].value;
629 break;
630 }
631- case UnitType::EX:
632- case UnitType::REX: {
633- iv.type = UnitType::NUMBER;
634- iv.value = unit.value*(m.heap[2].value*0.5f);
635+ case EX:
636+ case REX: {
637+ iv.type = NUMBER;
638+ iv.value = unit.value*(heap.units[2].value*0.5f);
639 break;
640 }
641- case UnitType::CQH:
642- case UnitType::VH: {
643- iv.type = UnitType::NUMBER;
644- iv.value = m.heap[1].value*(unit.value*0.01f);
645+ case CQH:
646+ case VH: {
647+ iv.type = NUMBER;
648+ iv.value = heap.units[1].value*(unit.value*0.01f);
649 break;
650 }
651- case UnitType::CQW:
652- case UnitType::CQI:
653- case UnitType::CQB:
654- case UnitType::PERCENT:
655- case UnitType::VW: {
656- iv.type = UnitType::NUMBER;
657- iv.value = m.heap[0].value*(unit.value*0.01f);
658+ case CQW:
659+ case CQI:
660+ case CQB:
661+ case PERCENT:
662+ case VW: {
663+ iv.type = NUMBER;
664+ iv.value = heap.units[0].value*(unit.value*0.01f);
665 break;
666 }
667- case UnitType::VMAX:
668- case UnitType::CQMAX: {
669- iv.type = UnitType::NUMBER;
670+ case VMAX:
671+ case CQMAX: {
672+ iv.type = NUMBER;
673 // 0: width
674 // 1: height
675- if (m.heap[0].value > m.heap[1].value) {
676- iv.value = unit.value*m.heap[0].value;
677+ if (heap.units[0].value > heap.units[1].value) {
678+ iv.value = unit.value*heap.units[0].value;
679 } else {
680- iv.value = unit.value*m.heap[1].value;
681+ iv.value = unit.value*heap.units[1].value;
682 }
683 break;
684 }
685- case UnitType::VMIN:
686- case UnitType::CQMIN: {
687- iv.type = UnitType::NUMBER;
688- if (m.heap[0].value < m.heap[1].value) {
689- iv.value = unit.value*m.heap[0].value;
690+ case VMIN:
691+ case CQMIN: {
692+ iv.type = NUMBER;
693+ if (heap.units[0].value < heap.units[1].value) {
694+ iv.value = unit.value*heap.units[0].value;
695 } else {
696- iv.value = unit.value*m.heap[1].value;
697+ iv.value = unit.value*heap.units[1].value;
698 }
699 break;
700 }
701- case UnitType::VB:
702- case UnitType::VI: {
703- iv.type = UnitType::NUMBER;
704- iv.value = unit.value*m.heap[0].value;
705+ case VB:
706+ case VI: {
707+ iv.type = NUMBER;
708+ iv.value = unit.value*heap.units[0].value;
709 break;
710 }
711- case UnitType::GROUP: {
712+ case GROUP: {
713 Snapshot s = m.save();
714 iv = UnitValue(m, units, i+1, i+1+unit.value);
715 i += unit.value;
716 m.restore(s);
717 break;
718 }
719- case UnitType::CALC: {
720- iv.type = UnitType::NUMBER;
721+ case CALC: {
722+ iv.type = NUMBER;
723 Unit u1 = UnitValue(m, units, i+1, i+1+unit.value);
724 iv.value = u1.value;
725 i += unit.value;
726 break;
727 }
728- case UnitType::MIN: {
729- iv.type = UnitType::NUMBER;
730+ case MIN: {
731+ iv.type = NUMBER;
732
733 size_t start = i + 1;
734 size_t end = i + 1 + unit.value;
735@@ -770,8 +614,8 @@ Unit UnitValue(Memory& m, std::vector<Unit>& units, size_t start, size_t end) {
736 i += unit.value;
737 break;
738 }
739- case UnitType::MAX: {
740- iv.type = UnitType::NUMBER;
741+ case MAX: {
742+ iv.type = NUMBER;
743
744 size_t start = i + 1;
745 size_t end = i + 1 + unit.value;
746@@ -787,8 +631,8 @@ Unit UnitValue(Memory& m, std::vector<Unit>& units, size_t start, size_t end) {
747 i += unit.value;
748 break;
749 }
750- case UnitType::CLAMP: {
751- iv.type = UnitType::NUMBER;
752+ case CLAMP: {
753+ iv.type = NUMBER;
754
755 float args[3];
756 int found = 0;
757@@ -809,10 +653,10 @@ Unit UnitValue(Memory& m, std::vector<Unit>& units, size_t start, size_t end) {
758 i += unit.value;
759 break;
760 }
761- case UnitType::ROUND: {
762- iv.type = UnitType::NUMBER;
763+ case ROUND: {
764+ iv.type = NUMBER;
765
766- UnitType ut = UnitType::NEAREST;
767+ UnitType ut = NEAREST;
768
769 Unit args[3];
770 int found = 0;
771@@ -828,33 +672,33 @@ Unit UnitValue(Memory& m, std::vector<Unit>& units, size_t start, size_t end) {
772 ut = args[0].type;
773
774 } else if (found == 2) {
775- ut = UnitType::NEAREST;
776+ ut = NEAREST;
777
778 args[2].value = args[1].value;
779 args[1].value = args[0].value;
780 } else if (found == 1) {
781- ut = UnitType::NEAREST;
782+ ut = NEAREST;
783
784 args[1].value = args[0].value;
785 args[2].value = 1.0f;
786 }
787
788
789- if (ut == UnitType::NEAREST) {
790+ if (ut == NEAREST) {
791 iv.value = std::round(args[1].value/args[2].value)*args[2].value;
792- } else if (ut == UnitType::UP) {
793+ } else if (ut == UP) {
794 iv.value = std::ceil(args[1].value/args[2].value)*args[2].value;
795- } else if (ut == UnitType::DOWN) {
796+ } else if (ut == DOWN) {
797 iv.value = std::floor(args[1].value/args[2].value)*args[2].value;
798- } else if (ut == UnitType::TO_ZERO) {
799+ } else if (ut == TO_ZERO) {
800 iv.value = std::trunc(args[1].value/args[2].value)*args[2].value;
801 }
802
803 i += unit.value;
804 break;
805 }
806- case UnitType::MOD: {
807- iv.type = UnitType::NUMBER;
808+ case MOD: {
809+ iv.type = NUMBER;
810
811 float args[2];
812 int found = 0;
813@@ -875,8 +719,8 @@ Unit UnitValue(Memory& m, std::vector<Unit>& units, size_t start, size_t end) {
814 i += unit.value;
815 break;
816 }
817- case UnitType::PROGRESS: {
818- iv.type = UnitType::NUMBER;
819+ case PROGRESS: {
820+ iv.type = NUMBER;
821
822 float args[3];
823 int found = 0;
824@@ -899,8 +743,8 @@ Unit UnitValue(Memory& m, std::vector<Unit>& units, size_t start, size_t end) {
825 i += unit.value;
826 break;
827 }
828- case UnitType::REMD: {
829- iv.type = UnitType::NUMBER;
830+ case REMD: {
831+ iv.type = NUMBER;
832
833 float args[2];
834 int found = 0;
835@@ -921,50 +765,50 @@ Unit UnitValue(Memory& m, std::vector<Unit>& units, size_t start, size_t end) {
836 i += unit.value;
837 break;
838 }
839- case UnitType::SIN: {
840- iv.type = UnitType::NUMBER;
841+ case SIN: {
842+ iv.type = NUMBER;
843 Unit u1 = UnitValue(m, units, i+1, i+1+unit.value);
844 iv.value = std::sinf(u1.value);
845 i += unit.value;
846 break;
847 }
848- case UnitType::COS: {
849- iv.type = UnitType::NUMBER;
850+ case COS: {
851+ iv.type = NUMBER;
852 Unit u1 = UnitValue(m, units, i+1, i+1+unit.value);
853 iv.value = std::cosf(u1.value);
854 i += unit.value;
855 break;
856 }
857- case UnitType::TAN: {
858- iv.type = UnitType::NUMBER;
859+ case TAN: {
860+ iv.type = NUMBER;
861 Unit u1 = UnitValue(m, units, i+1, i+1+unit.value);
862 iv.value = std::tanf(u1.value);
863 i += unit.value;
864 break;
865 }
866- case UnitType::ASIN: {
867- iv.type = UnitType::NUMBER;
868+ case ASIN: {
869+ iv.type = NUMBER;
870 Unit u1 = UnitValue(m, units, i+1, i+1+unit.value);
871 iv.value = std::asinf(u1.value);
872 i += unit.value;
873 break;
874 }
875- case UnitType::ACOS: {
876- iv.type = UnitType::NUMBER;
877+ case ACOS: {
878+ iv.type = NUMBER;
879 Unit u1 = UnitValue(m, units, i+1, i+1+unit.value);
880 iv.value = std::acosf(u1.value);
881 i += unit.value;
882 break;
883 }
884- case UnitType::ATAN: {
885- iv.type = UnitType::NUMBER;
886+ case ATAN: {
887+ iv.type = NUMBER;
888 Unit u1 = UnitValue(m, units, i+1, i+1+unit.value);
889 iv.value = std::atanf(u1.value);
890 i += unit.value;
891 break;
892 }
893- case UnitType::ATAN2: {
894- iv.type = UnitType::NUMBER;
895+ case ATAN2: {
896+ iv.type = NUMBER;
897
898 float args[2];
899 int found = 0;
900@@ -985,8 +829,8 @@ Unit UnitValue(Memory& m, std::vector<Unit>& units, size_t start, size_t end) {
901 i += unit.value;
902 break;
903 }
904- case UnitType::POW: {
905- iv.type = UnitType::NUMBER;
906+ case POW: {
907+ iv.type = NUMBER;
908
909 float args[2];
910 int found = 0;
911@@ -1007,15 +851,15 @@ Unit UnitValue(Memory& m, std::vector<Unit>& units, size_t start, size_t end) {
912 i += unit.value;
913 break;
914 }
915- case UnitType::SQRT: {
916- iv.type = UnitType::NUMBER;
917+ case SQRT: {
918+ iv.type = NUMBER;
919 Unit u1 = UnitValue(m, units, i+1, i+1+unit.value);
920 iv.value = std::sqrtf(u1.value);
921 i += unit.value;
922 break;
923 }
924- case UnitType::HYPOT: {
925- iv.type = UnitType::NUMBER;
926+ case HYPOT: {
927+ iv.type = NUMBER;
928
929
930 float v = 0;
931@@ -1033,8 +877,8 @@ Unit UnitValue(Memory& m, std::vector<Unit>& units, size_t start, size_t end) {
932 i += unit.value;
933 break;
934 }
935- case UnitType::LOG: {
936- iv.type = UnitType::NUMBER;
937+ case LOG: {
938+ iv.type = NUMBER;
939
940 float args[2];
941 int found = 0;
942@@ -1055,22 +899,22 @@ Unit UnitValue(Memory& m, std::vector<Unit>& units, size_t start, size_t end) {
943 i += unit.value;
944 break;
945 }
946- case UnitType::EXP: {
947- iv.type = UnitType::NUMBER;
948+ case EXP: {
949+ iv.type = NUMBER;
950 Unit u1 = UnitValue(m, units, i+1, i+1+unit.value);
951 iv.value = std::expf(u1.value);
952 i += unit.value;
953 break;
954 }
955- case UnitType::ABS: {
956- iv.type = UnitType::NUMBER;
957+ case ABS: {
958+ iv.type = NUMBER;
959 Unit u1 = UnitValue(m, units, i+1, i+1+unit.value);
960 iv.value = std::fabsf(u1.value);
961 i += unit.value;
962 break;
963 }
964- case UnitType::SIGN: {
965- iv.type = UnitType::NUMBER;
966+ case SIGN: {
967+ iv.type = NUMBER;
968 Unit u1 = UnitValue(m, units, i+1, i+1+unit.value);
969
970 if (u1.value > 0) {
971@@ -1084,7 +928,7 @@ Unit UnitValue(Memory& m, std::vector<Unit>& units, size_t start, size_t end) {
972 i += unit.value;
973 break;
974 }
975- case UnitType::ATTR: {
976+ case ATTR: {
977 Range args[3];
978 int found = 0;
979 size_t start = i + 1;
980@@ -1105,7 +949,7 @@ Unit UnitValue(Memory& m, std::vector<Unit>& units, size_t start, size_t end) {
981 Unit u2 = units[args[1].start];
982
983 // Cast the user defined type onto the value
984- if (u2.type == UnitType::TYPE) {
985+ if (u2.type == TYPE) {
986 value.type = units[args[1].start+1].type;
987 } else {
988 value.type = u2.type;
989@@ -1121,7 +965,7 @@ Unit UnitValue(Memory& m, std::vector<Unit>& units, size_t start, size_t end) {
990 i += unit.value;
991 break;
992 }
993- case UnitType::VAR_FUNC: {
994+ case VAR_FUNC: {
995 Unit args[2];
996 int found = 0;
997 size_t start = i + 1;
998@@ -1144,23 +988,23 @@ Unit UnitValue(Memory& m, std::vector<Unit>& units, size_t start, size_t end) {
999 i += unit.value;
1000 break;
1001 }
1002- case UnitType::VAR: {
1003+ case VAR: {
1004 Range r = m.get(unit.value);
1005
1006 if (r.end > 0) {
1007- iv = m.heap[r.start];
1008+ iv = heap.units[r.start];
1009 }
1010
1011 break;
1012 }
1013- case UnitType::PRINT: {
1014+ case PRINT: {
1015 Unit u = UnitValue(m, units, i+1, i+1+unit.value);
1016 std::cout << "> " << u.value << std::endl;
1017 iv = u;
1018 i += unit.value;
1019 break;
1020 }
1021- case UnitType::IF: {
1022+ case IF: {
1023 Range args[4]; // condition trueval else falseval
1024 int found = 0;
1025 size_t start = i + 1;
1026@@ -1176,7 +1020,7 @@ Unit UnitValue(Memory& m, std::vector<Unit>& units, size_t start, size_t end) {
1027 iv = UnitValue(m, units, args[1].start, args[1].end);
1028 } else {
1029 UnitType u = units[args[2].start].type;
1030- if (u == UnitType::ELSE) {
1031+ if (u == ELSE) {
1032 iv = UnitValue(m, units, args[3].start, args[3].end);
1033 } else {
1034 iv = UnitValue(m, units, args[2].start, args[2].end);
1035@@ -1187,23 +1031,23 @@ Unit UnitValue(Memory& m, std::vector<Unit>& units, size_t start, size_t end) {
1036 i += unit.value;
1037 break;
1038 }
1039- case UnitType::LET: {
1040+ case LET: {
1041 Unit u = UnitValue(m, units, i + 2, i + 1 + unit.value);
1042 m.push_back(units[i+1].value, u);
1043
1044 i += unit.value;
1045 break;
1046 }
1047- case UnitType::SET: {
1048- if (units[i + 1].type == UnitType::VAR) {
1049+ case SET: {
1050+ if (units[i + 1].type == VAR) {
1051 Range r = m.get(units[i + 1].value);
1052 Unit u = UnitValue(m, units, i + 2, i + 1 + unit.value);
1053
1054 // r.end is the length
1055 if (r.end > 0) { // need to write over
1056- m.heap[r.start] = u;
1057+ heap.units[r.start] = u;
1058 }
1059- } else if (units[i + 1].type == UnitType::AT && units[i + 2].type == UnitType::VAR) {
1060+ } else if (units[i + 1].type == AT && units[i + 2].type == VAR) {
1061 // Set at in a list
1062 Range r = m.get(units[i+2].value);
1063
1064@@ -1218,14 +1062,14 @@ Unit UnitValue(Memory& m, std::vector<Unit>& units, size_t start, size_t end) {
1065 if (r.end > 0) {
1066 Unit p = UnitValue(m, units, i + 2, i + 1 + units[i+2].value);
1067 Unit u = UnitValue(m, units, i + 2, i + 1 + unit.value);
1068- m.heap[r.start + p.value] = u;
1069+ heap.units[r.start + p.value] = u;
1070 }
1071 }
1072
1073 i += unit.value;
1074 break;
1075 }
1076- case UnitType::LIST: {
1077+ case LIST: {
1078
1079
1080
1081@@ -1244,7 +1088,7 @@ Unit UnitValue(Memory& m, std::vector<Unit>& units, size_t start, size_t end) {
1082
1083
1084
1085- if (units[i + 2].type == UnitType::EMPTY) {
1086+ if (units[i + 2].type == EMPTY) {
1087 Unit emptyCount = UnitValue(m, units, i+3, i + 3 +units[i + 2].value);
1088 m.alloc(units[i+1].value, emptyCount.value);
1089 } else {
1090@@ -1254,7 +1098,7 @@ Unit UnitValue(Memory& m, std::vector<Unit>& units, size_t start, size_t end) {
1091 i += unit.value;
1092 break;
1093 }
1094- case UnitType::AT: {
1095+ case AT: {
1096 Range r = m.get(units[i+1].value);
1097
1098 if (r.end > 0) {
1099@@ -1273,13 +1117,13 @@ Unit UnitValue(Memory& m, std::vector<Unit>& units, size_t start, size_t end) {
1100
1101
1102
1103- iv = m.heap[r.start + index.value];
1104+ iv = heap.units[r.start + index.value];
1105 }
1106
1107 i += unit.value;
1108 break;
1109 }
1110- case UnitType::INSERT: {
1111+ case INSERT: {
1112 Range listRange = m.get(units[i+1].value);
1113 size_t size = listRange.end-listRange.start;
1114
1115@@ -1307,7 +1151,7 @@ Unit UnitValue(Memory& m, std::vector<Unit>& units, size_t start, size_t end) {
1116
1117
1118 if (ri.end-ri.start + index.value < size) {
1119- std::copy(m.heap.begin() + ri.start, m.heap.begin() + ri.end, m.heap.begin()+listRange.start + index.value);
1120+ std::copy(heap.units.begin() + ri.start, heap.units.begin() + ri.end, heap.units.begin()+listRange.start + index.value);
1121 } else {
1122 std::cerr << "Cannot insert data at index: " << index.value << " list size: " << size << " data to be inserted: " << ri.end-ri.start << std::endl;
1123 }
1124@@ -1315,7 +1159,7 @@ Unit UnitValue(Memory& m, std::vector<Unit>& units, size_t start, size_t end) {
1125 i += unit.value;
1126 break;
1127 }
1128- case UnitType::SIZE: {
1129+ case SIZE: {
1130
1131
1132
1133@@ -1325,7 +1169,7 @@ Unit UnitValue(Memory& m, std::vector<Unit>& units, size_t start, size_t end) {
1134
1135
1136 Range r = m.get(units[i+1].value);
1137- iv = {UnitType::NUMBER, (float)r.end-(float)r.start};
1138+ iv = {NUMBER, (float)r.end-(float)r.start};
1139
1140 i += unit.value;
1141 break;
1142@@ -1333,65 +1177,65 @@ Unit UnitValue(Memory& m, std::vector<Unit>& units, size_t start, size_t end) {
1143 }
1144
1145 switch (op) {
1146- case UnitType::ADD:
1147- result.type = UnitType::NUMBER;
1148+ case ADD:
1149+ result.type = NUMBER;
1150 result.value += iv.value;
1151- op = UnitType::NONOP;
1152+ op = NONOP;
1153 break;
1154- case UnitType::SUB:
1155- result.type = UnitType::NUMBER;
1156+ case SUB:
1157+ result.type = NUMBER;
1158 result.value -= iv.value;
1159- op = UnitType::NONOP;
1160+ op = NONOP;
1161 break;
1162- case UnitType::DIV:
1163- result.type = UnitType::NUMBER;
1164+ case DIV:
1165+ result.type = NUMBER;
1166 result.value /= iv.value;
1167- op = UnitType::NONOP;
1168+ op = NONOP;
1169 break;
1170- case UnitType::MULT:
1171- result.type = UnitType::NUMBER;
1172+ case MULT:
1173+ result.type = NUMBER;
1174 result.value *= iv.value;
1175- op = UnitType::NONOP;
1176+ op = NONOP;
1177 break;
1178- case UnitType::LT:
1179- result.type = UnitType::BOOL;
1180+ case LT:
1181+ result.type = BOOL;
1182 result.value = result.value < iv.value;
1183- op = UnitType::NONOP;
1184+ op = NONOP;
1185 break;
1186- case UnitType::GT:
1187- result.type = UnitType::BOOL;
1188+ case GT:
1189+ result.type = BOOL;
1190 result.value = result.value > iv.value;
1191- op = UnitType::NONOP;
1192+ op = NONOP;
1193 break;
1194- case UnitType::LE:
1195- result.type = UnitType::BOOL;
1196+ case LE:
1197+ result.type = BOOL;
1198 result.value = result.value <= iv.value;
1199- op = UnitType::NONOP;
1200+ op = NONOP;
1201 break;
1202- case UnitType::GE:
1203- result.type = UnitType::BOOL;
1204+ case GE:
1205+ result.type = BOOL;
1206 result.value = result.value >= iv.value;
1207- op = UnitType::NONOP;
1208+ op = NONOP;
1209 break;
1210- case UnitType::EQ:
1211- result.type = UnitType::BOOL;
1212+ case EQ:
1213+ result.type = BOOL;
1214 result.value = result.value == iv.value;
1215- op = UnitType::NONOP;
1216+ op = NONOP;
1217 break;
1218- case UnitType::AND:
1219- result.type = UnitType::BOOL;
1220+ case AND:
1221+ result.type = BOOL;
1222 result.value = result.value && iv.value;
1223- op = UnitType::NONOP;
1224+ op = NONOP;
1225 break;
1226- case UnitType::OR:
1227- result.type = UnitType::BOOL;
1228+ case OR:
1229+ result.type = BOOL;
1230 result.value = result.value || iv.value;
1231- op = UnitType::NONOP;
1232+ op = NONOP;
1233 break;
1234- case UnitType::NOT:
1235- result.type = UnitType::BOOL;
1236+ case NOT:
1237+ result.type = BOOL;
1238 result.value = !iv.value;
1239- op = UnitType::NONOP;
1240+ op = NONOP;
1241 break;
1242 default:
1243 result = iv;
1244diff --git a/src/parser.c b/src/parser.c
1245index eb14712..b9c726f 100755
1246--- a/src/parser.c
1247+++ b/src/parser.c
1248@@ -90,7 +90,7 @@ void write_unit(struct Unit** units_ptr, int* len, int* cap, struct Unit val) {
1249 (*len)++;
1250 }
1251
1252-void get_unit(SymbolTable* sym, struct Unit** units, int* cap, int* units_len, char* value) {
1253+void get_unit(struct Unit** units, int* cap, int* units_len, char* value) {
1254 char buffer[1024];
1255 int buffer_len = 0;
1256
1257@@ -107,6 +107,9 @@ void get_unit(SymbolTable* sym, struct Unit** units, int* cap, int* units_len, c
1258
1259 int size = strlen(value);
1260
1261+
1262+ int depth = 0; // Add every time a functions is entered in
1263+
1264 for (int i = 0; i < size; i++) {
1265 char v = value[i];
1266 if (v == '\\' && !escaped) escaped = true;
1267@@ -195,6 +198,12 @@ void get_unit(SymbolTable* sym, struct Unit** units, int* cap, int* units_len, c
1268 }
1269 }
1270
1271+
1272+ // Logic for LET and SET
1273+ // on a non var declaration add current vars_len to the stack
1274+ // on LET add the word to the vars list
1275+ // on SET reverse index the array
1276+
1277 args[args_len++] = '\0';
1278
1279 int function_idx = *units_len;
1280@@ -203,7 +212,7 @@ void get_unit(SymbolTable* sym, struct Unit** units, int* cap, int* units_len, c
1281 write_unit(units, units_len, cap, placeholder);
1282
1283 int before_count = *units_len;
1284- get_unit(sym, units, cap, units_len, args);
1285+ get_unit(units, cap, units_len, args);
1286 int child_count = *units_len - before_count;
1287
1288 const struct FuncMap* fm = find_func(name, name_len);
1289@@ -405,7 +414,7 @@ std::string pathJoin(const std::string& p1, const std::string& p2) {
1290 }
1291 */
1292
1293-void html_parser(SymbolTable* sym, Node* root, const char* input, int size) {
1294+void html_parser(Node* root, const char* input, int size) {
1295 Node* currentNode = root;
1296
1297 bool inTag = false;
1298@@ -436,7 +445,7 @@ void html_parser(SymbolTable* sym, Node* root, const char* input, int size) {
1299
1300 token[token_length] = '\0';
1301 if (token_length > 0) {
1302- Node* textNode = CREATE_ELEMENT(sym, "text");
1303+ Node* textNode = CREATE_ELEMENT("text");
1304 SET_INNERTEXT(textNode, token);
1305 APPEND_CHILD(currentNode, textNode);
1306 }
1307@@ -497,14 +506,14 @@ void html_parser(SymbolTable* sym, Node* root, const char* input, int size) {
1308 inQuote = false;
1309 if (attr_name[0] != '\0' && attr_name_set) {
1310 if (strcmp(attr_name, "id") == 0) {
1311- SET_ID(sym, currentNode, token);
1312+ SET_ID(currentNode, token);
1313 } else if (strcmp(attr_name, "class") == 0) {
1314 char* buffer = "\0";
1315 int buffer_length = 0;
1316 for (int j = 0; j < token_length; j++) {
1317 if (isspace(token[j])) {
1318 buffer[buffer_length++] = '\0';
1319- ADD_CLASS(sym, currentNode, buffer);
1320+ ADD_CLASS(currentNode, buffer);
1321 buffer[0] = '\0';
1322 buffer_length = 0;
1323 } else {
1324@@ -539,7 +548,7 @@ void html_parser(SymbolTable* sym, Node* root, const char* input, int size) {
1325 strcpy(tagname, token);
1326
1327 if (tagname[0] != '!') {
1328- Node* node = CREATE_ELEMENT(sym, tagname);
1329+ Node* node = CREATE_ELEMENT(tagname);
1330 APPEND_CHILD(currentNode, node);
1331 if (!self_closing) {
1332 currentNode = node;
1333@@ -614,7 +623,7 @@ void html_parser(SymbolTable* sym, Node* root, const char* input, int size) {
1334 }
1335
1336 if (has_text) {
1337- Node* node = CREATE_ELEMENT(sym, "text");
1338+ Node* node = CREATE_ELEMENT("text");
1339 SET_INNERTEXT(node, token);
1340 APPEND_CHILD(currentNode, node);
1341 }