commit caa7865
0uppy
·
2026-09-09 21:19:54 +0000 UTC
parent d3753f8
cotton - remade the interpreter, cotton and main files (also updated the meson file and made the first neucot file woo :3)
9 files changed,
+257,
-278
+4,
-5
1@@ -8,8 +8,6 @@ cotton originally started as a slightly modified CHIP8 emulator, then was repurp
2
3 cotton is a passion hobby project being made solely by me, so, dont expect anything grandiose or of high quality - even then, suggestions and ideas are always welcome!! :D
4
5-(*Inspired by Lua's internal engine's layout, not really the syntax itself)
6-
7 ## building cotton,
8
9 ```
10@@ -37,6 +35,7 @@ this is cotton's mascot!! his name is ton!! he was drawn by me using old cotton'
11
12 honestly i dont have alot to write here for the time being, mostly because im afraid to set high expectations that i can't achieve, however:
13
14-* Repurpose the current code into my new idea for the project and run something []
15-* Update the current docs []
16-* One day figure out how to optionally compile cot files into uxntal files (might be too ambitious but one can dream, right :<) []
17+* Repurpose the current code into my new idea for the project and run something [X] (got a little base for tonight and it does work so wooo)
18+* Organise the codebase a bit bc i can see the interpreter getting quite full like on old cotton [ ]
19+* Update the current docs [ ]
20+* One day figure out how to optionally compile cot files into uxntal files (might be too ambitious but one can dream, right :<) [ ]
+0,
-2
1@@ -1,2 +0,0 @@
2-print "test test this is a test" print
3-print "does cot render text okay again uhhh" print
+5,
-0
1@@ -0,0 +1,5 @@
2+6 7 + .
3+
4+6 9 swap . .
5+
6+//im so funny aren't i
+2,
-3
1@@ -1,5 +1,5 @@
2 project('cotton', 'c',
3- version : '0.3',
4+ version : '0.1',
5 default_options : ['c_std=c99', 'warning_level=2'])
6
7 sdl2 = dependency('sdl2')
8@@ -7,8 +7,7 @@ sdl2 = dependency('sdl2')
9 src_files = [
10 'src/main.c',
11 'src/cotton.c',
12- 'src/cottonwindow.c',
13 'src/interpreter.c',
14 ]
15
16-executable('cotton', src_files, dependencies : sdl2)
17+executable('cotton', src_files)
+27,
-8
1@@ -1,17 +1,36 @@
2 #include "cotton.h"
3 #include <stdio.h>
4-#include <stdlib.h>
5-#include <string.h>
6-#include <time.h>
7
8 void cotton_init
9-(Cotton *c)
10+(Cotton *c)
11 {
12- memset(c, 0, sizeof(Cotton));
13+ c->stack_p = 0;
14+ c->instruct_p = 0;
15+ c->mem_len = 0;
16
17- srand((unsigned int)time(NULL));
18+ for (int i = 0; i < VARS_SIZE; i++) {
19+ c->vars[i] = 0;
20+ }
21+}
22+
23+void push
24+(Cotton *c, int v)
25+{
26+ if (c->stack_p >= STACK_SIZE) {
27+ fprintf(stderr, "cotton: stack overflow,., like the website,.., :<\n");
28+ return;
29+ }
30
31- c->stack_p = 0;
32+ c->stack[c->stack_p++] = v;
33+}
34+
35+int pop
36+(Cotton *c)
37+{
38+ if (c->stack_p <= 0) {
39+ fprintf(stderr, "cotton: stack underflow :<\n");
40+ return 0;
41+ }
42
43- c->c_cottolette = COTTOLETTE[1];
44+ return c->stack[--c->stack_p];
45 }
+25,
-48
1@@ -1,62 +1,39 @@
2 #ifndef COTTON_H
3 #define COTTON_H
4
5-#include <stdint.h>
6-
7-#define MEMORY_SIZE (64 * 1024)
8-#define VIDEO_WIDTH 250
9-#define VIDEO_HEIGHT 200
10-
11-#define COTTOLETTE_SIZE 8
12-
13-#define VARS 32 // i think this is enough,, not like cot programs can be that complex rn anyway :P
14-#define VAR_NAME_LEN 16
15-#define VAR_VAL_LEN 32
16-
17-static const uint32_t
18-COTTOLETTE[COTTOLETTE_SIZE] = {
19- 0xFF1C1C1C, // 0 - blabla
20- 0xFFFAFAFA, // 1 - whie
21- 0xFFECE3FF, // 2 - lav
22- 0xFFE4D8FD, // 3 - wink
23- 0xFFD4C5F5, // 4 - sink
24- 0xFFA9A0CF, // 5 - wist
25- 0xFFFFFBDA, // 6 - yebow (random kid)
26- 0xFFD0F0C0 // 7 - geen (the (first) dude nobody invited)
27-};
28-
29-typedef struct
30-{
31- char name[VAR_NAME_LEN];
32- char value[VAR_VAL_LEN];
33-} CotVar;
34+#define OP_PUSH 0
35+#define OP_CALL 1
36+#define OP_KILL 2
37
38-typedef struct
39-{
40- uint8_t memory[MEMORY_SIZE];
41- uint32_t video[VIDEO_WIDTH * VIDEO_HEIGHT];
42+#define STACK_SIZE 64
43+#define MEM_SIZE 1024
44+#define VARS_SIZE 64
45
46- // i cant come up with a better name that gets straight to the point than
47- // "cursor" so ig it will stay this way for now,,
48- int cursor_x;
49- int cursor_y;
50+typedef struct Cotton Cotton;
51
52- uint32_t ticktock;
53- uint32_t c_cottolette; // id write "current_cottolete" but that would be
54- // alot to type and im lazyyyyyyy bwaaaaaa
55+typedef struct {
56+ char *name;
57+ void (*code)(Cotton *c);
58+} Word;
59
60- CotVar vars[VARS];
61- int var_count;
62+struct Cotton {
63+ int stack[STACK_SIZE];
64+ int stack_p;
65
66- int stack[32];
67- int stack_p;
68+ int mem[MEM_SIZE];
69+ int instruct_p;
70+ int mem_len;
71
72-} Cotton;
73+ int vars[VARS_SIZE];
74+};
75
76 void cotton_init
77 (Cotton *c);
78-void cotton_store_var
79-(Cotton *cotton, const char *name, const char *value);
80
81-#endif
82+void push
83+(Cotton *c, int v);
84
85+int pop
86+(Cotton *c);
87+
88+#endif
+154,
-208
1@@ -1,273 +1,219 @@
2-// i got to eventually clean up this file a bit i feel like its very janky but i suppose i can worry about that later - future dani here, it seems you ended up just remaking the entire file bc you thought remaking cot into a concatenated language was cooler, good job dani - future future dani here, thank you dani :D
3-
4+#include "cotton.h"
5 #include "interpreter.h"
6-#include "cottonwindow.h"
7-#include "eiki.h"
8-#include <SDL.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <ctype.h>
13
14-#define MAX_LINE 256
15-
16-// da stack
17-static void push
18-(Cotton *c, int v)
19+static void word_add
20+(Cotton *c)
21 {
22- if (c->stack_p >= 64) {
23- fprintf(stderr, "cot: there has been a stack overflow :< (like the website badumptsss)\n");
24- return;
25- }
26+ int b = pop(c);
27+ int a = pop(c);
28
29- c->stack[c->stack_p++] = v;
30+ push(c, a + b);
31 }
32
33-static int pop
34+static void word_sub
35 (Cotton *c)
36 {
37- if (c->stack_p <= 0) {
38- fprintf(stderr, "cot: there has been a stack underflow :<\n");
39- return 0;
40- }
41+ int b = pop(c);
42+ int a = pop(c);
43
44- return c->stack[--c->stack_p];
45+ push(c, a - b);
46 }
47
48-// da variable stuff
49-static int find_var
50-(Cotton *c, const char *name)
51+static void word_mul
52+(Cotton *c)
53 {
54- for (int i = 0; i < c->var_count; i++) {
55- if (strcmp(c->vars[i].name, name) == 0) return i;
56- }
57+ int b = pop(c);
58+ int a = pop(c);
59
60- return -1;
61+ push(c, a * b);
62 }
63
64-static void add_var
65-(Cotton *c, const char *name)
66+static void word_div
67+(Cotton *c)
68 {
69- if (c->var_count >= VARS) {
70- fprintf(stderr, "cot: too many variables\n");
71+ int b = pop(c);
72+ int a = pop(c);
73+
74+// Now i doubt anyone will really be dividing stuff by zero but you never know.., talk about le safety amirite.., heh
75+ if (b == 0) {
76+ fprintf(stderr, "cotton: you cant divide by zero, you dummy :P\n");
77 return;
78 }
79
80- strncpy(c->vars[c->var_count].name, name, VAR_NAME_LEN - 1);
81- c->vars[c->var_count].name[VAR_NAME_LEN - 1] = '\0';
82- strcpy(c->vars[c->var_count].value, "0");
83- c->var_count++;
84+ push(c, a / b);
85 }
86
87-// da graphics
88-static void draw_pixel_c
89-(Cotton *c, int x, int y)
90+static void word_dot
91+(Cotton *c)
92 {
93- if (x < 0 || x >= VIDEO_WIDTH || y < 0 || y >= VIDEO_HEIGHT) return;
94- c->video[y * VIDEO_WIDTH + x] = c->c_cottolette;
95+ printf("%d\n", pop(c));
96 }
97
98-static void draw_char_c
99-(Cotton *c, char ch, int x, int y)
100+// while forth does use ! and @, im quirky and #notlikeothergirls so im changing ! to -> bc i think it makes more sense :P
101+static void word_store
102+(Cotton *c)
103 {
104- for (int row = 0; row < FONT_HEIGHT; row++) {
105- uint8_t bits = EIKI_FONT[(uint8_t)ch][row];
106+ int slot = pop(c);
107+ int num = pop(c);
108
109- for (int col = 0; col < FONT_WIDTH; col++) {
110- if (bits & (1 << col)) {
111- draw_pixel_c(c, x + col, y + row);
112- }
113- }
114+ if (slot >= 0 && slot < VARS_SIZE) {
115+ c->vars[slot] = num;
116+ } else {
117+ fprintf(stderr, "cotton: tried to store somewhere that don't exist.,. its in the void now.., :<\n");
118 }
119 }
120
121-// those who interpretate skull emoji skull emoji nahhhh get outttttttttt skull emoji door emoji
122-void cotton_interpret
123-(Cotton *c, CottonWindow *cw, FILE *file)
124+static void word_fetch
125+(Cotton *c)
126 {
127- char line[MAX_LINE];
128- if (!fgets(line, sizeof(line), file)) return;
129-
130- line[strcspn(line, "\r\n")] = 0;
131- if (line[0] == '\0' || (line[0] == '/' && line[1] == '/')) return;
132-
133- char *tok = strtok(line, " ");
134-
135- while (tok) {
136+ int slot = pop(c);
137
138- int is_a_num = 1;
139- for (int i = 0; tok[i]; i++) {
140- if (!isdigit(tok[i]) && !(i == 0 && tok[i] == '-')) {
141- is_a_num = 0;
142- break;
143- }
144- }
145-
146- if (is_a_num) {
147- push(c, atoi(tok));
148- }
149-
150- // those who do math..., math from the epic video gaem baldi's basics in education and learning,., you guys should play it its a good game i like baldi,. send me an email telling me your guys' PR on endless mode
151- else if (strcmp(tok, "+") == 0) {
152- int b = pop(c), a = pop(c);
153- push(c, a + b);
154- }
155+ if (slot >= 0 && slot < VARS_SIZE) {
156+ push(c, c->vars[slot]);
157+ } else {
158+ fprintf(stderr, "cotton: tried to fetch from somewhere that don't exist,., :<\n");
159+ }
160+}
161
162- else if (strcmp(tok, "-") == 0) {
163- int b = pop(c), a = pop(c);
164- push(c, a - b);
165- }
166+static void word_dup
167+(Cotton *c)
168+{
169+ int a = pop(c);
170
171- else if (strcmp(tok, "*") == 0) {
172- int b = pop(c), a = pop(c);
173- push(c, a * b);
174- }
175+ push(c, a);
176+ push(c, a);
177+}
178
179- else if (strcmp(tok, "/") == 0) {
180- int b = pop(c), a = pop(c);
181- push(c, a / b);
182- }
183+static void word_drop
184+(Cotton *c)
185+{
186+ pop(c);
187+}
188
189- // while forth does use ! and @, im quirky and #notlikeothergirls so im changing ! to -> bc i think it makes more sense :P
190- else if (strcmp(tok, "->") == 0) {
191+static void word_swap
192+(Cotton *c)
193+{
194+ int b = pop(c);
195+ int a = pop(c);
196
197- int slot = pop(c);
198- int num = pop(c);
199-
200- if (slot >= 0 && slot < c->var_count) {
201- char buf[VAR_VAL_LEN];
202- sprintf(buf, "%d", num);
203- strncpy(c->vars[slot].value, buf, VAR_VAL_LEN - 1);
204- }
205+ push(c, b);
206+ push(c, a);
207+}
208
209- else {
210- fprintf(stderr, "cot: tried to store somewhere that don't exist.,. its in the void now.., :<\n");
211- }
212- }
213+static void word_equal
214+(Cotton *c)
215+{
216+ int b = pop(c);
217+ int a = pop(c);
218
219- else if (strcmp(tok, "@") == 0) {
220- int slot = pop(c);
221+ push(c, a == b ? 1 : 0);
222+}
223
224- if (slot >= 0 && slot < c->var_count) {
225- push(c, atoi(c->vars[slot].value));
226- }
227+static void word_lssr
228+(Cotton *c)
229+{
230+ int b = pop(c);
231+ int a = pop(c);
232
233- else {
234- fprintf(stderr, "cot: tried to fetch from somewhere that don't exist,., :<\n");
235- }
236+ push(c, a < b ? 1 : 0);
237+}
238
239- }
240+static void word_grtr
241+(Cotton *c)
242+{
243+ int b = pop(c);
244+ int a = pop(c);
245
246- else if (strcmp(tok, ".") == 0) {
247- printf("%d", pop(c));
248- fflush(stdout);
249- }
250+ push(c, a > b ? 1 : 0);
251+}
252
253- else if (strcmp(tok, "var") == 0) {
254- tok = strtok(NULL, " ");
255- if (tok) add_var(c, tok);
256- }
257+// should be enough for tonight.,., i shall be borrowing more from forth, forth is awesome, i love you forth, i forth <3 :3
258+static Word builtins[] = {
259+ {"+", word_add},
260+ {"-", word_sub},
261+ {"*", word_mul},
262+ {"/", word_div},
263+ {".", word_dot},
264+ {"->", word_store},
265+ {"@", word_fetch},
266+ {"dup", word_dup},
267+ {"drop", word_drop},
268+ {"swap", word_swap},
269+ {"=", word_equal},
270+ {"<", word_lssr},
271+ {">", word_grtr},
272+ {NULL, NULL}
273+};
274+
275+void cotton_compile
276+(Cotton *c, char *line)
277+{
278+ line[strcspn(line, "\r\n")] = 0;
279+ if (line[0] == '\0' || (line[0] == '/' && line[1] == '/')) return;
280
281- else if (strcmp(tok, "pixel") == 0) {
282- int y = pop(c);
283- int x = pop(c);
284- draw_pixel_c(c, x, y);
285- cottonwindow_update(cw, c->video, sizeof(c->video[0]) * VIDEO_WIDTH);
286- }
287+ char *tok = strtok(line, " ");
288
289- else if (strcmp(tok, "color") == 0) {
290- int slot = pop(c);
291- if (slot >= 0 && slot < COTTOLETTE_SIZE)
292- c->c_cottolette = COTTOLETTE[slot];
293+ while (tok) {
294+ if (c->mem_len >= MEM_SIZE - 2) {
295+ fprintf(stderr, "cotton: memory is full,., can't compile anymore :<\n");
296+ return;
297 }
298
299- else if (strcmp(tok, "clear") == 0) {
300- for (int i = 0; i < VIDEO_WIDTH * VIDEO_HEIGHT; i++)
301- c->video[i] = 0;
302- c->cursor_x = 0;
303- c->cursor_y = 0;
304- cottonwindow_update(cw, c->video, sizeof(c->video[0]) * VIDEO_WIDTH);
305+ int is_num = 1;
306+ for (int i = 0; tok[i]; i++) {
307+ if (!isdigit(tok[i]) && !(i == 0 && tok[i] == '-')) {
308+ is_num = 0;
309+ break;
310+ }
311 }
312
313- // the great wall of colors
314- else if (strcmp(tok, "blabla") == 0) push(c, 0);
315- else if (strcmp(tok, "whie") == 0) push(c, 1);
316- else if (strcmp(tok, "lav") == 0) push(c, 2);
317- else if (strcmp(tok, "wink") == 0) push(c, 3);
318- else if (strcmp(tok, "sink") == 0) push(c, 4);
319- else if (strcmp(tok, "wist") == 0) push(c, 5);
320- else if (strcmp(tok, "yebow") == 0) push(c, 6);
321- else if (strcmp(tok, "geen") == 0) push(c, 7);
322-
323- else if (strcmp(tok, "print") == 0) {
324- char *str = strtok(NULL, "");
325-
326- if (str) {
327- while (*str == ' ') str++;
328-
329- int nl = 0;
330- char *nl_at = strstr(str, " /n");
331-
332- if (nl_at) {
333- *nl_at = '\0';
334- nl = 1;
335- }
336-
337- if (str[0] == '"') {
338- str++;
339- char *end = strrchr(str, '"');
340- if (end) *end = '\0';
341- }
342-
343- printf("%s", str);
344- if (nl) printf("\n");
345- fflush(stdout);
346-
347- for (int i = 0; str[i]; i++) {
348- if (str[i] == '\n') {
349- c->cursor_x = 0;
350- c->cursor_y += FONT_HEIGHT + 4;
351- continue;
352- }
353-
354- draw_char_c(c, str[i], c->cursor_x, c->cursor_y);
355- c->cursor_x += FONT_WIDTH + 2;
356-
357- if (c->cursor_x + FONT_WIDTH >= VIDEO_WIDTH) {
358- c->cursor_x = 0;
359- c->cursor_y += FONT_HEIGHT + 4;
360- }
361- }
362+ if (is_num) {
363+ c->mem[c->mem_len++] = OP_PUSH;
364+ c->mem[c->mem_len++] = atoi(tok);
365+ }
366
367- if (nl) {
368- c->cursor_x = 0;
369- c->cursor_y += FONT_HEIGHT + 4;
370+ else {
371+ int found = 0;
372+ for (int i = 0; builtins[i].name != NULL; i++) {
373+ if (strcmp(tok, builtins[i].name) == 0) {
374+ c->mem[c->mem_len++] = OP_CALL;
375+ c->mem[c->mem_len++] = i;
376+ found = 1;
377+ break;
378 }
379+ }
380
381- cottonwindow_update(cw, c->video, sizeof(c->video[0]) * VIDEO_WIDTH);
382+ if (!found) {
383+ fprintf(stderr, "cotton: cotton doesn't know what \"%s\" means,., :<\n", tok);
384 }
385- break;
386- }
387-
388- else if (strcmp(tok, "wait") == 0) {
389- c->ticktock = SDL_GetTicks() + pop(c);
390 }
391+ tok = strtok(NULL, " ");
392+ }
393+}
394
395- else if (strcmp(tok, "kill") == 0) {
396- exit(0);
397+void cotton_run
398+(Cotton *c)
399+{
400+ c->instruct_p = 0;
401+
402+ while (c->instruct_p < c->mem_len) {
403+ int op = c->mem[c->instruct_p++];
404+
405+ if (op == OP_PUSH) {
406+ push(c, c->mem[c->instruct_p++]);
407 }
408
409- else {
410- int slot = find_var(c, tok);
411- if (slot >= 0) {
412- push(c, slot);
413- }
414+ else if (op == OP_CALL) {
415+ int idx = c->mem[c->instruct_p++];
416+ builtins[idx].code(c);
417+ }
418
419- else {
420- fprintf(stderr, "cot: cotton doesn't know what \"%s\" means, maybe type that out again? :<", tok);
421- }
422+ else if (op == OP_KILL) {
423+ break;
424 }
425-
426- tok = strtok(NULL, " ");
427 }
428 }
+5,
-4
1@@ -2,10 +2,11 @@
2 #define INTERPRETER_H
3
4 #include "cotton.h"
5-#include "cottonwindow.h"
6-#include <stdio.h>
7
8-void cotton_interpret
9-(Cotton *cotton, CottonWindow *cw, FILE *file);
10+void cotton_compile
11+(Cotton *c, char *line);
12+
13+void cotton_run
14+(Cotton *c);
15
16 #endif
+35,
-0
1@@ -0,0 +1,35 @@
2+#include "cotton.h"
3+#include "interpreter.h"
4+#include <stdio.h>
5+
6+int main
7+(int argc, char **argv)
8+{
9+ if (argc < 2) {
10+ fprintf(stderr, "cotton: cotton couldn't find any .cot files to run :P\n");
11+ return 1;
12+ }
13+
14+ FILE *f = fopen(argv[1], "r");
15+
16+ if (!f) {
17+ fprintf(stderr, "cotton: couldn't open \"%s\", is this even a file.,.? :<\n", argv[1]);
18+ return 1;
19+ }
20+
21+ Cotton c;
22+ cotton_init(&c);
23+
24+ char line[256];
25+ while (fgets(line, sizeof(line), f)) {
26+ cotton_compile(&c, line);
27+ }
28+
29+ fclose(f);
30+
31+ c.mem[c.mem_len++] = OP_KILL;
32+
33+ cotton_run(&c);
34+
35+ return 0;
36+}