main soggy/cotton / src / interpreter.c
  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}