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) {