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 			}