commit 35d7299
0uppy
·
2026-09-10 17:30:15 +0000 UTC
parent caa7865
cotton - added if and else statements to cot, also organised the interpreter and both cotton files a bit
3 files changed,
+149,
-35
+1,
-0
1@@ -5,6 +5,7 @@ void cotton_init
2 (Cotton *c)
3 {
4 c->stack_p = 0;
5+ c->jmp_stack_p = 0;
6 c->instruct_p = 0;
7 c->mem_len = 0;
8
+12,
-6
1@@ -1,13 +1,16 @@
2 #ifndef COTTON_H
3 #define COTTON_H
4
5-#define OP_PUSH 0
6-#define OP_CALL 1
7-#define OP_KILL 2
8+#define OP_PUSH 0
9+#define OP_CALL 1
10+#define OP_KILL 2
11+#define OP_JMP 3
12+#define OP_FJMP 4
13
14-#define STACK_SIZE 64
15-#define MEM_SIZE 1024
16-#define VARS_SIZE 64
17+#define STACK_SIZE 64
18+#define JMP_STACK_SIZE 32
19+#define MEM_SIZE 1024
20+#define VARS_SIZE 64
21
22 typedef struct Cotton Cotton;
23
24@@ -20,6 +23,9 @@ struct Cotton {
25 int stack[STACK_SIZE];
26 int stack_p;
27
28+ int jmp_stack[JMP_STACK_SIZE];
29+ int jmp_stack_p;
30+
31 int mem[MEM_SIZE];
32 int instruct_p;
33 int mem_len;
+136,
-29
1@@ -1,3 +1,6 @@
2+/* I eventually need to split this file before it gets too big, i'll keep this comment here as a mental reminder,.,
3+ooooo get off your ass dani ooooo go work ooooo dani you're a bum oooooo oooooo you suckkk oooooooo,., sorry me.., */
4+
5 #include "cotton.h"
6 #include "interpreter.h"
7 #include <stdio.h>
8@@ -38,7 +41,7 @@ static void word_div
9 int b = pop(c);
10 int a = pop(c);
11
12-// Now i doubt anyone will really be dividing stuff by zero but you never know.., talk about le safety amirite.., heh
13+ // Now, i doubt anyone will really be dividing stuff by zero but you never know.., talk about le safety amirite.., heh
14 if (b == 0) {
15 fprintf(stderr, "cotton: you cant divide by zero, you dummy :P\n");
16 return;
17@@ -62,8 +65,10 @@ static void word_store
18
19 if (slot >= 0 && slot < VARS_SIZE) {
20 c->vars[slot] = num;
21- } else {
22- fprintf(stderr, "cotton: tried to store somewhere that don't exist.,. its in the void now.., :<\n");
23+ }
24+
25+ else {
26+ fprintf(stderr, "cotton: i tried to store somewhere that don't exist,, its in the void now.., :(\n");
27 }
28 }
29
30@@ -74,8 +79,10 @@ static void word_fetch
31
32 if (slot >= 0 && slot < VARS_SIZE) {
33 push(c, c->vars[slot]);
34- } else {
35- fprintf(stderr, "cotton: tried to fetch from somewhere that don't exist,., :<\n");
36+ }
37+
38+ else {
39+ fprintf(stderr, "cotton: i tried to fetch from somewhere that seemingly don't exist,, erm.,.\n");
40 }
41 }
42
43@@ -131,7 +138,6 @@ static void word_grtr
44 push(c, a > b ? 1 : 0);
45 }
46
47-// should be enough for tonight.,., i shall be borrowing more from forth, forth is awesome, i love you forth, i forth <3 :3
48 static Word builtins[] = {
49 {"+", word_add},
50 {"-", word_sub},
51@@ -149,6 +155,61 @@ static Word builtins[] = {
52 {NULL, NULL}
53 };
54
55+/* this comment serves as a separator to split the words above from the words below, the words below run straight away while compiling
56+instead of waiting to be ran later, forth calls these "immediate words" so thats what im calling them too :P (if it aint broke dont fix it as they say) */
57+
58+static void word_if
59+(Cotton *c)
60+{
61+ if (c->jmp_stack_p >= JMP_STACK_SIZE) {
62+ fprintf(stderr, "cotton: there are too many nested ifs, calm down!! D:\n");
63+ return;
64+ }
65+
66+ c->mem[c->mem_len++] = OP_FJMP;
67+ c->jmp_stack[c->jmp_stack_p++] = c->mem_len;
68+ c->mem[c->mem_len++] = 0;
69+}
70+
71+static void word_else
72+(Cotton *c)
73+{
74+ if (c->jmp_stack_p <= 0) {
75+ fprintf(stderr, "cotton: i found an else without an if,., where'd that come from??\n");
76+ return;
77+ }
78+
79+ int if_target = c->jmp_stack[--c->jmp_stack_p];
80+
81+ c->mem[c->mem_len++] = OP_JMP;
82+ c->jmp_stack[c->jmp_stack_p++] = c->mem_len;
83+ c->mem[c->mem_len++] = 0;
84+
85+ c->mem[if_target] = c->mem_len;
86+}
87+
88+static void word_end
89+(Cotton *c)
90+{
91+ if (c->jmp_stack_p <= 0) {
92+ fprintf(stderr, "cotton: i found an end without an if,., where'd that come from??\n");
93+ return;
94+ }
95+
96+ int target = c->jmp_stack[--c->jmp_stack_p];
97+ c->mem[target] = c->mem_len;
98+}
99+
100+static Word immediates[] = {
101+ {"if", word_if},
102+ {"else", word_else},
103+ {"end", word_end},
104+ {NULL, NULL}
105+};
106+
107+/* Another comment just so i can separate the immediates from the compiler and runtime functions blehhhhhh
108+words words words words more words SO many words OH MY GOD THERE ARE SO MANY WORDS WORDS WORDS WORDS AAAAAA*/
109+
110 void cotton_compile
111 (Cotton *c, char *line)
112 {
113@@ -158,39 +219,70 @@ void cotton_compile
114 char *tok = strtok(line, " ");
115
116 while (tok) {
117+
118 if (c->mem_len >= MEM_SIZE - 2) {
119- fprintf(stderr, "cotton: memory is full,., can't compile anymore :<\n");
120+ fprintf(stderr, "cotton: i ran out of memory,., can't compile anymore :<\n");
121 return;
122 }
123
124- int is_num = 1;
125- for (int i = 0; tok[i]; i++) {
126- if (!isdigit(tok[i]) && !(i == 0 && tok[i] == '-')) {
127- is_num = 0;
128- break;
129- }
130+ /* This is subjective to change but i thought that using ? for conditionals so stuff reads out as
131+ "is this happening? if so, then, blah blah blah" was a good idea, atleast sounded good in my head :P*/
132+
133+ if (strcmp(tok, "?") == 0) {
134+ // oh yeah, also, this doesn't really do anything, its just here to make if statements look nicer x3
135 }
136
137- if (is_num) {
138- c->mem[c->mem_len++] = OP_PUSH;
139- c->mem[c->mem_len++] = atoi(tok);
140- }
141-
142- else {
143- int found = 0;
144- for (int i = 0; builtins[i].name != NULL; i++) {
145- if (strcmp(tok, builtins[i].name) == 0) {
146- c->mem[c->mem_len++] = OP_CALL;
147- c->mem[c->mem_len++] = i;
148- found = 1;
149+ else {
150+
151+ int found_immediate = 0;
152+
153+ for (int i = 0; immediates[i].name != NULL; i++) {
154+
155+ if (strcmp(tok, immediates[i].name) == 0) {
156+ immediates[i].code(c);
157+ found_immediate = 1;
158 break;
159 }
160 }
161
162- if (!found) {
163- fprintf(stderr, "cotton: cotton doesn't know what \"%s\" means,., :<\n", tok);
164+ if (!found_immediate) {
165+
166+ int is_num = 1;
167+
168+ for (int i = 0; tok[i]; i++) {
169+
170+ if (!isdigit(tok[i]) && !(i == 0 && tok[i] == '-')) {
171+ is_num = 0;
172+ break;
173+ }
174+ }
175+
176+ if (is_num) {
177+ c->mem[c->mem_len++] = OP_PUSH;
178+ c->mem[c->mem_len++] = atoi(tok);
179+ }
180+
181+ else {
182+
183+ int found = 0;
184+
185+ for (int i = 0; builtins[i].name != NULL; i++) {
186+
187+ if (strcmp(tok, builtins[i].name) == 0) {
188+ c->mem[c->mem_len++] = OP_CALL;
189+ c->mem[c->mem_len++] = i;
190+ found = 1;
191+ break;
192+ }
193+ }
194+
195+ if (!found) {
196+ fprintf(stderr, "cotton: sorry, i don't know what \"%s\" means :(\n", tok);
197+ }
198+ }
199 }
200 }
201+
202 tok = strtok(NULL, " ");
203 }
204 }
205@@ -201,17 +293,32 @@ void cotton_run
206 c->instruct_p = 0;
207
208 while (c->instruct_p < c->mem_len) {
209+
210 int op = c->mem[c->instruct_p++];
211-
212+
213 if (op == OP_PUSH) {
214 push(c, c->mem[c->instruct_p++]);
215 }
216
217- else if (op == OP_CALL) {
218+ else if (op == OP_CALL) {
219+
220 int idx = c->mem[c->instruct_p++];
221 builtins[idx].code(c);
222 }
223
224+ else if (op == OP_JMP) {
225+ c->instruct_p = c->mem[c->instruct_p];
226+ }
227+
228+ else if (op == OP_FJMP) {
229+
230+ int target = c->mem[c->instruct_p++];
231+
232+ if (pop(c) == 0) {
233+ c->instruct_p = target;
234+ }
235+ }
236+
237 else if (op == OP_KILL) {
238 break;
239 }