commit e63e81b

0uppy  ·  2026-09-13 17:53:12 +0000 UTC
parent 7c6460c
cotton & docs - BIG update, made the split (TM) and updated the docs to be up-to-date with the changes from this update
11 files changed,  +319, -269
+11, -3
 1@@ -13,7 +13,15 @@ programming language
 2 cot's development is being made side by side with cotton's development, as such, one keeps
 3 the other in mind
 4 
 5-cot has two types of keywords: builtins and immediates
 6+in cot, "words" are refered to as cogs - as such, there are two types of cogs:
 7+
 8+.B1 -tag -width "Cogs" 
 9+.It Cogs
10+Hardcoded words into cot, so, words that already come with base cot
11+.It UCogs 
12+Words that are defined by the user, so, words that do not come with cot by default and that the user must make themselves (as of cot 0.1 this isn't possible YET, however, it is smth i want to implement in the near future)
13+
14+cot also has two types of keywords (or, keycogs): builtins and immediates
15 
16 .Bl -tag -width "Immediates"
17 .It Builtins
18@@ -22,7 +30,7 @@ Words that are executed at runtime that directly manipulate the data stack or th
19 Words processed at compile time to handle control flow and the program's structure (such as if, else, end, etc.)
20 .El
21 
22-.Sh WORDS
23+.Sh COGS
24 .Bl -tag -width "-> (slot)"
25 .It Ic + , - , * , /
26 Pops two values, performs arithmetic, and pushes the result
27@@ -52,7 +60,7 @@ Starts a loop
28 Jumps back to it's correspondent loop statement while the condition is false, then it falls through once the condition is true
29 .El
30 
31-NOTE: some of the commands above are subject to change given that cot(ton) has yet to reach it's first stable release - even then, any update to any command will be doccumented here and i will also do my best to not break the whole syntax every update ;w;
32+NOTE: some of the cogs above are subject to change given that cot(ton) has yet to reach it's first stable release - even then, any update to any command will be doccumented here and i will also do my best to not break the whole syntax every update ;w;
33 
34 .Sh SEE ALSO
35 .Xr cotton 1
+20, -2
 1@@ -13,9 +13,27 @@
 2 
 3 cotton is a small stack machine for the cot(5) programming language (inspired by Lua, Forth and Uxntal) written in C99
 4 
 5+cotton's internals consist of 7 files (as of cotton 0.1) which are:
 6+
 7+.Ss src/
 8+.Bl -tag -width "main.c"
 9+.It main.c
10+This file reads each .cot file line by line and then hands each read line to the loom, then, it returns the results
11+.It Ic cotton.c
12+This file handles the core operations of cotton: initializing state, and, pushing and popping the stack
13+.It Ic cotton.h 
14+This file has the Cotton struct, contains the cog types, opcode definitions and the specs for Cotton
15+.It Ic weave.c
16+This file has the cogs, so, the builtin and runtime keycogs
17+.It Ic weave.h 
18+This file declares the keycogs so they can be used elsewhere inside of Cotton
19+.It Ic loom.c
20+This file is for the compiler and the runtime for Cotton
21+.It Ic loom.h
22+This file is where cotton_compile and cotton_run are declared to be used in loom.c
23+.El
24+
25 as of now it only compiles cot programs, but, i do intend to add the option to compile cot programs to uxntal in the future :P
26 
27 .Sh SEE ALSO
28 .Xr cot 5
29-
30-
+19, -0
 1@@ -0,0 +1,19 @@
 2+// those who loop through the cotrooms hashtag awesome reference
 3+
 4+"kurukuru kurukuru" .s
 5+
 6+0 0 ->
 7+loop
 8+"kurikaesu" .s
 9+0 @ 1 + 0 ->
10+0 @ 4 =
11+until
12+
13+"furafura furafura" .s
14+
15+0 0 ->
16+loop
17+"furakutaru" .s
18+0 @ 1 + 0 ->
19+0 @ 4 =
20+until
+0, -9
 1@@ -1,9 +0,0 @@
 2-0 0 ->
 3-
 4-loop
 5-
 6-0 @ .n
 7-0 @ 1 + 0 ->
 8-0 @ 6 =
 9-
10-until
+2, -3
 1@@ -2,12 +2,11 @@ project('cotton', 'c',
 2   version : '0.1',
 3   default_options : ['c_std=c99', 'warning_level=2'])
 4 
 5-sdl2 = dependency('sdl2')
 6-
 7 src_files = [
 8   'src/main.c',
 9   'src/cotton.c',
10-  'src/interpreter.c',
11+  'src/loom.c',
12+  'src/weave.c',
13 ]
14 
15 executable('cotton', src_files)
+1, -1
1@@ -18,7 +18,7 @@ typedef struct Cotton Cotton;
2 typedef struct {
3     char *name;
4     void (*code)(Cotton *c);
5-} Word;
6+} Cog;
7 
8 struct Cotton {
9     int stack[STACK_SIZE];
R src/interpreter.c => src/loom.c
+7, -248
  1@@ -1,264 +1,23 @@
  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+// FUTURE DANI HERE !!! I DID IT !!! I GOT OFF MY LAZY ASS !!! RAGHHHHHHHHHHHHHH
  6+
  7 #include "cotton.h"
  8-#include "interpreter.h"
  9+#include "loom.h"
 10+#include "weave.h"
 11 #include <stdio.h>
 12 #include <stdlib.h>
 13 #include <string.h>
 14 #include <ctype.h>
 15 
 16-static void word_add
 17-(Cotton *c)
 18-{
 19-	int b = pop(c);
 20-    int a = pop(c);
 21-
 22-    push(c, a + b);
 23-}
 24-
 25-static void word_sub
 26-(Cotton *c)
 27-{
 28-    int b = pop(c);
 29-    int a = pop(c);
 30-
 31-    push(c, a - b);
 32-}
 33-
 34-static void word_mul
 35-(Cotton *c)
 36-{
 37-    int b = pop(c);
 38-    int a = pop(c);
 39-
 40-    push(c, a * b);
 41-}
 42-
 43-static void word_div
 44-(Cotton *c)
 45-{
 46-    int b = pop(c);
 47-    int a = pop(c);
 48-
 49-    // Now, i doubt anyone will really be dividing stuff by zero but you never know.., talk about le safety amirite.., heh 
 50-    if (b == 0) {
 51-
 52-        fprintf(stderr, "cotton: you cant divide by zero, you dummy :P\n");
 53-        return;
 54-    }
 55-
 56-    push(c, a / b);
 57-}
 58-
 59-static void word_dotnum
 60-(Cotton *c)
 61-{
 62-	printf("%d\n", pop(c));
 63-}
 64-
 65-static void word_dotstr
 66-(Cotton *c)
 67-{ 
 68-    int ptr = pop(c);
 69-
 70-    while (c->mem[ptr] != '\0') {
 71-
 72-        printf("%c", c->mem[ptr]);
 73-
 74-        ptr++;
 75-    }
 76-
 77-	printf("\n");
 78-}
 79-
 80-// while forth does use ! and @, im quirky and #notlikeothergirls so im changing ! to -> bc i think it makes more sense :P
 81-static void word_store
 82-(Cotton *c)
 83-{
 84-    int slot = pop(c);
 85-    int num = pop(c);
 86-
 87-    if (slot >= 0 && slot < VARS_SIZE) {
 88-
 89-        c->vars[slot] = num;
 90-    } 
 91-
 92-    else {
 93-
 94-        fprintf(stderr, "cotton: i tried to store somewhere that don't exist,, its in the void now.., :(\n");
 95-    }
 96-}
 97-
 98-static void word_fetch
 99-(Cotton *c)
100-{
101-    int slot = pop(c);
102-
103-    if (slot >= 0 && slot < VARS_SIZE) {
104-
105- 		push(c, c->vars[slot]);
106-    } 
107-
108-    else {
109-
110-        fprintf(stderr, "cotton: i tried to fetch from somewhere that seemingly don't exist,, erm.,.\n");
111-    }
112-}
113-
114-static void word_dup
115-(Cotton *c)
116-{
117-    int a = pop(c);
118-
119-    push(c, a);
120-    push(c, a);
121-}
122-
123-static void word_drop
124-(Cotton *c)
125-{
126-    pop(c);
127-}
128-
129-static void word_swap
130-(Cotton *c)
131-{
132-    int b = pop(c);
133-    int a = pop(c);
134-
135-    push(c, b);
136-    push(c, a);
137-}
138-
139-static void word_equal
140-(Cotton *c)
141-{
142-    int b = pop(c);
143-    int a = pop(c);
144-
145-    push(c, a == b ? 1 : 0);
146-}
147-
148-static void word_lssr
149-(Cotton *c)
150-{
151-    int b = pop(c);
152-    int a = pop(c);
153-
154-    push(c, a < b ? 1 : 0);
155-}
156-
157-static void word_grtr
158-(Cotton *c)
159-{
160-    int b = pop(c);
161-    int a = pop(c);
162-
163-    push(c, a > b ? 1 : 0);
164-}
165-
166-static Word builtins[] = {
167-    {"+", word_add},
168-    {"-", word_sub},
169-    {"*", word_mul},
170-    {"/", word_div},
171-    {".n", word_dotnum},
172-	{".s", word_dotstr}, 
173-    {"->", word_store},
174-    {"@", word_fetch},
175-    {"dup", word_dup},
176-    {"drop", word_drop},
177-    {"swap", word_swap},
178-    {"=", word_equal},
179-    {"<", word_lssr},
180-    {">", word_grtr},
181-    {NULL, NULL}
182-};
183-
184-/* this comment serves as a separator to split the words above from the words below, the words below run straight away while compiling
185-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) */
186-
187-static void word_if
188-(Cotton *c)
189-{
190-    if (c->jmp_stack_p >= JMP_STACK_SIZE) {
191-
192-        fprintf(stderr, "cotton: there are too many nested ifs, calm down!! D:\n");
193-        return;
194-    }
195-
196-    c->mem[c->mem_len++] = OP_FJMP;
197-    c->jmp_stack[c->jmp_stack_p++] = c->mem_len;
198-    c->mem[c->mem_len++] = 0;
199-}
200-
201-static void word_else
202-(Cotton *c)
203-{
204-    if (c->jmp_stack_p <= 0) {
205-
206-        fprintf(stderr, "cotton: i found an else without an if,., where'd that come from??\n");
207-        return;
208-    }
209-
210-    int if_target = c->jmp_stack[--c->jmp_stack_p];
211-
212-    c->mem[c->mem_len++] = OP_JMP;
213-    c->jmp_stack[c->jmp_stack_p++] = c->mem_len;
214-    c->mem[c->mem_len++] = 0;
215-
216-    c->mem[if_target] = c->mem_len;
217-}
218-
219-static void word_end
220-(Cotton *c)
221-{
222-    if (c->jmp_stack_p <= 0) {
223-
224-        fprintf(stderr, "cotton: i found an end without an if,., where'd that come from??\n");
225-        return;
226-    }
227-
228-    int target = c->jmp_stack[--c->jmp_stack_p];
229-    c->mem[target] = c->mem_len;
230-}
231-
232-static void word_loop
233-(Cotton *c)
234-{
235-	c->jmp_stack[c->jmp_stack_p++] = c->mem_len;
236-}
237-
238-static void word_until
239-(Cotton *c)
240-{
241-	int loop_back = c->jmp_stack[--c->jmp_stack_p];
242-
243-	c->mem[c->mem_len++] = OP_FJMP;
244-	c->mem[c->mem_len++] = loop_back;
245-}
246-
247-static Word immediates[] = {
248-    {"if", word_if},
249-    {"else", word_else},
250-    {"end", word_end},
251-    {"loop", word_loop},
252-    {"until", word_until},
253-    {NULL, NULL}
254-};
255-
256-/* Another comment just so i can separate the immediates from the compiler and runtime functions blehhhhhh
257-words words words words more words SO many words OH MY GOD THERE ARE SO MANY WORDS WORDS WORDS WORDS AAAAAA*/
258-
259-// i feel like the compiler's a bit messy atm but i suppose this is yet another thing i shall revise when i eventually split the interpreter :P
260 void cotton_compile
261 (Cotton *c, char *line)
262 {
263     line[strcspn(line, "\r\n")] = 0;
264     if (line[0] == '\0' || (line[0] == '/' && line[1] == '/')) return;
265 
266-// this part of the compiling process is just for cotton to find strings 
267+	// this part of the compiling process is just for cotton to find strings 
268 
269     int i = 0;
270 
271@@ -309,7 +68,7 @@ void cotton_compile
272         }
273 
274 
275-// now it resumes to it's usual "reading words character by character" behaviour :P
276+		// now it resumes to it's usual "reading words character by character" behaviour :P
277 
278         else {
279             
280@@ -321,7 +80,7 @@ void cotton_compile
281             }
282             
283             // Here i just terminate the token temporarily
284-            char temp = line[i];
285+			char temp = line[i];
286             line[i] = '\0';
287             
288             char *tok = line + tok_start;
R src/interpreter.h => src/loom.h
+2, -2
1@@ -1,5 +1,5 @@
2-#ifndef INTERPRETER_H
3-#define INTERPRETER_H
4+#ifndef LOOM_H
5+#define LOOM_H
6 
7 #include "cotton.h"
8 
+1, -1
1@@ -1,5 +1,5 @@
2 #include "cotton.h"
3-#include "interpreter.h"
4+#include "loom.h"
5 #include <stdio.h>
6 
7 int main
+247, -0
  1@@ -0,0 +1,247 @@
  2+#include "weave.h"
  3+#include "cotton.h"
  4+#include <stdio.h>
  5+
  6+void cog_add
  7+(Cotton *c)
  8+{
  9+	int b = pop(c);
 10+    int a = pop(c);
 11+
 12+    push(c, a + b);
 13+}
 14+
 15+void cog_sub
 16+(Cotton *c)
 17+{
 18+    int b = pop(c);
 19+    int a = pop(c);
 20+
 21+    push(c, a - b);
 22+}
 23+
 24+void cog_mul
 25+(Cotton *c)
 26+{
 27+    int b = pop(c);
 28+    int a = pop(c);
 29+
 30+    push(c, a * b);
 31+}
 32+
 33+void cog_div
 34+(Cotton *c)
 35+{
 36+    int b = pop(c);
 37+    int a = pop(c);
 38+
 39+    // Now, i doubt anyone will really be dividing stuff by zero but you never know.., talk about le safety amirite.., heh 
 40+    if (b == 0) {
 41+
 42+        fprintf(stderr, "cotton: you cant divide by zero, you dummy :P\n");
 43+        return;
 44+    }
 45+
 46+    push(c, a / b);
 47+}
 48+
 49+void cog_dotnum
 50+(Cotton *c)
 51+{
 52+	printf("%d\n", pop(c));
 53+}
 54+
 55+void cog_dotstr
 56+(Cotton *c)
 57+{ 
 58+    int ptr = pop(c);
 59+
 60+    while (c->mem[ptr] != '\0') {
 61+
 62+        printf("%c", c->mem[ptr]);
 63+
 64+        ptr++;
 65+    }
 66+
 67+	printf("\n");
 68+}
 69+
 70+// while forth does use ! and @, im quirky and #notlikeothergirls so im changing ! to -> bc i think it makes more sense :P
 71+void cog_store
 72+(Cotton *c)
 73+{
 74+    int slot = pop(c);
 75+    int num = pop(c);
 76+
 77+    if (slot >= 0 && slot < VARS_SIZE) {
 78+
 79+        c->vars[slot] = num;
 80+    } 
 81+
 82+    else {
 83+
 84+        fprintf(stderr, "cotton: i tried to store somewhere that don't exist,, its in the void now.., :(\n");
 85+    }
 86+}
 87+
 88+void cog_fetch
 89+(Cotton *c)
 90+{
 91+    int slot = pop(c);
 92+
 93+    if (slot >= 0 && slot < VARS_SIZE) {
 94+
 95+ 		push(c, c->vars[slot]);
 96+    } 
 97+
 98+    else {
 99+
100+        fprintf(stderr, "cotton: i tried to fetch from somewhere that seemingly don't exist,, erm.,.\n");
101+    }
102+}
103+
104+void cog_dup
105+(Cotton *c)
106+{
107+    int a = pop(c);
108+
109+    push(c, a);
110+    push(c, a);
111+}
112+
113+void cog_drop
114+(Cotton *c)
115+{
116+    pop(c);
117+}
118+
119+void cog_swap
120+(Cotton *c)
121+{
122+    int b = pop(c);
123+    int a = pop(c);
124+
125+    push(c, b);
126+    push(c, a);
127+}
128+
129+void cog_equal
130+(Cotton *c)
131+{
132+    int b = pop(c);
133+    int a = pop(c);
134+
135+    push(c, a == b ? 1 : 0);
136+}
137+
138+void cog_lssr
139+(Cotton *c)
140+{
141+    int b = pop(c);
142+    int a = pop(c);
143+
144+    push(c, a < b ? 1 : 0);
145+}
146+
147+void cog_grtr
148+(Cotton *c)
149+{
150+    int b = pop(c);
151+    int a = pop(c);
152+
153+    push(c, a > b ? 1 : 0);
154+}
155+
156+Cog builtins[] = {
157+    {"+", cog_add},
158+    {"-", cog_sub},
159+    {"*", cog_mul},
160+    {"/", cog_div},
161+    {".n", cog_dotnum},
162+	{".s", cog_dotstr}, 
163+    {"->", cog_store},
164+    {"@", cog_fetch},
165+    {"dup", cog_dup},
166+    {"drop", cog_drop},
167+    {"swap", cog_swap},
168+    {"=", cog_equal},
169+    {"<", cog_lssr},
170+    {">", cog_grtr},
171+    {NULL, NULL}
172+};
173+
174+/*
175+
176+ separator comment to split the builtins from immediates xP
177+
178+*/
179+
180+void cog_if
181+(Cotton *c)
182+{
183+    if (c->jmp_stack_p >= JMP_STACK_SIZE) {
184+
185+        fprintf(stderr, "cotton: there are too many nested ifs, calm down!! D:\n");
186+        return;
187+    }
188+
189+    c->mem[c->mem_len++] = OP_FJMP;
190+    c->jmp_stack[c->jmp_stack_p++] = c->mem_len;
191+    c->mem[c->mem_len++] = 0;
192+}
193+
194+void cog_else
195+(Cotton *c)
196+{
197+    if (c->jmp_stack_p <= 0) {
198+
199+        fprintf(stderr, "cotton: i found an else without an if,., where'd that come from??\n");
200+        return;
201+    }
202+
203+    int if_target = c->jmp_stack[--c->jmp_stack_p];
204+
205+    c->mem[c->mem_len++] = OP_JMP;
206+    c->jmp_stack[c->jmp_stack_p++] = c->mem_len;
207+    c->mem[c->mem_len++] = 0;
208+
209+    c->mem[if_target] = c->mem_len;
210+}
211+
212+void cog_end
213+(Cotton *c)
214+{
215+    if (c->jmp_stack_p <= 0) {
216+
217+        fprintf(stderr, "cotton: i found an end without an if,., where'd that come from??\n");
218+        return;
219+    }
220+
221+    int target = c->jmp_stack[--c->jmp_stack_p];
222+    c->mem[target] = c->mem_len;
223+}
224+
225+void cog_loop
226+(Cotton *c)
227+{
228+	c->jmp_stack[c->jmp_stack_p++] = c->mem_len;
229+}
230+
231+void cog_until
232+(Cotton *c)
233+{
234+	int loop_back = c->jmp_stack[--c->jmp_stack_p];
235+
236+	c->mem[c->mem_len++] = OP_FJMP;
237+	c->mem[c->mem_len++] = loop_back;
238+}
239+
240+Cog immediates [] = {
241+    {"if", cog_if},
242+    {"else", cog_else},
243+    {"end", cog_end},
244+    {"loop", cog_loop},
245+    {"until", cog_until},
246+    {NULL, NULL}
247+};
248+
+9, -0
 1@@ -0,0 +1,9 @@
 2+#ifndef WEAVE_H
 3+#define WEAVE_H
 4+
 5+#include "cotton.h"
 6+
 7+extern Cog builtins[];
 8+extern Cog immediates[];
 9+
10+#endif