1/* I eventually need to split this file before it gets too big, i'll keep this comment here as a mental reminder,.,
2ooooo get off your ass dani ooooo go work ooooo dani you're a bum oooooo oooooo you suckkk oooooooo,., sorry me.., */
3
4// FUTURE DANI HERE !!! I DID IT !!! I GOT OFF MY LAZY ASS !!! RAGHHHHHHHHHHHHHH
5
6#include "cotton.h"
7#include "interpreter.h"
8#include "cogs.h"
9#include <stdio.h>
10#include <stdlib.h>
11#include <string.h>
12#include <ctype.h>
13
14void cotton_compile
15(Cotton *c, char *line)
16{
17 line[strcspn(line, "\r\n")] = 0;
18 if (line[0] == '\0' || (line[0] == '-' && line[1] == '-')) return; // i like lua's comments, i think they'd fit cot better than C's
19
20 // this part of the compiling process is just for cotton to find strings
21
22 int i = 0;
23
24 while (line[i] != '\0') {
25
26 if (c->mem_len >= MEM_SIZE - 2) {
27
28 fprintf(stderr, "cotton: i have ran out of memory,., can't compile anymore :<\n");
29 return;
30 }
31
32 if (line[i] == ' ') {
33
34 i++;
35 }
36
37 else if (line[i] == '"') {
38
39 int string_start = i + 1;
40
41 for (i = string_start; line[i] != '\0'; i++) {
42
43 if (line[i] == '"') {
44
45 line[i] = '\0';
46 break;
47 }
48
49 else if (line[i] == '\0') {
50
51 fprintf(stderr, "cotton: you forgot to close a string.,. i cant compile the file until you fix it :P");
52 return;
53 }
54
55 }
56
57 c->mem[c->mem_len++] = OP_PUSH_STR;
58
59 for (int j = string_start; line[j] != '\0'; j++) {
60
61 c->mem[c->mem_len++] = line[j];
62 }
63
64 c->mem[c->mem_len++] = '\0';
65
66 i++;
67 }
68
69
70 // now it resumes to it's usual "reading words character by character" behaviour :P
71
72 else {
73
74 int tok_start = i;
75
76 while (line[i] != ' ' && line[i] != '\0') {
77
78 i++;
79 }
80
81 // Here i just terminate the token temporarily
82 char temp = line[i];
83 line[i] = '\0';
84
85 char *tok = line + tok_start;
86
87 /* This is subjective to change but i thought that using ? for conditionals so stuff reads out as
88 "is this happening? if so, then, blah blah blah" was a good idea, atleast sounded good in my head :P*/
89
90 if (strcmp(tok, "?") == 0) {
91 // oh yeah, also, this doesn't really do anything, its just here to make if statements look nicer x3
92 }
93
94 else {
95
96 int found_immediate = 0;
97
98 for (int j = 0; immediates[j].name != NULL; j++) {
99
100 if (strcmp(tok, immediates[j].name) == 0) {
101
102 immediates[j].code(c);
103 found_immediate = 1;
104 break;
105 }
106 }
107
108 if (!found_immediate) {
109
110 int is_num = 1;
111
112 for (int j = 0; tok[j]; j++) {
113
114 if (!isdigit(tok[j]) && !(j == 0 && tok[j] == '-' && tok[1] != '\0')) {
115
116 is_num = 0;
117 break;
118 }
119 }
120
121 if (is_num) {
122
123 c->mem[c->mem_len++] = OP_PUSH;
124 c->mem[c->mem_len++] = atoi(tok);
125 }
126
127 else {
128
129 int found = 0;
130
131 for (int j = 0; builtins[j].name != NULL; j++) {
132
133 if (strcmp(tok, builtins[j].name) == 0) {
134
135 c->mem[c->mem_len++] = OP_CALL;
136 c->mem[c->mem_len++] = j;
137 found = 1;
138 break;
139 }
140 }
141
142 if (!found) {
143
144 fprintf(stderr, "cotton: sorry, i don't know what \"%s\" means :(\n", tok);
145 }
146 }
147 }
148 }
149
150 // now i just add this back so that the outer loop doesn't get kirkified broken heart emoji
151 line[i] = temp;
152 }
153 }
154}
155
156void cotton_run
157(Cotton *c)
158{
159 c->instruct_p = 0;
160
161 while (c->instruct_p < c->mem_len) {
162
163 int op = c->mem[c->instruct_p++];
164
165 switch (op) {
166
167 case OP_PUSH:
168
169 push(c, c->mem[c->instruct_p++]);
170 break;
171
172 case OP_CALL: {
173
174 int id = c->mem[c->instruct_p++];
175 builtins[id].code(c);
176 break;
177 }
178
179 case OP_JMP: {
180
181 c->instruct_p = c->mem[c->instruct_p];
182 break;
183 }
184
185 case OP_FJMP: {
186
187 int target = c->mem[c->instruct_p++];
188
189 if (pop(c) == 0) {
190
191 c->instruct_p = target;
192 }
193
194 break;
195 }
196
197 case OP_PUSH_STR:
198
199 push(c, c->instruct_p);
200
201 while (c->mem[c->instruct_p] != '\0') {
202
203 c->instruct_p++;
204 }
205
206 c->instruct_p++;
207 break;
208
209 case OP_KILL:
210
211 return;
212
213 }
214 }
215}