commit b5586b1
0uppy
·
2026-09-08 19:42:06 +0000 UTC
parent c6d7e65
cot - started remaking cot (aiming to make it a concatenated lang) and remade the interpreter for cot
9 files changed,
+215,
-400
+0,
-0
+2,
-0
1@@ -0,0 +1,2 @@
2+print "test test this is a test" print
3+print "does cot render text okay again uhhh" print
+0,
-16
1@@ -1,16 +0,0 @@
2-color blabla
3-print "hallo this is" /n
4-color whie
5-print "a showcase cot file" /n
6-color lav
7-print "to show YOU" /n
8-color wink
9-print "cotton's slightly new" /n
10-color sink
11-print "cottolette,..," /n
12-color wist
13-print "i hope yuo guys liek it" /n
14-color yebow
15-print "thats it" /n
16-color geen
17-print "geen" /n
+0,
-9
1@@ -1,9 +0,0 @@
2-print "ABCDEFGHIJKL"
3-print "MNOPQRSTUVWX"
4-print "YZ"
5-print "abcdefghijkl"
6-print "mnopqrstuvwx"
7-print "yz"
8-
9-print "1234567890"
10-print "! ? ; : ."
+0,
-5
1@@ -1,5 +0,0 @@
2-print "HELLO FROM COT :D"
3-wait 1
4-print "THIS IS A SHOWCASE COT FILE"
5-wait 1
6-print "WORDS WORDS WORDS"
+1,
-1
1@@ -1,5 +1,5 @@
2 project('cotton', 'c',
3- version : '0.2',
4+ version : '0.3',
5 default_options : ['c_std=c99', 'warning_level=2'])
6
7 sdl2 = dependency('sdl2')
+2,
-24
1@@ -11,29 +11,7 @@ void cotton_init
2
3 srand((unsigned int)time(NULL));
4
5- c->c_cottolette = COTTOLETTE[1];
6-}
7-
8-void cotton_store_var
9-(Cotton *cotton, const char *name, const char *value)
10-{
11- for (int i = 0; i < cotton->var_count; i++) {
12- if (strcmp(cotton->vars[i].name, name) == 0) {
13- strncpy(cotton->vars[i].value, value, VAR_VAL_LEN - 1);
14- cotton->vars[i].value[VAR_VAL_LEN - 1] = '\0';
15- return;
16- }
17- }
18+ c->stack_p = 0;
19
20- if (cotton->var_count < VARS) {
21- strncpy(cotton->vars[cotton->var_count].name, name, VAR_NAME_LEN - 1);
22- cotton->vars[cotton->var_count].name[VAR_NAME_LEN - 1] = '\0';
23-
24- strncpy(cotton->vars[cotton->var_count].value, value, VAR_VAL_LEN - 1);
25- cotton->vars[cotton->var_count].value[VAR_VAL_LEN - 1] = '\0';
26-
27- cotton->var_count++;
28- } else {
29- fprintf(stderr, "cotton ran out of variable slots :( - max ammount is %d\n", VARS);
30- }
31+ c->c_cottolette = COTTOLETTE[1];
32 }
+4,
-1
1@@ -46,7 +46,10 @@ typedef struct
2 // alot to type and im lazyyyyyyy bwaaaaaa
3
4 CotVar vars[VARS];
5- int var_count;
6+ int var_count;
7+
8+ int stack[32];
9+ int stack_p;
10
11 } Cotton;
12
+206,
-344
1@@ -1,4 +1,4 @@
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
3+// 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
4
5 #include "interpreter.h"
6 #include "cottonwindow.h"
7@@ -7,405 +7,267 @@
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11-#include <unistd.h>
12+#include <ctype.h>
13
14-// maximum length of a .cot file line
15 #define MAX_LINE 256
16
17-// da string AND variable stuff
18-
19-static void
20-strip_newline(char *s)
21+// da stack
22+static void push
23+(Cotton *c, int v)
24 {
25- s[strcspn(s, "\r\n")] = 0;
26+ if (c->stack_p >= 64) {
27+ fprintf(stderr, "cot: there has been a stack overflow :< (like the website badumptsss)\n");
28+ return;
29+ }
30+
31+ c->stack[c->stack_p++] = v;
32 }
33
34-static char
35-*get_arg (char *line)
36+static int pop
37+(Cotton *c)
38 {
39- char *space = strchr(line, ' ');
40-
41- if (space != NULL) {
42- return space + 1;
43+ if (c->stack_p <= 0) {
44+ fprintf(stderr, "cot: there has been a stack underflow :<\n");
45+ return 0;
46 }
47
48- else {
49- return NULL;
50- }
51+ return c->stack[--c->stack_p];
52 }
53
54-static char
55-*strip_quotes(char *s)
56+// da variable stuff
57+static int find_var
58+(Cotton *c, const char *name)
59 {
60- if (s[0] == '"') {
61- char *end = strrchr(s, '"');
62-
63- if (end == NULL) {
64- fprintf(stderr, "cot syntax error : looks like you forgot a quote at the end xP\n");
65- return s;
66- }
67-
68- *end = '\0';
69- return s + 1;
70+ for (int i = 0; i < c->var_count; i++) {
71+ if (strcmp(c->vars[i].name, name) == 0) return i;
72 }
73
74- return s;
75+ return -1;
76 }
77
78-static const char
79-*get_var_value(Cotton *cotton, const char *name)
80+static void add_var
81+(Cotton *c, const char *name)
82 {
83- for (int i = 0; i < cotton->var_count; i++) {
84- if (strcmp(cotton->vars[i].name, name) == 0) {
85- return cotton->vars[i].value;
86- }
87+ if (c->var_count >= VARS) {
88+ fprintf(stderr, "cot: too many variables\n");
89+ return;
90 }
91- return NULL;
92-}
93
94-// da graphics stuff
95+ strncpy(c->vars[c->var_count].name, name, VAR_NAME_LEN - 1);
96+ c->vars[c->var_count].name[VAR_NAME_LEN - 1] = '\0';
97+ strcpy(c->vars[c->var_count].value, "0");
98+ c->var_count++;
99+}
100
101-static void
102-draw_pixel (Cotton *cotton, int x, int y)
103+// da graphics
104+static void draw_pixel_c
105+(Cotton *c, int x, int y)
106 {
107- cotton->video[y * VIDEO_WIDTH + x] = cotton->c_cottolette;
108+ if (x < 0 || x >= VIDEO_WIDTH || y < 0 || y >= VIDEO_HEIGHT) return;
109+ c->video[y * VIDEO_WIDTH + x] = c->c_cottolette;
110 }
111
112-static void
113-draw_char (Cotton *cotton, char c, int x, int y)
114+static void draw_char_c
115+(Cotton *c, char ch, int x, int y)
116 {
117 for (int row = 0; row < FONT_HEIGHT; row++) {
118- uint8_t bits = EIKI_FONT[(uint8_t)c][row];
119+ uint8_t bits = EIKI_FONT[(uint8_t)ch][row];
120
121 for (int col = 0; col < FONT_WIDTH; col++) {
122-
123 if (bits & (1 << col)) {
124- draw_pixel(cotton, x + col, y + row);
125+ draw_pixel_c(c, x + col, y + row);
126 }
127 }
128 }
129 }
130
131-// da commands
132-
133-static void
134-cmd_print(Cotton *cotton, CottonWindow *cw, char *arg)
135+// those who interpretate skull emoji skull emoji nahhhh get outttttttttt skull emoji door emoji
136+void cotton_interpret
137+(Cotton *c, CottonWindow *cw, FILE *file)
138 {
139- if (!arg)
140- return;
141-
142- int nl = 0;
143- char *nl_str = strstr(arg, " /n");
144-
145- if (nl_str != NULL) {
146- nl = 1;
147- *nl_str = '\0';
148- }
149-
150- char *text = strip_quotes(arg);
151-
152- const char *value = get_var_value(cotton, text);
153- if (value != NULL) {
154- text = (char *)value;
155- }
156-
157- if (nl) {
158- printf("%s\n", text);
159- } else {
160- printf("%s", text);
161- fflush(stdout);
162- }
163-
164- for (int i = 0; text[i] != '\0'; i++) {
165- if (text[i] == '\n') {
166- cotton->cursor_x = 0;
167- cotton->cursor_y += FONT_HEIGHT + 4;
168- continue;
169+ char line[MAX_LINE];
170+ if (!fgets(line, sizeof(line), file)) return;
171+
172+ line[strcspn(line, "\r\n")] = 0;
173+ if (line[0] == '\0' || (line[0] == '/' && line[1] == '/')) return;
174+
175+ char *tok = strtok(line, " ");
176+
177+ while (tok) {
178+
179+ int is_a_num = 1;
180+ for (int i = 0; tok[i]; i++) {
181+ if (!isdigit(tok[i]) && !(i == 0 && tok[i] == '-')) {
182+ is_a_num = 0;
183+ break;
184+ }
185 }
186-
187- draw_char(cotton, text[i], cotton->cursor_x, cotton->cursor_y);
188- cotton->cursor_x += FONT_WIDTH + 2;
189-
190- if (cotton->cursor_x + FONT_WIDTH + 2 >= VIDEO_WIDTH) {
191- cotton->cursor_x = 0;
192- cotton->cursor_y += FONT_HEIGHT + 4;
193+
194+ if (is_a_num) {
195+ push(c, atoi(tok));
196 }
197- }
198-
199- if (nl) {
200- cotton->cursor_x = 0;
201- cotton->cursor_y += FONT_HEIGHT + 4;
202- }
203-
204- cottonwindow_update(cw, cotton->video, sizeof(cotton->video[0]) * VIDEO_WIDTH);
205-}
206-
207-static void
208-cmd_pixel(Cotton *cotton, CottonWindow *cw, char *arg)
209-{
210- int x, y;
211-
212- if (!arg || sscanf(arg, "%d %d", &x, &y) != 2) {
213- fprintf(stderr, "cot syntax error: usage for pixel is 'pixel <x> <y>' :P\n");
214- return;
215- }
216
217- if (x < 0 || x >= VIDEO_WIDTH || y < 0 || y >= VIDEO_HEIGHT) {
218- fprintf(stderr, "cot syntax error: pixel (%d, %d) is out of bounds :<\n", x, y);
219- return;
220- }
221-
222- draw_pixel(cotton, x, y);
223-
224- cottonwindow_update(cw, cotton->video, sizeof(cotton->video[0]) * VIDEO_WIDTH);
225-}
226-
227-static void
228-cmd_var(Cotton *cotton, char *arg)
229-{
230- if (!arg)
231- return;
232-
233- char *space = strchr(arg, ' ');
234- if (!space) {
235- fprintf(stderr, "cot syntax error: you forgor to put a value for your variable xP\n");
236- return;
237- }
238-
239- *space = '\0';
240- char *name = arg;
241- char *value = space + 1;
242-
243- cotton_store_var(cotton, name, value);
244-}
245-
246-static void
247-cmd_clear(Cotton *cotton, CottonWindow *cw)
248-{
249- for (int i = 0; i < VIDEO_WIDTH * VIDEO_HEIGHT; i++) {
250- cotton->video[i] = 0;
251- }
252-
253- cotton->cursor_x = 0;
254- cotton->cursor_y = 0;
255-
256- cottonwindow_update(cw, cotton->video, sizeof(cotton->video[0]) * VIDEO_WIDTH);
257-}
258-
259-static void
260-cmd_color(Cotton *cotton, char *arg)
261-{
262- if (!arg)
263- return;
264-
265- if (strcmp(arg, "blabla") == 0)
266- cotton->c_cottolette = COTTOLETTE[0];
267-
268- else if (strcmp(arg, "whie") == 0)
269- cotton->c_cottolette = COTTOLETTE[1];
270-
271- else if (strcmp(arg, "lav") == 0)
272- cotton->c_cottolette = COTTOLETTE[2];
273-
274- else if (strcmp(arg, "wink") == 0)
275- cotton->c_cottolette = COTTOLETTE[3];
276-
277- else if (strcmp(arg, "sink") == 0)
278- cotton->c_cottolette = COTTOLETTE[4];
279-
280- else if (strcmp(arg, "wist") == 0)
281- cotton->c_cottolette = COTTOLETTE[5];
282-
283- else if (strcmp(arg, "yebow") == 0)
284- cotton->c_cottolette = COTTOLETTE[6];
285-
286- else if (strcmp(arg, "geen") == 0)
287- cotton->c_cottolette = COTTOLETTE[7];
288-
289- else
290- fprintf(stderr, "cot syntax error: cotton doesn't know the color \"%s\" sorry,, :(\n", arg);
291-}
292-
293-static void
294-cmd_wait(Cotton *cotton, char *arg)
295-{
296- if (!arg)
297- return;
298+ // 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
299+ else if (strcmp(tok, "+") == 0) {
300+ int b = pop(c), a = pop(c);
301+ push(c, a + b);
302+ }
303
304- int seconds = atoi(arg);
305+ else if (strcmp(tok, "-") == 0) {
306+ int b = pop(c), a = pop(c);
307+ push(c, a - b);
308+ }
309
310- cotton->ticktock = SDL_GetTicks() + (seconds * 1000);
311-}
312+ else if (strcmp(tok, "*") == 0) {
313+ int b = pop(c), a = pop(c);
314+ push(c, a * b);
315+ }
316
317-static void
318-cmd_input(Cotton *cotton, char *arg)
319-{
320- if (!arg) {
321- fprintf(stderr, "cotton syntax error: input needs a variable name xP\n");
322- return;
323- }
324+ else if (strcmp(tok, "/") == 0) {
325+ int b = pop(c), a = pop(c);
326+ push(c, a / b);
327+ }
328
329- char buffer[VAR_VAL_LEN];
330+ // while forth does use ! and @, im quirky and #notlikeothergirls so im changing ! to -> bc i think it makes more sense :P
331+ else if (strcmp(tok, "->") == 0) {
332
333- // kind of a quick and dirty way of implementing input, i know, but, i cant be arsed to get myself into a potential rabbit hole with SDL so for now i will leave this to be this way,, sorry,,
334- if (fgets(buffer, sizeof(buffer), stdin) != NULL) {
335- buffer[strcspn(buffer, "\r\n")] = '\0';
336+ int slot = pop(c);
337+ int num = pop(c);
338+
339+ if (slot >= 0 && slot < c->var_count) {
340+ char buf[VAR_VAL_LEN];
341+ sprintf(buf, "%d", num);
342+ strncpy(c->vars[slot].value, buf, VAR_VAL_LEN - 1);
343+ }
344
345- cotton_store_var(cotton, arg, buffer);
346- }
347-}
348+ else {
349+ fprintf(stderr, "cot: tried to store somewhere that don't exist.,. its in the void now.., :<\n");
350+ }
351+ }
352
353-static void
354-cmd_kill(void)
355-{
356- printf("[cotton stopped]\n");
357- exit(0);
358-}
359+ else if (strcmp(tok, "@") == 0) {
360+ int slot = pop(c);
361
362-static void
363-cmd_math(Cotton *cotton, char *arg, char op)
364-{
365- char var_name[64];
366- char value[64];
367+ if (slot >= 0 && slot < c->var_count) {
368+ push(c, atoi(c->vars[slot].value));
369+ }
370
371- if (!arg || sscanf(arg, "%63s %63s", var_name, value) != 2) {
372- fprintf(stderr, "cot syntax error: usage is '<add, sub, mult, div> <variable> <number OR another variable>'\n");
373- return;
374- }
375+ else {
376+ fprintf(stderr, "cot: tried to fetch from somewhere that don't exist,., :<\n");
377+ }
378
379- int current = 0;
380- int amount = 0;
381+ }
382
383- // thank you clang for coming in clutch and telling me to make this const i forgor (skull emoji)
384- const char *var = get_var_value(cotton, var_name);
385- if (var) {
386- current = atoi(var);
387- }
388+ else if (strcmp(tok, ".") == 0) {
389+ printf("%d", pop(c));
390+ fflush(stdout);
391+ }
392
393- // and this too, i love clang, clang is the best compiler evah !!!
394- const char *other = get_var_value(cotton, value);
395- if (other) {
396- amount = atoi(other);
397- } else {
398- amount = atoi(value);
399- }
400+ else if (strcmp(tok, "var") == 0) {
401+ tok = strtok(NULL, " ");
402+ if (tok) add_var(c, tok);
403+ }
404
405- switch (op) {
406- case '+':
407- current += amount;
408- break;
409+ else if (strcmp(tok, "pixel") == 0) {
410+ int y = pop(c);
411+ int x = pop(c);
412+ draw_pixel_c(c, x, y);
413+ cottonwindow_update(cw, c->video, sizeof(c->video[0]) * VIDEO_WIDTH);
414+ }
415
416- case '-':
417- current -= amount;
418- break;
419+ else if (strcmp(tok, "color") == 0) {
420+ int slot = pop(c);
421+ if (slot >= 0 && slot < COTTOLETTE_SIZE)
422+ c->c_cottolette = COTTOLETTE[slot];
423+ }
424
425- case '*':
426- current *= amount;
427- break;
428+ else if (strcmp(tok, "clear") == 0) {
429+ for (int i = 0; i < VIDEO_WIDTH * VIDEO_HEIGHT; i++)
430+ c->video[i] = 0;
431+ c->cursor_x = 0;
432+ c->cursor_y = 0;
433+ cottonwindow_update(cw, c->video, sizeof(c->video[0]) * VIDEO_WIDTH);
434+ }
435
436- case '/':
437- current /= amount;
438+ // the great wall of colors
439+ else if (strcmp(tok, "blabla") == 0) push(c, 0);
440+ else if (strcmp(tok, "whie") == 0) push(c, 1);
441+ else if (strcmp(tok, "lav") == 0) push(c, 2);
442+ else if (strcmp(tok, "wink") == 0) push(c, 3);
443+ else if (strcmp(tok, "sink") == 0) push(c, 4);
444+ else if (strcmp(tok, "wist") == 0) push(c, 5);
445+ else if (strcmp(tok, "yebow") == 0) push(c, 6);
446+ else if (strcmp(tok, "geen") == 0) push(c, 7);
447+
448+ else if (strcmp(tok, "print") == 0) {
449+ char *str = strtok(NULL, "");
450+
451+ if (str) {
452+ while (*str == ' ') str++;
453+
454+ int nl = 0;
455+ char *nl_at = strstr(str, " /n");
456+
457+ if (nl_at) {
458+ *nl_at = '\0';
459+ nl = 1;
460+ }
461+
462+ if (str[0] == '"') {
463+ str++;
464+ char *end = strrchr(str, '"');
465+ if (end) *end = '\0';
466+ }
467+
468+ printf("%s", str);
469+ if (nl) printf("\n");
470+ fflush(stdout);
471+
472+ for (int i = 0; str[i]; i++) {
473+ if (str[i] == '\n') {
474+ c->cursor_x = 0;
475+ c->cursor_y += FONT_HEIGHT + 4;
476+ continue;
477+ }
478+
479+ draw_char_c(c, str[i], c->cursor_x, c->cursor_y);
480+ c->cursor_x += FONT_WIDTH + 2;
481+
482+ if (c->cursor_x + FONT_WIDTH >= VIDEO_WIDTH) {
483+ c->cursor_x = 0;
484+ c->cursor_y += FONT_HEIGHT + 4;
485+ }
486+ }
487+
488+ if (nl) {
489+ c->cursor_x = 0;
490+ c->cursor_y += FONT_HEIGHT + 4;
491+ }
492+
493+ cottonwindow_update(cw, c->video, sizeof(c->video[0]) * VIDEO_WIDTH);
494+ }
495 break;
496+ }
497+
498+ else if (strcmp(tok, "wait") == 0) {
499+ c->ticktock = SDL_GetTicks() + pop(c);
500+ }
501
502- default:
503- fprintf(stderr, "cot syntax error: cot doesn't know what operator this is :( \n");
504- return;
505- }
506-
507- char buffer[32];
508- sprintf(buffer, "%d", current);
509-
510- cotton_store_var(cotton, var_name, buffer);
511-}
512-
513-static void
514-cmd_unknown(const char *cmd)
515-{
516- fprintf(stderr,
517- "cot syntax error: cotton doesn't know what \"%s\" means, care to "
518- "type that out again? :<\n",
519- cmd);
520-}
521-
522-// da interpreter loop
523-
524-void
525-cotton_interpret(Cotton *cotton, CottonWindow *cw, FILE *file)
526-{
527- char line[MAX_LINE];
528-
529- // this reads the file one line at a time until we get to da end of da file
530- if (!fgets(line, sizeof(line), file))
531- return;
532-
533- strip_newline(line);
534-
535-// there used to be a joke about cot using # comments "like C" which was an inside joke but after this being pointed out because of genuine curiosity i decided to just change the comments in cot to //, more used to that anyway bwaa
536- if (line[0] == '\0' || (line[0] == '/' && line[1] == '/')) // thank you for the fix emilia!! :D
537- return;
538-
539- char line_copy[MAX_LINE];
540-
541- strncpy(line_copy, line, MAX_LINE - 1);
542- line_copy[MAX_LINE - 1] = '\0';
543-
544- char *cmd = strtok(line_copy, " ");
545-
546- if (!cmd)
547- return;
548-
549- // RELEASE THE KRAKE- I MEAN, RELEASE THE GREAT WALL OF COMMANDS !!! could i format this better? maybe,, but but i'd say this is readable and i think readability is gud so i will keep it nice and green,,, green!! :D
550- char *arg = get_arg(line);
551-
552- if (strcmp(cmd, "print") == 0) {
553- cmd_print(cotton, cw, arg);
554- }
555-
556- else if (strcmp(cmd, "pixel") == 0) {
557- cmd_pixel(cotton, cw, arg);
558- }
559-
560- else if (strcmp(cmd, "var") == 0) {
561- cmd_var(cotton, arg);
562- }
563-
564- else if (strcmp(cmd, "clear") == 0) {
565- cmd_clear(cotton, cw);
566- }
567-
568- else if (strcmp(cmd, "color") == 0) {
569- cmd_color(cotton, arg);
570- }
571-
572- else if (strcmp(cmd, "wait") == 0) {
573- cmd_wait(cotton, arg);
574- }
575-
576- else if (strcmp(cmd, "input") == 0) {
577- cmd_input(cotton, arg);
578- }
579-
580- else if (strcmp(cmd, "kill") == 0) {
581- cmd_kill();
582- }
583-
584- else if (strcmp(cmd, "add") == 0) {
585- cmd_math(cotton, arg, '+');
586- }
587-
588- else if (strcmp(cmd, "sub") == 0) {
589- cmd_math(cotton, arg, '-');
590- }
591-
592- else if (strcmp(cmd, "mult") == 0) {
593- cmd_math(cotton, arg, '*');
594- }
595+ else if (strcmp(tok, "kill") == 0) {
596+ exit(0);
597+ }
598
599- else if (strcmp(cmd, "div") == 0) {
600- cmd_math(cotton, arg, '/');
601- }
602+ else {
603+ int slot = find_var(c, tok);
604+ if (slot >= 0) {
605+ push(c, slot);
606+ }
607
608- else {
609- cmd_unknown(cmd);
610+ else {
611+ fprintf(stderr, "cot: cotton doesn't know what \"%s\" means, maybe type that out again? :<", tok);
612+ }
613+ }
614+
615+ tok = strtok(NULL, " ");
616 }
617 }