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 "loom.h"
8#include "weave.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
47 break;
48 }
49
50 else if (line[i] == '\0') {
51
52 fprintf(stderr, "cotton: you forgot to close a string.,. i cant compile the file until you fix it :P");
53 return;
54 }
55
56 }
57
58 c->mem[c->mem_len++] = OP_PUSH_STR;
59
60 for (int j = string_start; line[j] != '\0'; j++) {
61
62 c->mem[c->mem_len++] = line[j];
63 }
64
65 c->mem[c->mem_len++] = '\0';
66
67 i++;
68 }
69
70
71 // now it resumes to it's usual "reading words character by character" behaviour :P
72
73 else {
74
75 int tok_start = i;
76
77 while (line[i] != ' ' && line[i] != '\0') {
78
79 i++;
80 }
81
82 // Here i just terminate the token temporarily
83 char temp = line[i];
84 line[i] = '\0';
85
86 char *tok = line + tok_start;
87
88 /* This is subjective to change but i thought that using ? for conditionals so stuff reads out as
89 "is this happening? if so, then, blah blah blah" was a good idea, atleast sounded good in my head :P*/
90
91 if (strcmp(tok, "?") == 0) {
92 // oh yeah, also, this doesn't really do anything, its just here to make if statements look nicer x3
93 }
94
95 else {
96
97 int found_immediate = 0;
98
99 for (int j = 0; immediates[j].name != NULL; j++) {
100
101 if (strcmp(tok, immediates[j].name) == 0) {
102
103 immediates[j].code(c);
104 found_immediate = 1;
105 break;
106 }
107 }
108
109 if (!found_immediate) {
110
111 int is_num = 1;
112
113 for (int j = 0; tok[j]; j++) {
114
115 if (!isdigit(tok[j]) && !(j == 0 && tok[j] == '-' && tok[1] != '\0')) {
116
117 is_num = 0;
118 break;
119 }
120 }
121
122 if (is_num) {
123
124 c->mem[c->mem_len++] = OP_PUSH;
125 c->mem[c->mem_len++] = atoi(tok);
126 }
127
128 else {
129
130 int found = 0;
131
132 for (int j = 0; builtins[j].name != NULL; j++) {
133
134 if (strcmp(tok, builtins[j].name) == 0) {
135
136 c->mem[c->mem_len++] = OP_CALL;
137 c->mem[c->mem_len++] = j;
138 found = 1;
139 break;
140 }
141 }
142
143 if (!found) {
144
145 fprintf(stderr, "cotton: sorry, i don't know what \"%s\" means :(\n", tok);
146 }
147 }
148 }
149 }
150
151 // now i just add this back so that the outer loop doesn't get kirkified broken heart emoji
152 line[i] = temp;
153 }
154 }
155}
156
157void cotton_run
158(Cotton *c)
159{
160 c->instruct_p = 0;
161
162 while (c->instruct_p < c->mem_len) {
163
164 int op = c->mem[c->instruct_p++];
165
166 switch (op) {
167
168 case OP_PUSH:
169 push(c, c->mem[c->instruct_p++]);
170
171 break;
172
173 case OP_CALL: {
174 int id = c->mem[c->instruct_p++];
175 builtins[id].code(c);
176
177 break;
178 }
179
180 case OP_JMP: {
181 c->instruct_p = c->mem[c->instruct_p];
182
183 break;
184 }
185
186 case OP_FJMP: {
187
188 int target = c->mem[c->instruct_p++];
189
190 if (pop(c) == 0) {
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 c->instruct_p++;
203 }
204
205 c->instruct_p++;
206
207 break;
208
209 case OP_KILL:
210
211 return;
212
213 }
214 }
215}