1#include "interpreter.h"
2#include "cotton.h"
3#include <stdio.h>
4
5void cog_add
6(Cotton *c)
7{
8 int b = pop(c);
9 int a = pop(c);
10
11 push(c, a + b);
12}
13
14void cog_sub
15(Cotton *c)
16{
17 int b = pop(c);
18 int a = pop(c);
19
20 push(c, a - b);
21}
22
23void cog_mul
24(Cotton *c)
25{
26 int b = pop(c);
27 int a = pop(c);
28
29 push(c, a * b);
30}
31
32void cog_div
33(Cotton *c)
34{
35 int b = pop(c);
36 int a = pop(c);
37
38 // Now, i doubt anyone will really be dividing stuff by zero but you never know.., talk about le safety amirite.., heh
39 if (b == 0) {
40
41 fprintf(stderr, "cotton: you cant divide by zero, you dummy :P\n");
42 return;
43 }
44
45 push(c, a / b);
46}
47
48void cog_mod
49(Cotton *c)
50{
51 int b = pop(c);
52 int a = pop(c);
53
54 push(c, a % b);
55}
56
57void cog_dotnum
58(Cotton *c)
59{
60 printf("%d\n", pop(c));
61}
62
63void cog_dotstr
64(Cotton *c)
65{
66 int ptr = pop(c);
67
68 while (c->mem[ptr] != '\0') {
69
70 printf("%c", c->mem[ptr]);
71 ptr++;
72 }
73}
74
75// im aware c goes unused here and hence this gives a warning, yes im lazy, might do smth about it another time
76void cog_newline
77(Cotton *c)
78{
79 printf("\n");
80}
81
82// while forth does use ! and @, im quirky and #notlikeothergirls so im changing ! to -> bc i think it makes more sense :P
83void cog_store
84(Cotton *c)
85{
86 int slot = pop(c);
87 int num = pop(c);
88
89 if (slot >= 0 && slot < VARS_SIZE) {
90
91 c->vars[slot] = num;
92 }
93
94 else {
95
96 fprintf(stderr, "cotton: i tried to store somewhere that don't exist,, its in the void now.., :(\n");
97 }
98}
99
100void cog_fetch
101(Cotton *c)
102{
103 int slot = pop(c);
104
105 if (slot >= 0 && slot < VARS_SIZE) {
106
107 push(c, c->vars[slot]);
108 }
109
110 else {
111
112 fprintf(stderr, "cotton: i tried to fetch from somewhere that seemingly don't exist,, erm.,.\n");
113 }
114}
115
116void cog_dup
117(Cotton *c)
118{
119 int a = pop(c);
120
121 push(c, a);
122 push(c, a);
123}
124
125void cog_drop
126(Cotton *c)
127{
128 pop(c);
129}
130
131void cog_swap
132(Cotton *c)
133{
134 int b = pop(c);
135 int a = pop(c);
136
137 push(c, b);
138 push(c, a);
139}
140
141void cog_rotate
142(Cotton *c)
143{
144 int a = pop(c);
145 int b = pop(c);
146 int c_ = pop(c);
147
148 push(c, b);
149 push(c, c_);
150 push(c, a);
151}
152
153void cog_equal
154(Cotton *c)
155{
156 int b = pop(c);
157 int a = pop(c);
158
159 push(c, a == b ? 1 : 0);
160}
161
162void cog_lssr
163(Cotton *c)
164{
165 int b = pop(c);
166 int a = pop(c);
167
168 push(c, a < b ? 1 : 0);
169}
170
171void cog_grtr
172(Cotton *c)
173{
174 int b = pop(c);
175 int a = pop(c);
176
177 push(c, a > b ? 1 : 0);
178}
179
180Cog builtins[] = {
181 {"+", cog_add},
182 {"-", cog_sub},
183 {"*", cog_mul},
184 {"/", cog_div},
185 {"%", cog_mod},
186 {".n", cog_dotnum},
187 {".s", cog_dotstr},
188 {"nl", cog_newline},
189 {"->", cog_store},
190 {"@", cog_fetch},
191 {"dup", cog_dup},
192 {"drop", cog_drop},
193 {"swap", cog_swap},
194 {"rot", cog_rotate},
195 {"=", cog_equal},
196 {"<", cog_lssr},
197 {">", cog_grtr},
198 {NULL, NULL}
199};
200
201/*
202
203 separator comment to split the builtins from immediates xP
204
205*/
206
207void cog_if
208(Cotton *c)
209{
210 if (c->jmp_stack_p >= JMP_STACK_SIZE) {
211
212 fprintf(stderr, "cotton: there are too many nested ifs, calm down!! D:\n");
213 return;
214 }
215
216 c->mem[c->mem_len++] = OP_FJMP;
217 c->jmp_stack[c->jmp_stack_p++] = c->mem_len;
218 c->mem[c->mem_len++] = 0;
219}
220
221void cog_else
222(Cotton *c)
223{
224 if (c->jmp_stack_p <= 0) {
225
226 fprintf(stderr, "cotton: i found an else without an if,., where'd that come from??\n");
227 return;
228 }
229
230 int if_target = c->jmp_stack[--c->jmp_stack_p];
231
232 c->mem[c->mem_len++] = OP_JMP;
233 c->jmp_stack[c->jmp_stack_p++] = c->mem_len;
234 c->mem[c->mem_len++] = 0;
235
236 c->mem[if_target] = c->mem_len;
237}
238
239void cog_end
240(Cotton *c)
241{
242 if (c->jmp_stack_p <= 0) {
243
244 fprintf(stderr, "cotton: i found an end without an if,., where'd that come from??\n");
245 return;
246 }
247
248 int target = c->jmp_stack[--c->jmp_stack_p];
249 c->mem[target] = c->mem_len;
250}
251
252void cog_loop
253(Cotton *c)
254{
255 c->jmp_stack[c->jmp_stack_p++] = c->mem_len;
256}
257
258void cog_until
259(Cotton *c)
260{
261 int loop_back = c->jmp_stack[--c->jmp_stack_p];
262
263 c->mem[c->mem_len++] = OP_FJMP;
264 c->mem[c->mem_len++] = loop_back;
265}
266
267Cog immediates [] = {
268 {"if", cog_if},
269 {"else", cog_else},
270 {"end", cog_end},
271 {"loop", cog_loop},
272 {"until", cog_until},
273 {NULL, NULL}
274};