home readme diff tree note docs

0commit f31de50d1a1ec334612e1130be7955910f2f10e6
1Author: lakefox <mason@lakefox.net>
2Date:   Sat Apr 4 16:09:27 2026 -0600
3
4    Basic while loops
5
6diff --git a/include/grim.h b/include/grim.h
7index 62ceba9..7db3a5d 100755
8--- a/include/grim.h
9+++ b/include/grim.h
10@@ -87,7 +87,7 @@ typedef enum {
11 		HYPOT, LOG, EXP, ABS, SIGN, SIN, COS, TAN, ASIN, ACOS, ATAN, ATAN2, VAR_FUNC,
12 		BLUR, BRIGHTNESS, CONTRAST, DROP_SHADOW, GRAYSCALE, HUE_ROTATE, INVERT, 
13 		OPACITY, SEPIA, SATURATE, ATTR, TYPE, ENV, IF, FUNC, LET, RETURN, SET,
14-		AT, EMPTY, APPEND, WHILE, PRINT, LENGTH, CAPACITY, DEF,
15+		AT, EMPTY, APPEND, WHILE, PRINT, LENGTH, CAPACITY, DEF, RANGE, MAP,
16 		
17 		// Easing Functions
18 		EASING_FUNCTION, LINEAR_EASING_FUNCTION, LINEAR, EASE, EASE_IN, EASE_OUT, EASE_IN_OUT, CUBIC_BEZIER_FUNCTION, 
19diff --git a/maps/functions.gperf b/maps/functions.gperf
20index 4562394..cb5cf71 100644
21--- a/maps/functions.gperf
22+++ b/maps/functions.gperf
23@@ -94,4 +94,7 @@ length, LENGTH
24 capacity, CAPACITY
25 append, APPEND
26 def, DEF
27+while, WHILE
28+range, RANGE
29+map, MAP
30 %%
31diff --git a/playground/css_unit.c b/playground/css_unit.c
32index 732a8f8..832de62 100644
33--- a/playground/css_unit.c
34+++ b/playground/css_unit.c
35@@ -139,7 +139,7 @@ int main() {
36 	int stack_len = 0;
37 	int max_register_size = 0;
38 
39-	char* ustr = "let(height 10) def(x (age name) (age + height * name)) x(4 x(5 x(6 x(7 8))))";
40+	char* ustr = "let(i 0) while((i < 90) set(i (i + 1))) print(i)";
41 
42 	get_unit(&units, &cap, &units_len, &vars, &vars_len, &vars_cap, &funcs, &funcs_len, &funcs_cap, &stack_len, &max_register_size, ustr);
43 
44diff --git a/playground/unit_value.c b/playground/unit_value.c
45index 5bd83ad..067b7eb 100644
46--- a/playground/unit_value.c
47+++ b/playground/unit_value.c
48@@ -145,7 +145,7 @@ int main() {
49 	int stack_len = 0;
50 	int max_register_size = 0;
51 
52-	char* ustr = "let(height 10) def(x (name age) (age + height * name)) x(4 x(5 x(6 x(7 8))))";
53+	char* ustr = "let(i 0) while(true (print(i < 10, i) set(i (i + 1))))";
54 
55 	get_unit(&units, &cap, &units_len, &vars, &vars_len, &vars_cap, &funcs, &funcs_len, &funcs_cap, &stack_len, &max_register_size, ustr);
56 
57@@ -177,7 +177,7 @@ int main() {
58 
59 
60 	if (true) {
61-		benchmark_unit_value(ustr);
62+		//benchmark_unit_value(ustr);
63 
64 		test_unit_value("1 + 1", 2);
65 		test_unit_value("pow(10 2)", 100);
66@@ -193,8 +193,8 @@ int main() {
67 		test_unit_value("(let(x 10px 20px 30px) capacity(x) == 3)", 1);
68 		test_unit_value("min(1 10) + 10 == 11", 1);
69 		test_unit_value("let(x 10px 20px 30px) set(at(x 1) 90px) at(x 1) == 90px", 1);
70-		test_unit_value("let(x 10px 20px 30px) set(at(x 1) 90px) if(at(x 1) != 90px, 1 + 1, 5 + 5)", 5);
71-		test_unit_value("let(x 10px 20px 30px) set(at(x 1) 90px) if(at(x 1) == 90px, 1 + 1)", 1);
72+		test_unit_value("let(x 10px 20px 30px) set(at(x 1) 90px) if(at(x 1) != 90px, 1 + 1, 5 + 5)", 10);
73+		test_unit_value("let(x 10px 20px 30px) set(at(x 1) 90px) if(at(x 1) == 90px, 1 + 1)", 2);
74 		test_unit_value("let(x empty(3)) ((length(x) == 3) && (capacity(x) == 3))", 1);
75 		test_unit_value("let(height 10) def(x (age name) (age + height * name)) x(4 x(5 x(6 x(7 8))))", 456960);
76 		test_unit_value("let(height 10) def(x () (21 + 3)) x()", 24);
77diff --git a/src/grim.c b/src/grim.c
78index 16dde23..67b29a4 100755
79--- a/src/grim.c
80+++ b/src/grim.c
81@@ -794,7 +794,7 @@ float unit_value(struct Slot stack[], int register_size, struct Unit* units, int
82 						} else if (stack[(int)unit.value].length > 1) {
83 							registers[register_len++] = stack[(int)unit.value].data[0];
84 						} else {
85-							registers[register_len++].type = NUMBER;
86+							registers[register_len].type = NUMBER;
87 							registers[register_len++].value = 0.0f;
88 						}
89 					}
90@@ -833,7 +833,8 @@ float unit_value(struct Slot stack[], int register_size, struct Unit* units, int
91 				break;
92 			}
93 			case JUMP: {
94-				i += unit.value;
95+				i = (int)unit.value;
96+				break;
97 			}
98 			case IF: {
99 				// All the if statement need to do is to check if the last register is false. If it is then it will jump the amount of the value
100@@ -841,6 +842,7 @@ float unit_value(struct Slot stack[], int register_size, struct Unit* units, int
101 				if (!registers[idx].value) {
102 					i += unit.value;
103 				}
104+				register_len = idx;
105 				break;
106 			}
107 			case EMPTY: {
108@@ -1019,7 +1021,7 @@ float unit_value(struct Slot stack[], int register_size, struct Unit* units, int
109 					registers[register_len++] = unit;
110 				} else {
111 					int index = (unit.type - CUSTOM_FUNCS) - 1;
112-					units[(int)units[index].value].value = (float)((i) - (int)units[index].value); // Set the jump to return to the next instruction
113+					units[(int)units[index].value].value = (float)i; // Set the jump to return to the next instruction
114 
115 					for (int j = 0; j < (int)unit.value; j++) {
116 						units[index+1+j] = registers[((register_len)-(int)unit.value)+j];
117diff --git a/src/parser.c b/src/parser.c
118index d375cf1..3560c76 100755
119--- a/src/parser.c
120+++ b/src/parser.c
121@@ -349,22 +349,21 @@ void get_unit(struct Unit** units, int* cap, int* units_len, char** vars, int* v
122 
123 					memmove((*units) + indexes[0], (*units) + indexes[0] - 1, (*units_len - indexes[0]) * sizeof(struct Unit));
124 					(*units)[indexes[0]].type = IF;
125-					(*units)[indexes[0]].value = (*units_len-before_count) - indexes[0] + 1;
126+					(*units)[indexes[0]].value = (*units_len-indexes[0]);
127 				} else if (child_count == 3) {
128 					// if else
129 					// Move back 1 and add a jump at the end of the conditional logic
130-					if ((unsigned long)(*cap) < (indexes[2] + 20) * sizeof(struct Unit)) {
131+					if ((unsigned long)(*cap) < (indexes[2] + 23) * sizeof(struct Unit)) {
132 						*units = realloc(*units, sizeof(struct Unit) * (*cap * 2));
133 					}
134 
135 					memmove((*units) + indexes[1], (*units) + indexes[1] - 1, (*units_len - indexes[1]) * sizeof(struct Unit));
136 					(*units)[indexes[1]].type = IF;
137-					(*units)[indexes[1]].value = (indexes[0] - indexes[1]) + 2; // Add one for the jump and one for the if
138+					(*units)[indexes[1]].value = (indexes[0] - indexes[1]) + 1; // Add one for the jump and one for the if
139 
140-					memmove((*units) + indexes[0] + 1, (*units) + indexes[0], ((indexes[0] - indexes[1]) + 1) * sizeof(struct Unit));
141+					memmove((*units) + indexes[0] + 1, (*units) + indexes[0], ((indexes[0] - indexes[1]) + 2) * sizeof(struct Unit));
142 					(*units)[indexes[0] + 1].type = JUMP;
143-					(*units)[indexes[0] + 1].value = (*units_len-indexes[0]);
144-
145+					(*units)[indexes[0] + 1].value = *units_len + 1;
146 					(*units_len)++;
147 				}
148 			} else if (placeholder.type == DEF) {
149@@ -388,6 +387,19 @@ void get_unit(struct Unit** units, int* cap, int* units_len, char** vars, int* v
150 
151 				(*units)[*units_len-2].type = JUMP; // This is for the calling function to use to jump itself back to its prevous position
152 				*units_len -= 1;
153+			} else if (placeholder.type == WHILE) {
154+				// Move back 1
155+				if (sizeof(units) / sizeof(struct Unit) < ((*units_len)-indexes[1]) * sizeof(struct Unit)) {
156+					*units = realloc(*units, sizeof(struct Unit) * (*cap * 2));
157+				}
158+
159+				memmove((*units) + indexes[0], (*units) + indexes[0] - 1, (*units_len - indexes[0]) * sizeof(struct Unit));
160+				(*units)[indexes[0]].type = IF;
161+				(*units)[indexes[0]].value = (*units_len-indexes[0]);
162+				(*units)[*units_len].type = JUMP;
163+				(*units)[*units_len].value = before_count-1;
164+				*units_len += 1;
165+
166 			}
167 
168 			if (hasOP) {