home readme diff tree note docs

0commit 440895de367aca1b1eab94209200b2bb00b682ef
1Author: lakefox <mason@lakefox.net>
2Date:   Fri Jan 23 20:02:40 2026 -0700
3
4    Removed UnitType union in favor of a float
5
6diff --git a/Makefile b/Makefile
7index 5197f09..e30b7f0 100755
8--- a/Makefile
9+++ b/Makefile
10@@ -1,4 +1,5 @@
11 # --- Variables ---
12+#CCFLAGS = -std=c++2b -O3
13 CCFLAGS = -Wall -Wextra -std=c++2b -g -O0 -fsanitize=address,undefined -fno-omit-frame-pointer
14 # -O2 -Wall -Wformat -Wformat=2 -Wconversion -Wimplicit-fallthrough \
15 # -Werror=format-security \
16diff --git a/include/grim.h b/include/grim.h
17index 45d25bb..7ca03fd 100755
18--- a/include/grim.h
19+++ b/include/grim.h
20@@ -98,7 +98,7 @@ enum class UnitType : short {
21 		HYPOT, LOG, EXP, ABS, SIGN, SIN, COS, TAN, ASIN, ACOS, ATAN, ATAN2, VAR_FUNC,
22 		BLUR, BRIGHTNESS, CONTRAST, DROP_SHADOW, GRAYSCALE, HUE_ROTATE, INVERT, 
23 		OPACITY, SEPIA, SATURATE, ATTR, TYPE, ENV, IF, FUNC, LET, RETURN, SET,
24-		LIST,
25+		LIST, AT,
26 		
27 		// Easing Functions
28 		EASING_FUNCTION, LINEAR_EASING_FUNCTION, LINEAR, EASE, EASE_IN, EASE_OUT, EASE_IN_OUT, CUBIC_BEZIER_FUNCTION, 
29@@ -117,20 +117,10 @@ enum class UnitType : short {
30 };
31 
32 
33-// 4 bytes
34-union UnitValue {
35-	UnitType ENUM;
36-	int INT;
37-	unsigned int UINT;
38-	float FLOAT;
39-	bool BOOL;
40-	char CHAR;
41-};
42-
43 // 8 bytes 
44 struct Unit {
45 	UnitType type; // short
46-	UnitValue value;
47+	float value;
48 };
49 
50 struct Range {
51@@ -164,8 +154,8 @@ class Memory {
52 			size_t len = end-start;
53 			arena.push_back({id, pointer, len, current});
54 			current = &arena.back();
55-			pointer += len;
56 			std::copy(units.begin() + start, units.begin() + end, heap.begin() + pointer);
57+			pointer += len;
58 		}
59 
60 		// Used to prefill the heap
61diff --git a/playground/unitvalue.cc b/playground/unitvalue.cc
62index bab6d4a..9d56df9 100644
63--- a/playground/unitvalue.cc
64+++ b/playground/unitvalue.cc
65@@ -51,13 +51,13 @@ int main() {
66 
67 	Memory m;
68 	// Preset width, height, and em
69-	m.push_back(sym.get("width"),{UnitType::NUMBER, {.FLOAT = 1000.0f}});
70-	m.push_back(sym.get("height"),{UnitType::NUMBER, {.FLOAT = 700.0f}});
71-	m.push_back(sym.get("em"),{UnitType::NUMBER, {.FLOAT= 16.0f}});
72+	m.push_back(sym.get("width"),{UnitType::NUMBER, 1000.0f});
73+	m.push_back(sym.get("height"),{UnitType::NUMBER, 700.0f});
74+	m.push_back(sym.get("em"),{UnitType::NUMBER, 16.0f});
75 
76-	std::vector<Unit> units = getUnit("if((1 > 1): 10px; else: 11vw;)", &sym);
77+	std::vector<Unit> units = getUnit("list(x 5 2 3 4) print(at(x 0)) set(at(x 0) 13) print(at(x 0))", &sym);
78 	
79 	Unit u = UnitValue(m, units, 0, units.size());
80 
81-	std::cout << "Value: " << u.value.FLOAT << std::endl;
82+	std::cout << "Value: " << u.value << std::endl;
83 }
84diff --git a/src/grim.cc b/src/grim.cc
85index 0ea2d69..8ab1d5a 100755
86--- a/src/grim.cc
87+++ b/src/grim.cc
88@@ -878,7 +878,7 @@ bool executeQuery(Window* w, std::string p) {
89 	Context c;
90 	c.id = window->symbol_table.get("all");
91 	c.type = UnitType::BOOL;
92-	c.value.BOOL = w->getMedia() == Media::All;
93+	c.value = w->getMedia() == Media::All;
94 	c.previous = nullptr;
95 
96 
97@@ -910,7 +910,7 @@ Range getNextUnit(const std::vector<Unit>& units, size_t& offset, size_t end) {
98 
99     if (unit.type > UnitType::FUNC_START) {
100         // Range is the function unit + its body
101-        size_t argEnd = offset + unit.value.INT + 1;
102+        size_t argEnd = offset + unit.value + 1;
103         offset = argEnd; // Move offset past this function for next time
104         return {start, argEnd};
105     } else {
106@@ -924,7 +924,7 @@ Range getNextUnit(const std::vector<Unit>& units, size_t& offset, size_t end) {
107 Unit UnitValue(Memory& m, std::vector<Unit>& units, size_t start, size_t end) {
108 	Unit result{};
109 	result.type = UnitType::NUMBER;
110-	result.value.FLOAT = 0.0f;
111+	result.value = 0.0f;
112 	UnitType op = UnitType::ADD;
113 
114 	Unit iv;
115@@ -957,37 +957,37 @@ Unit UnitValue(Memory& m, std::vector<Unit>& units, size_t start, size_t end) {
116 				// NUMBER is any untyped numbers "2". Treat as a pixel
117 			case UnitType::PX: {
118 				iv.type = UnitType::NUMBER;
119-				iv.value.FLOAT = unit.value.FLOAT;
120+				iv.value = unit.value;
121 				break;
122 			}
123 			case UnitType::CM: {
124 				iv.type = UnitType::NUMBER;
125-				iv.value.FLOAT = unit.value.FLOAT*37.8f;
126+				iv.value = unit.value*37.8f;
127 				break;
128 			}
129 			case UnitType::MM: {
130 				iv.type = UnitType::NUMBER;
131-				iv.value.FLOAT = unit.value.FLOAT*3.78f;
132+				iv.value = unit.value*3.78f;
133 				break;
134 			}
135 			case UnitType::Q: {
136 				iv.type = UnitType::NUMBER;
137-				iv.value.FLOAT = unit.value.FLOAT*0.94f;
138+				iv.value = unit.value*0.94f;
139 				break;
140 			}
141 			case UnitType::IN: {
142 				iv.type = UnitType::NUMBER;
143-				iv.value.FLOAT = unit.value.FLOAT*96.0f;
144+				iv.value = unit.value*96.0f;
145 				break;
146 			}
147 			case UnitType::PC: {
148 				iv.type = UnitType::NUMBER;
149-				iv.value.FLOAT = unit.value.FLOAT*16.0f;
150+				iv.value = unit.value*16.0f;
151 				break;
152 			}
153 			case UnitType::PT: {
154 				iv.type = UnitType::NUMBER;
155-				iv.value.FLOAT = unit.value.FLOAT*1.3f;
156+				iv.value = unit.value*1.3f;
157 				break;
158 			}
159 			case UnitType::EM:
160@@ -1002,19 +1002,19 @@ Unit UnitValue(Memory& m, std::vector<Unit>& units, size_t start, size_t end) {
161 			case UnitType::RIC:
162 			case UnitType::RLH: {
163 				iv.type = UnitType::NUMBER;
164-				iv.value.FLOAT = unit.value.FLOAT*m.heap[2].value.FLOAT;
165+				iv.value = unit.value*m.heap[2].value;
166 				break;
167 			}
168 			case UnitType::EX:
169 			case UnitType::REX: {
170 				iv.type = UnitType::NUMBER;
171-				iv.value.FLOAT = unit.value.FLOAT*(m.heap[2].value.FLOAT*0.5f);
172+				iv.value = unit.value*(m.heap[2].value*0.5f);
173 				break;
174 			}
175 			case UnitType::CQH:
176 			case UnitType::VH: {
177 				iv.type = UnitType::NUMBER;
178-				iv.value.FLOAT = m.heap[1].value.FLOAT*(unit.value.FLOAT*0.01f);
179+				iv.value = m.heap[1].value*(unit.value*0.01f);
180 				break;
181 			}
182 			case UnitType::CQW:
183@@ -1023,7 +1023,7 @@ Unit UnitValue(Memory& m, std::vector<Unit>& units, size_t start, size_t end) {
184 			case UnitType::PERCENT:
185 			case UnitType::VW: {
186 				iv.type = UnitType::NUMBER;
187-				iv.value.FLOAT = m.heap[0].value.FLOAT*(unit.value.FLOAT*0.01f);
188+				iv.value = m.heap[0].value*(unit.value*0.01f);
189 				break;
190 			}
191 			case UnitType::VMAX:
192@@ -1031,76 +1031,76 @@ Unit UnitValue(Memory& m, std::vector<Unit>& units, size_t start, size_t end) {
193 				iv.type = UnitType::NUMBER;
194 				// 0: width
195 				// 1: height
196-				if (m.heap[0].value.FLOAT > m.heap[1].value.FLOAT) {
197-					iv.value.FLOAT = unit.value.FLOAT*m.heap[0].value.FLOAT;
198+				if (m.heap[0].value > m.heap[1].value) {
199+					iv.value = unit.value*m.heap[0].value;
200 				} else {
201-					iv.value.FLOAT = unit.value.FLOAT*m.heap[1].value.FLOAT;
202+					iv.value = unit.value*m.heap[1].value;
203 				}
204 				break;
205 			}
206 			case UnitType::VMIN:
207 			case UnitType::CQMIN: {
208 				iv.type = UnitType::NUMBER;
209-				if (m.heap[0].value.FLOAT < m.heap[1].value.FLOAT) {
210-					iv.value.FLOAT = unit.value.FLOAT*m.heap[0].value.FLOAT;
211+				if (m.heap[0].value < m.heap[1].value) {
212+					iv.value = unit.value*m.heap[0].value;
213 				} else {
214-					iv.value.FLOAT = unit.value.FLOAT*m.heap[1].value.FLOAT;
215+					iv.value = unit.value*m.heap[1].value;
216 				}	
217 				break;
218 			}
219 			case UnitType::VB:
220 			case UnitType::VI: {
221 				iv.type = UnitType::NUMBER;
222-				iv.value.FLOAT = unit.value.FLOAT*m.heap[0].value.FLOAT;
223+				iv.value = unit.value*m.heap[0].value;
224 				break;
225 			}
226 			case UnitType::GROUP: {
227 				Snapshot s = m.save();
228-			      	iv = UnitValue(m, units, i+1, i+1+unit.value.INT);
229-				i += unit.value.INT;
230+			      	iv = UnitValue(m, units, i+1, i+1+unit.value);
231+				i += unit.value;
232 				m.restore(s);
233 				break;
234 			}
235 			case UnitType::CALC: {
236 				iv.type = UnitType::NUMBER;
237-				Unit u1 = UnitValue(m, units, i+1, i+1+unit.value.INT);
238-				iv.value.FLOAT = u1.value.FLOAT;
239-				i += unit.value.INT;
240+				Unit u1 = UnitValue(m, units, i+1, i+1+unit.value);
241+				iv.value = u1.value;
242+				i += unit.value;
243 				break;
244 			}
245 			case UnitType::MIN: {
246 				iv.type = UnitType::NUMBER;
247 
248 				size_t start = i + 1;
249-				size_t end = i + 1 + unit.value.INT;
250+				size_t end = i + 1 + unit.value;
251 
252 				Range r = getNextUnit(units, start, end);
253-				iv.value.FLOAT = UnitValue(m, units, r.start, r.end).value.FLOAT;
254+				iv.value = UnitValue(m, units, r.start, r.end).value;
255 
256 				while (start < end) {
257 					r = getNextUnit(units, start, end);
258-					float u = UnitValue(m, units, r.start, r.end).value.FLOAT;
259-					iv.value.FLOAT = std::min(iv.value.FLOAT, u);
260+					float u = UnitValue(m, units, r.start, r.end).value;
261+					iv.value = std::min(iv.value, u);
262 				}
263 
264-				i += unit.value.INT;
265+				i += unit.value;
266 				break;
267 			}
268 			case UnitType::MAX: {
269 				iv.type = UnitType::NUMBER;
270 
271 				size_t start = i + 1;
272-				size_t end = i + 1 + unit.value.INT;
273+				size_t end = i + 1 + unit.value;
274 
275 				Range r = getNextUnit(units, start, end);
276-				iv.value.FLOAT = UnitValue(m, units, r.start, r.end).value.FLOAT;
277+				iv.value = UnitValue(m, units, r.start, r.end).value;
278 
279 				while (start < end) {
280 					r = getNextUnit(units, start, end);
281-					iv.value.FLOAT = std::max(iv.value.FLOAT, UnitValue(m, units, r.start, r.end).value.FLOAT);
282+					iv.value = std::max(iv.value, UnitValue(m, units, r.start, r.end).value);
283 				}
284 
285-				i += unit.value.INT;
286+				i += unit.value;
287 				break;
288 			}
289 			case UnitType::CLAMP: {
290@@ -1109,20 +1109,20 @@ Unit UnitValue(Memory& m, std::vector<Unit>& units, size_t start, size_t end) {
291 				float args[3];
292 				int found = 0;
293 				size_t start = i + 1;
294-				size_t end = i + 1 + unit.value.INT;
295+				size_t end = i + 1 + unit.value;
296 
297 				while (start < end) {
298 					Range r = getNextUnit(units, start, end);
299-					args[found++] = UnitValue(m, units, r.start, r.end).value.FLOAT;
300+					args[found++] = UnitValue(m, units, r.start, r.end).value;
301 				}
302 
303 				if (found == 3) {
304-					iv.value.FLOAT = std::clamp(args[1], args[0], args[2]);
305+					iv.value = std::clamp(args[1], args[0], args[2]);
306 				} else {
307-					iv.value.FLOAT = args[0];
308+					iv.value = args[0];
309 				}
310 				
311-				i += unit.value.INT;
312+				i += unit.value;
313 				break;
314 			}
315 			case UnitType::ROUND: {
316@@ -1133,7 +1133,7 @@ Unit UnitValue(Memory& m, std::vector<Unit>& units, size_t start, size_t end) {
317 				Unit args[3];
318 				int found = 0;
319 				size_t start = i + 1;
320-				size_t end = i + 1 + unit.value.INT;
321+				size_t end = i + 1 + unit.value;
322 
323 				while (start < end) {
324 					Range r = getNextUnit(units, start, end);
325@@ -1146,27 +1146,27 @@ Unit UnitValue(Memory& m, std::vector<Unit>& units, size_t start, size_t end) {
326 				} else if (found == 2) {
327 					ut = UnitType::NEAREST;
328 
329-					args[2].value.FLOAT = args[1].value.FLOAT;
330-					args[1].value.FLOAT = args[0].value.FLOAT;
331+					args[2].value = args[1].value;
332+					args[1].value = args[0].value;
333 				} else if (found == 1) {
334 					ut = UnitType::NEAREST;
335 
336-					args[1].value.FLOAT = args[0].value.FLOAT;
337-					args[2].value.FLOAT = 1.0f;
338+					args[1].value = args[0].value;
339+					args[2].value = 1.0f;
340 				}
341 
342 
343 				if (ut == UnitType::NEAREST) {
344-					iv.value.FLOAT = std::round(args[1].value.FLOAT/args[2].value.FLOAT)*args[2].value.FLOAT; 
345+					iv.value = std::round(args[1].value/args[2].value)*args[2].value; 
346 				} else if (ut == UnitType::UP) {
347-					iv.value.FLOAT = std::ceil(args[1].value.FLOAT/args[2].value.FLOAT)*args[2].value.FLOAT;
348+					iv.value = std::ceil(args[1].value/args[2].value)*args[2].value;
349 				} else if (ut == UnitType::DOWN) {
350-					iv.value.FLOAT = std::floor(args[1].value.FLOAT/args[2].value.FLOAT)*args[2].value.FLOAT; 
351+					iv.value = std::floor(args[1].value/args[2].value)*args[2].value; 
352 				} else if (ut == UnitType::TO_ZERO) {
353-					iv.value.FLOAT = std::trunc(args[1].value.FLOAT/args[2].value.FLOAT)*args[2].value.FLOAT;
354+					iv.value = std::trunc(args[1].value/args[2].value)*args[2].value;
355 				}
356 
357-				i += unit.value.INT;
358+				i += unit.value;
359 				break;
360 			}
361 			case UnitType::MOD: {
362@@ -1175,20 +1175,20 @@ Unit UnitValue(Memory& m, std::vector<Unit>& units, size_t start, size_t end) {
363 				float args[2];
364 				int found = 0;
365 				size_t start = i + 1;
366-				size_t end = i + 1 + unit.value.INT;
367+				size_t end = i + 1 + unit.value;
368 
369 				while (start < end) {
370 					Range r = getNextUnit(units, start, end);
371-					args[found++] = UnitValue(m, units, r.start, r.end).value.FLOAT;
372+					args[found++] = UnitValue(m, units, r.start, r.end).value;
373 				}
374 
375 				if (found == 2) {
376-					iv.value.FLOAT = std::fmod(args[0], args[1]);
377+					iv.value = std::fmod(args[0], args[1]);
378 				} else {
379-					iv.value.FLOAT = args[0];
380+					iv.value = args[0];
381 				}
382 
383-				i += unit.value.INT;
384+				i += unit.value;
385 				break;
386 			}
387 			case UnitType::PROGRESS: {
388@@ -1197,22 +1197,22 @@ Unit UnitValue(Memory& m, std::vector<Unit>& units, size_t start, size_t end) {
389 				float args[3];
390 				int found = 0;
391 				size_t start = i + 1;
392-				size_t end = i + 1 + unit.value.INT;
393+				size_t end = i + 1 + unit.value;
394 
395 				while (start < end) {
396 					Range r = getNextUnit(units, start, end);
397-					args[found++] = UnitValue(m, units, r.start, r.end).value.FLOAT;
398+					args[found++] = UnitValue(m, units, r.start, r.end).value;
399 				}
400 
401 				if (found == 3) {
402 					// (progress - progress start) / (progress end - progress start)
403-					iv.value.FLOAT = (args[0]-args[1])/(args[2]-args[1]);
404+					iv.value = (args[0]-args[1])/(args[2]-args[1]);
405 				} else {
406-					iv.value.FLOAT = args[0];
407+					iv.value = args[0];
408 				}
409 
410 				
411-				i += unit.value.INT;
412+				i += unit.value;
413 				break;
414 			}
415 			case UnitType::REMD: {
416@@ -1221,62 +1221,62 @@ Unit UnitValue(Memory& m, std::vector<Unit>& units, size_t start, size_t end) {
417 				float args[2];
418 				int found = 0;
419 				size_t start = i + 1;
420-				size_t end = i + 1 + unit.value.INT;
421+				size_t end = i + 1 + unit.value;
422 
423 				while (start < end) {
424 					Range r = getNextUnit(units, start, end);
425-					args[found++] = UnitValue(m, units, r.start, r.end).value.FLOAT;
426+					args[found++] = UnitValue(m, units, r.start, r.end).value;
427 				}
428 
429 				if (found == 2) {
430-					iv.value.FLOAT = std::fmodf(args[0], args[1]);
431+					iv.value = std::fmodf(args[0], args[1]);
432 				} else {
433-					iv.value.FLOAT = args[0];
434+					iv.value = args[0];
435 				}
436 
437-				i += unit.value.INT;
438+				i += unit.value;
439 				break;
440 			}
441 			case UnitType::SIN: {
442 				iv.type = UnitType::NUMBER;
443-				Unit u1 = UnitValue(m, units, i+1, i+1+unit.value.INT);
444-				iv.value.FLOAT = std::sinf(u1.value.FLOAT);
445-				i += unit.value.INT;
446+				Unit u1 = UnitValue(m, units, i+1, i+1+unit.value);
447+				iv.value = std::sinf(u1.value);
448+				i += unit.value;
449 				break;
450 			}
451 			case UnitType::COS: {
452 				iv.type = UnitType::NUMBER;
453-				Unit u1 = UnitValue(m, units, i+1, i+1+unit.value.INT);
454-				iv.value.FLOAT = std::cosf(u1.value.FLOAT);
455-				i += unit.value.INT;
456+				Unit u1 = UnitValue(m, units, i+1, i+1+unit.value);
457+				iv.value = std::cosf(u1.value);
458+				i += unit.value;
459 				break;
460 			}
461 			case UnitType::TAN: {
462 				iv.type = UnitType::NUMBER;
463-				Unit u1 = UnitValue(m, units, i+1, i+1+unit.value.INT);
464-				iv.value.FLOAT = std::tanf(u1.value.FLOAT);
465-				i += unit.value.INT;
466+				Unit u1 = UnitValue(m, units, i+1, i+1+unit.value);
467+				iv.value = std::tanf(u1.value);
468+				i += unit.value;
469 				break;
470 			}
471 			case UnitType::ASIN: {
472 				iv.type = UnitType::NUMBER;
473-				Unit u1 = UnitValue(m, units, i+1, i+1+unit.value.INT);
474-				iv.value.FLOAT = std::asinf(u1.value.FLOAT);
475-				i += unit.value.INT;
476+				Unit u1 = UnitValue(m, units, i+1, i+1+unit.value);
477+				iv.value = std::asinf(u1.value);
478+				i += unit.value;
479 				break;
480 			}
481 			case UnitType::ACOS: {
482 				iv.type = UnitType::NUMBER;
483-				Unit u1 = UnitValue(m, units, i+1, i+1+unit.value.INT);
484-				iv.value.FLOAT = std::acosf(u1.value.FLOAT);
485-				i += unit.value.INT;
486+				Unit u1 = UnitValue(m, units, i+1, i+1+unit.value);
487+				iv.value = std::acosf(u1.value);
488+				i += unit.value;
489 				break;
490 			}
491 			case UnitType::ATAN: {
492 				iv.type = UnitType::NUMBER;
493-				Unit u1 = UnitValue(m, units, i+1, i+1+unit.value.INT);
494-				iv.value.FLOAT = std::atanf(u1.value.FLOAT);
495-				i += unit.value.INT;
496+				Unit u1 = UnitValue(m, units, i+1, i+1+unit.value);
497+				iv.value = std::atanf(u1.value);
498+				i += unit.value;
499 				break;
500 			}
501 			case UnitType::ATAN2: {
502@@ -1285,20 +1285,20 @@ Unit UnitValue(Memory& m, std::vector<Unit>& units, size_t start, size_t end) {
503 				float args[2];
504 				int found = 0;
505 				size_t start = i + 1;
506-				size_t end = i + 1 + unit.value.INT;
507+				size_t end = i + 1 + unit.value;
508 
509 				while (start < end) {
510 					Range r = getNextUnit(units, start, end);
511-					args[found++] = UnitValue(m, units, r.start, r.end).value.FLOAT;
512+					args[found++] = UnitValue(m, units, r.start, r.end).value;
513 				}
514 
515 				if (found == 2) {
516-					iv.value.FLOAT = std::atan2f(args[0], args[1]);
517+					iv.value = std::atan2f(args[0], args[1]);
518 				} else {
519-					iv.value.FLOAT = args[0];
520+					iv.value = args[0];
521 				}
522 
523-				i += unit.value.INT;
524+				i += unit.value;
525 				break;
526 			}
527 			case UnitType::POW: {
528@@ -1307,27 +1307,27 @@ Unit UnitValue(Memory& m, std::vector<Unit>& units, size_t start, size_t end) {
529 				float args[2];
530 				int found = 0;
531 				size_t start = i + 1;
532-				size_t end = i + 1 + unit.value.INT;
533+				size_t end = i + 1 + unit.value;
534 
535 				while (start < end) {
536 					Range r = getNextUnit(units, start, end);
537-					args[found++] = UnitValue(m, units, r.start, r.end).value.FLOAT;
538+					args[found++] = UnitValue(m, units, r.start, r.end).value;
539 				}
540 
541 				if (found == 2) {
542-					iv.value.FLOAT = std::powf(args[0], args[1]);
543+					iv.value = std::powf(args[0], args[1]);
544 				} else {
545-					iv.value.FLOAT = args[0];
546+					iv.value = args[0];
547 				}
548 
549-				i += unit.value.INT;
550+				i += unit.value;
551 				break;
552 			}
553 			case UnitType::SQRT: {
554 				iv.type = UnitType::NUMBER;
555-				Unit u1 = UnitValue(m, units, i+1, i+1+unit.value.INT);
556-				iv.value.FLOAT = std::sqrtf(u1.value.FLOAT);
557-				i += unit.value.INT;
558+				Unit u1 = UnitValue(m, units, i+1, i+1+unit.value);
559+				iv.value = std::sqrtf(u1.value);
560+				i += unit.value;
561 				break;
562 			}
563 			case UnitType::HYPOT: {
564@@ -1336,17 +1336,17 @@ Unit UnitValue(Memory& m, std::vector<Unit>& units, size_t start, size_t end) {
565 
566 				float v = 0;
567 				size_t start = i + 1;
568-				size_t end = i + 1 + unit.value.INT;
569+				size_t end = i + 1 + unit.value;
570 
571 				while (start < end) {
572 					Range r = getNextUnit(units, start, end);
573-					float t = UnitValue(m, units, r.start, r.end).value.FLOAT;
574+					float t = UnitValue(m, units, r.start, r.end).value;
575 					v += t * t;
576 				}
577 
578-				iv.value.FLOAT = std::sqrtf(v);
579+				iv.value = std::sqrtf(v);
580 
581-				i += unit.value.INT;
582+				i += unit.value;
583 				break;
584 			}
585 			case UnitType::LOG: {
586@@ -1355,56 +1355,56 @@ Unit UnitValue(Memory& m, std::vector<Unit>& units, size_t start, size_t end) {
587 				float args[2];
588 				int found = 0;
589 				size_t start = i + 1;
590-				size_t end = i + 1 + unit.value.INT;
591+				size_t end = i + 1 + unit.value;
592 
593 				while (start < end) {
594 					Range r = getNextUnit(units, start, end);
595-					args[found++] = UnitValue(m, units, r.start, r.end).value.FLOAT;
596+					args[found++] = UnitValue(m, units, r.start, r.end).value;
597 				}
598 
599 				if (found == 2) {
600-					iv.value.FLOAT = std::logf(args[0]) / std::logf(args[1]);
601+					iv.value = std::logf(args[0]) / std::logf(args[1]);
602 				} else if (found == 1) {
603-					iv.value.FLOAT = std::logf(args[0]);
604+					iv.value = std::logf(args[0]);
605 				}
606 
607-				i += unit.value.INT;
608+				i += unit.value;
609 				break;
610 			}
611 			case UnitType::EXP: {
612 				iv.type = UnitType::NUMBER;
613-				Unit u1 = UnitValue(m, units, i+1, i+1+unit.value.INT);
614-				iv.value.FLOAT = std::expf(u1.value.FLOAT);
615-				i += unit.value.INT;
616+				Unit u1 = UnitValue(m, units, i+1, i+1+unit.value);
617+				iv.value = std::expf(u1.value);
618+				i += unit.value;
619 				break;
620 			}
621 			case UnitType::ABS: {
622 				iv.type = UnitType::NUMBER;
623-				Unit u1 = UnitValue(m, units, i+1, i+1+unit.value.INT);
624-				iv.value.FLOAT = std::fabsf(u1.value.FLOAT);
625-				i += unit.value.INT;
626+				Unit u1 = UnitValue(m, units, i+1, i+1+unit.value);
627+				iv.value = std::fabsf(u1.value);
628+				i += unit.value;
629 				break;
630 			}
631 			case UnitType::SIGN: {
632 				iv.type = UnitType::NUMBER;
633-				Unit u1 = UnitValue(m, units, i+1, i+1+unit.value.INT);
634+				Unit u1 = UnitValue(m, units, i+1, i+1+unit.value);
635 
636-				if (u1.value.FLOAT > 0) {
637-					iv.value.FLOAT = 1;
638-				} else if (u1.value.FLOAT < 0) {
639-					iv.value.FLOAT = -1;
640+				if (u1.value > 0) {
641+					iv.value = 1;
642+				} else if (u1.value < 0) {
643+					iv.value = -1;
644 				} else {
645-					iv.value.FLOAT = 0;
646+					iv.value = 0;
647 				}
648 
649-				i += unit.value.INT;
650+				i += unit.value;
651 				break;
652 			}
653 			case UnitType::ATTR: {
654 			     	Range args[3];
655 				int found = 0;
656 				size_t start = i + 1;
657-				size_t end = i + 1 + unit.value.INT;
658+				size_t end = i + 1 + unit.value;
659 
660 				while (start < end) {
661 					args[found++] = getNextUnit(units, start, end);
662@@ -1414,7 +1414,7 @@ Unit UnitValue(Memory& m, std::vector<Unit>& units, size_t start, size_t end) {
663 
664 				if (u1.type == UnitType::VAR) {
665 
666-					Range r = m.get(u1.value.INT); // Pull the marker off the ctx
667+					Range r = m.get(u1.value); // Pull the marker off the ctx
668 					Unit value = UnitValue(m, units, r.start, r.end);
669 
670 					if (r.end - r.start > 0) {
671@@ -1437,14 +1437,14 @@ Unit UnitValue(Memory& m, std::vector<Unit>& units, size_t start, size_t end) {
672 					}
673 				}
674 
675-				i += unit.value.INT;
676+				i += unit.value;
677 				break;
678 			}
679 			case UnitType::VAR_FUNC: {
680 				Unit args[2];
681 				int found = 0;
682 				size_t start = i + 1;
683-				size_t end = i + 1 + unit.value.INT;
684+				size_t end = i + 1 + unit.value;
685 
686 				while (start < end) {
687 					Range r = getNextUnit(units, start, end);
688@@ -1452,7 +1452,7 @@ Unit UnitValue(Memory& m, std::vector<Unit>& units, size_t start, size_t end) {
689 				}
690 
691 				if (args[0].type == UnitType::VAR) {
692-					Range r = m.get(args[0].value.INT); // Pull the marker off the ctx
693+					Range r = m.get(args[0].value); // Pull the marker off the ctx
694 
695 					if (r.end > 0) {
696 						iv = UnitValue(m, units, r.start, r.end);
697@@ -1462,11 +1462,11 @@ Unit UnitValue(Memory& m, std::vector<Unit>& units, size_t start, size_t end) {
698 					}
699 				}
700 
701-				i += unit.value.INT;
702+				i += unit.value;
703 				break;
704 			}
705 			case UnitType::VAR: {
706-				Range r = m.get(unit.value.INT);
707+				Range r = m.get(unit.value);
708 
709 				if (r.end > 0) {
710 					iv = m.heap[r.start];
711@@ -1476,47 +1476,56 @@ Unit UnitValue(Memory& m, std::vector<Unit>& units, size_t start, size_t end) {
712 			}
713 			case UnitType::LET: {
714 				if (units[start + 1].type == UnitType::VAR) {
715-					Unit u = UnitValue(m, units, i + 2, i + 1 + unit.value.INT);
716-					m.push_back(units[i+1].value.INT, u);
717+					Unit u = UnitValue(m, units, i + 2, i + 1 + unit.value);
718+					m.push_back(units[i+1].value, u);
719 				}
720 
721-				i += unit.value.INT;
722+				i += unit.value;
723 				break;
724 			}
725 			case UnitType::SET: {
726 				if (units[i + 1].type == UnitType::VAR) {
727-					Range r = m.get(units[i + 1].value.INT);
728-					Unit u = UnitValue(m, units, i + 2, i + 1 + unit.value.INT);
729+					Range r = m.get(units[i + 1].value);
730+					Unit u = UnitValue(m, units, i + 2, i + 1 + unit.value);
731 
732 					// r.end is the length
733 					if (r.end > 0) { // need to write over
734 						m.heap[r.start] = u;
735 					} else {
736-						m.push_back(units[i + 1].value.INT, u);
737+						m.push_back(units[i + 1].value, u);
738+					}
739+				} else if (units[i + 1].type == UnitType::AT && units[i + 2].type == UnitType::VAR) {
740+					// Set at in a list
741+					Range r = m.get(units[i+2].value);
742+
743+					if (r.end > 0) {
744+						Unit p = UnitValue(m, units, i + 2, i + 1 + units[i+2].value);
745+						Unit u = UnitValue(m, units, i + 2, i + 1 + unit.value);
746+						m.heap[r.start + p.value] = u;
747 					}
748 				}
749 
750-				i += unit.value.INT;
751+				i += unit.value;
752 				break;
753 			}
754 			case UnitType::PRINT: {
755-				Unit u = UnitValue(m, units, i+1, i+1+unit.value.INT);
756-				std::cout << "> " << u.value.FLOAT << std::endl;
757+				Unit u = UnitValue(m, units, i+1, i+1+unit.value);
758+				std::cout << "> " << u.value << std::endl;
759 				iv = u;
760-				i += unit.value.INT;
761+				i += unit.value;
762 				break;
763 			}
764 			case UnitType::IF: {
765 				Range args[4]; // condition trueval else falseval
766 				int found = 0;
767 				size_t start = i + 1;
768-				size_t end = i + 1 + unit.value.INT;
769+				size_t end = i + 1 + unit.value;
770 
771 				while (start < end) {
772 					args[found++] = getNextUnit(units, start, end);
773 				}
774 
775-				bool condition = UnitValue(m, units, args[0].start, args[0].end).value.BOOL;
776+				bool condition = UnitValue(m, units, args[0].start, args[0].end).value;
777 
778 				if (condition) {
779 					iv = UnitValue(m, units, args[1].start, args[1].end);
780@@ -1530,73 +1539,98 @@ Unit UnitValue(Memory& m, std::vector<Unit>& units, size_t start, size_t end) {
781 				}
782 
783 
784-			   	i += unit.value.INT;
785+			   	i += unit.value;
786 				break;
787 			}
788 			case UnitType::LIST: {
789-				
790+				if (units[start + 1].type == UnitType::VAR) {
791+
792+				//	how to pre allocate a empty list????
793+				//	empty(5)
794+				//	link(links two lists) join(joins them in memory)???
795+				//	make a JUMP to padd the list
796+
797+					m.push(units[i+1].value, units, i+2, i+1+unit.value);
798+				//	m.push_back({UnitType::JUMP, 0})
799+				}
800+
801+				i += unit.value;
802+				break;
803+			}
804+			case UnitType::AT: {
805+				if (units[start + 1].type == UnitType::VAR) {
806+					Range r = m.get(units[i+1].value);
807+
808+					if (r.end > 0) {
809+						Unit u = UnitValue(m, units, i + 1, i + 1 + unit.value);
810+						iv = m.heap[r.start + u.value];
811+					}
812+				}
813+
814+				i += unit.value;
815+				break;
816 			}
817 		}
818 
819 		switch (op) {
820 			case UnitType::ADD:
821 				result.type = UnitType::NUMBER;
822-				result.value.FLOAT += iv.value.FLOAT;
823+				result.value += iv.value;
824 				op = UnitType::NONOP;
825 				break;
826 			case UnitType::SUB:
827 				result.type = UnitType::NUMBER;
828-				result.value.FLOAT -= iv.value.FLOAT;
829+				result.value -= iv.value;
830 				op = UnitType::NONOP;
831 				break;
832 			case UnitType::DIV:
833 				result.type = UnitType::NUMBER;
834-				result.value.FLOAT /= iv.value.FLOAT;
835+				result.value /= iv.value;
836 				op = UnitType::NONOP;
837 				break;
838 			case UnitType::MULT:
839 				result.type = UnitType::NUMBER;
840-				result.value.FLOAT *= iv.value.FLOAT;
841+				result.value *= iv.value;
842 				op = UnitType::NONOP;
843 				break;
844 			case UnitType::LT:
845 				result.type = UnitType::BOOL;
846-				result.value.BOOL = result.value.FLOAT < iv.value.FLOAT;
847+				result.value = result.value < iv.value;
848 				op = UnitType::NONOP;
849 				break;
850 			case UnitType::GT:
851 				result.type = UnitType::BOOL;
852-				result.value.BOOL = result.value.FLOAT > iv.value.FLOAT;
853+				result.value = result.value > iv.value;
854 				op = UnitType::NONOP;
855 				break;
856 			case UnitType::LE:
857 				result.type = UnitType::BOOL;
858-				result.value.BOOL = result.value.FLOAT <= iv.value.FLOAT;
859+				result.value = result.value <= iv.value;
860 				op = UnitType::NONOP;
861 				break;
862 			case UnitType::GE:
863 				result.type = UnitType::BOOL;
864-				result.value.BOOL = result.value.FLOAT >= iv.value.FLOAT;
865+				result.value = result.value >= iv.value;
866 				op = UnitType::NONOP;
867 				break;
868 			case UnitType::EQ:
869 				result.type = UnitType::BOOL;
870-				result.value.BOOL = result.value.FLOAT == iv.value.FLOAT;
871+				result.value = result.value == iv.value;
872 				op = UnitType::NONOP;
873 				break;
874 			case UnitType::AND:
875 				result.type = UnitType::BOOL;
876-				result.value.BOOL = result.value.FLOAT && iv.value.FLOAT;
877+				result.value = result.value && iv.value;
878 				op = UnitType::NONOP;
879 				break;
880 			case UnitType::OR:
881 				result.type = UnitType::BOOL;
882-				result.value.BOOL = result.value.FLOAT || iv.value.FLOAT;
883+				result.value = result.value || iv.value;
884 				op = UnitType::NONOP;
885 				break;
886 			case UnitType::NOT:
887 				result.type = UnitType::BOOL;
888-				result.value.BOOL = !iv.value.FLOAT;
889+				result.value = !iv.value;
890 				op = UnitType::NONOP;
891 				break;
892 			default:
893diff --git a/src/parser.cc b/src/parser.cc
894index b92c0b3..6508b7f 100755
895--- a/src/parser.cc
896+++ b/src/parser.cc
897@@ -7,6 +7,8 @@
898 #include <algorithm>
899 #include <cmath>
900 #include <string_view>
901+#include <bit>
902+#include <cstdint>
903 
904 struct SymbolTable {
905 	std::unordered_map<std::string, int> table{};
906@@ -1050,6 +1052,7 @@ static const std::unordered_map<std::string_view, UnitType> kFunc{
907 	{"var", UnitType::VAR},
908 	{"print", UnitType::PRINT},
909 	{"list", UnitType::LIST},
910+	{"at", UnitType::AT},
911 	{"", UnitType::GROUP}
912 };
913 
914@@ -1085,7 +1088,7 @@ std::vector<Unit> getUnit(std::string value, SymbolTable* externalTable = nullpt
915 				for (size_t j = 0; j < str_buffer.length(); j++) {
916 					Unit unit{};
917 					unit.type = UnitType::STRING;
918-					unit.value.CHAR = str_buffer[j];
919+					unit.value = str_buffer[j];
920 					units.push_back(unit);
921 				}
922 
923@@ -1093,7 +1096,7 @@ std::vector<Unit> getUnit(std::string value, SymbolTable* externalTable = nullpt
924 
925 				Unit unit{};
926 				unit.type = UnitType::STRING_TERM;
927-				unit.value.INT = str_buffer.length();
928+				unit.value = str_buffer.length();
929 				units.push_back(unit);
930 
931 				inQuotes = false;
932@@ -1143,7 +1146,7 @@ std::vector<Unit> getUnit(std::string value, SymbolTable* externalTable = nullpt
933 			}
934 
935 			// The value of the function is the child count
936-			unit.value.INT = children.size();
937+			unit.value = children.size();
938 
939 			units.push_back(unit);
940 			units.insert(units.end(), children.begin(), children.end());
941@@ -1168,16 +1171,16 @@ std::vector<Unit> getUnit(std::string value, SymbolTable* externalTable = nullpt
942 					Color Matching
943 				*/
944 				unit.type = UnitType::HEX;
945-				unit.value.UINT = it->second;
946+				unit.value = it->second;
947 			} else {
948 				bool found = false;
949 				for (const auto& [suffix, type, trim] : sufMatch) {
950 					if (buffer.ends_with(suffix)) {
951 						found = true;
952 						try {
953-							unit.value.FLOAT = std::stof(std::string(buffer.substr(0, buffer.size() - trim)));
954+							unit.value = std::stof(std::string(buffer.substr(0, buffer.size() - trim)));
955 						} catch (...) {
956-							unit.value.FLOAT = 0.0f;
957+							unit.value = 0.0f;
958 						}
959 
960 						unit.type = type;
961@@ -1191,23 +1194,23 @@ std::vector<Unit> getUnit(std::string value, SymbolTable* externalTable = nullpt
962 							# Prefix for HEX codes
963 						*/
964 						unit.type = UnitType::HEX;
965-						unit.value.UINT = std::stoul(buffer.substr(1), nullptr, 16);
966+						unit.value = std::bit_cast<float>(static_cast<uint32_t>(std::stoul(buffer.substr(1), nullptr, 16)));
967 					} else if (auto it = kAbsSize.find(buffer); it != kAbsSize.end()) { 
968 						/*
969 							Absolute size matching
970 						*/
971 						unit.type = UnitType::EM;
972-						unit.value.FLOAT = it->second;
973+						unit.value = it->second;
974 					} else if (buffer == "true") {
975 						unit.type = UnitType::BOOL;
976-						unit.value.BOOL = true;
977+						unit.value = true;
978 					} else if (buffer == "false") {
979 						unit.type = UnitType::BOOL;
980-						unit.value.BOOL = false;
981+						unit.value = false;
982 					} else {
983 						// Maybe its a number?
984 						try {
985-							unit.value.FLOAT = std::stof(buffer);
986+							unit.value = std::stof(buffer);
987 							unit.type = UnitType::NUMBER;
988 						} catch (...) {
989 							// If we are here it is not a known parsable word, this could be a typo 
990@@ -1215,7 +1218,7 @@ std::vector<Unit> getUnit(std::string value, SymbolTable* externalTable = nullpt
991 							// parsed but not size.
992 							if (!buffer.empty() && buffer.find_first_not_of(' ') != std::string::npos) {
993 								unit.type = UnitType::VAR;
994-								unit.value.INT = table.get(buffer);
995+								unit.value = table.get(buffer);
996 							} else {
997 								continue;
998 							}
999diff --git a/tests/unitvalue.cc b/tests/unitvalue.cc
1000index 6bd824d..7b396c2 100644
1001--- a/tests/unitvalue.cc
1002+++ b/tests/unitvalue.cc
1003@@ -96,11 +96,11 @@ TEST_CASE("BENCH") {
1004 
1005 		Memory m;
1006 		// Preset width, height, and em
1007-		m.push_back(sym.get("width"),{UnitType::NUMBER, {.FLOAT = 1000.0f}});
1008-		m.push_back(sym.get("height"),{UnitType::NUMBER, {.FLOAT = 700.0f}});
1009-		m.push_back(sym.get("em"),{UnitType::NUMBER, {.FLOAT= 16.0f}});
1010+		m.push_back(sym.get("width"),{UnitType::NUMBER, 1000.0f});
1011+		m.push_back(sym.get("height"),{UnitType::NUMBER, 700.0f});
1012+		m.push_back(sym.get("em"),{UnitType::NUMBER, 16.0f});
1013 
1014-		std::vector<Unit> units = getUnit("let(x 10px) set(x (x + 100)) (min(5 x) * 2)", &sym);
1015+		std::vector<Unit> units = getUnit("list(x 5 2 3 4)  set(at(x 0) 13)", &sym);
1016 
1017 		Snapshot s = m.save();
1018