255 lines
7.7 KiB
C
Raw Normal View History

2025-11-22 22:22:43 +01:00
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "types.h"
#include "interpreter.h"
#include "parser.h"
void error(char *msg) {
2025-11-22 23:15:15 +01:00
if (pc >= 0 && pc < MAX_TOK && pc < tk_idx) {
printf("Error at token %d ('%c'): %s\n", pc, tokens[pc].type, msg);
} else {
printf("Error at token %d: %s\n", pc, msg);
}
2025-11-22 22:22:43 +01:00
exit(1);
}
void match(int type) {
2025-11-22 23:15:15 +01:00
if (pc >= MAX_TOK || pc >= tk_idx) {
error("Token index out of bounds in match");
}
2025-11-22 22:22:43 +01:00
if (tokens[pc].type == type) pc++;
else error("Unexpected token");
}
int find_local(char *name, int len) {
2025-11-22 23:15:15 +01:00
if (!name || len < 0 || len >= 32) return -1;
if (loc_cnt > VAR_MAX) loc_cnt = VAR_MAX;
2025-11-22 22:22:43 +01:00
for (int i = loc_cnt - 1; i >= 0; i--) {
if (!strncmp(locals[i].name, name, len) && locals[i].name[len] == 0)
return i;
}
return -1;
}
int find_func(char *name, int len) {
2025-11-22 23:15:15 +01:00
if (!name || len < 0 || len >= 32) return -1;
if (func_cnt > 100) func_cnt = 100;
2025-11-22 22:22:43 +01:00
for (int i = 0; i < func_cnt; i++) {
if (!strncmp(funcs[i].name, name, len) && funcs[i].name[len] == 0)
return i;
}
return -1;
}
int find_native_func(char *name, int len) {
2025-11-22 23:15:15 +01:00
if (!name || len < 0 || len >= 32) return -1;
if (native_func_cnt > 100) native_func_cnt = 100;
2025-11-22 22:22:43 +01:00
for (int i = 0; i < native_func_cnt; i++) {
if (!strncmp(native_funcs[i].name, name, len) && native_funcs[i].name[len] == 0)
return i;
}
return -1;
}
void skip_block() {
int brace = 0;
do {
2025-11-22 23:15:15 +01:00
if (pc >= MAX_TOK || pc >= tk_idx) {
error("Token index out of bounds in skip_block");
}
2025-11-22 22:22:43 +01:00
if (tokens[pc].type == '{') brace++;
if (tokens[pc].type == '}') brace--;
pc++;
2025-11-22 23:15:15 +01:00
} while (brace > 0 && pc < MAX_TOK && pc < tk_idx && tokens[pc].type != 0);
2025-11-22 22:22:43 +01:00
}
void statement() {
2025-11-22 23:15:15 +01:00
if (pc >= MAX_TOK || pc >= tk_idx) {
error("Token index out of bounds in statement");
}
2025-11-22 22:22:43 +01:00
if (tokens[pc].type == '{') {
pc++;
2025-11-22 23:15:15 +01:00
while (pc < MAX_TOK && pc < tk_idx && tokens[pc].type != '}' && tokens[pc].type != 0) {
2025-11-22 22:22:43 +01:00
statement();
if (ax == -999) break;
}
match('}');
}
else if (tokens[pc].type == Int || tokens[pc].type == Char) {
pc++;
2025-11-22 23:15:15 +01:00
while (pc < MAX_TOK && pc < tk_idx && tokens[pc].type != ';') {
while (pc < MAX_TOK && pc < tk_idx && tokens[pc].type == '*') pc++;
if (pc >= MAX_TOK || pc >= tk_idx) break;
2025-11-22 22:22:43 +01:00
Token *t = &tokens[pc];
match(Id);
2025-11-22 23:15:15 +01:00
if (loc_cnt >= VAR_MAX) {
error("Too many local variables");
}
if (sp >= MEM_SIZE) {
error("Stack overflow");
}
2025-11-22 22:22:43 +01:00
int addr = sp;
Symbol *s = &locals[loc_cnt++];
strncpy(s->name, t->text, t->val); s->name[t->val] = 0;
s->addr = addr;
s->is_array = 0;
2025-11-22 23:15:15 +01:00
if (pc < MAX_TOK && pc < tk_idx && tokens[pc].type == '[') {
2025-11-22 22:22:43 +01:00
pc++;
int size = (int)expression();
match(']');
s->is_array = 1;
2025-11-22 23:15:15 +01:00
if (sp + size >= MEM_SIZE) {
error("Stack overflow during array allocation");
}
2025-11-22 22:22:43 +01:00
sp += size;
} else {
sp++;
}
2025-11-22 23:15:15 +01:00
if (pc < MAX_TOK && pc < tk_idx && tokens[pc].type == '=') {
2025-11-22 22:22:43 +01:00
pc++;
2025-11-22 23:15:15 +01:00
if (addr >= 0 && addr < MEM_SIZE) {
memory[addr] = expression();
} else {
error("Memory access out of bounds");
}
2025-11-22 22:22:43 +01:00
}
2025-11-22 23:15:15 +01:00
if (pc < MAX_TOK && pc < tk_idx && tokens[pc].type == ',') pc++;
2025-11-22 22:22:43 +01:00
}
match(';');
}
else if (tokens[pc].type == If) {
pc++;
match('(');
long cond = expression();
match(')');
if (cond) {
statement();
if (ax == -999) return;
2025-11-22 23:15:15 +01:00
if (pc < MAX_TOK && pc < tk_idx && tokens[pc].type == Else) { pc++; skip_block(); }
2025-11-22 22:22:43 +01:00
} else {
skip_block();
2025-11-22 23:15:15 +01:00
if (pc < MAX_TOK && pc < tk_idx && tokens[pc].type == Else) {
2025-11-22 22:22:43 +01:00
pc++;
statement();
if (ax == -999) return;
}
}
}
else if (tokens[pc].type == While) {
pc++;
int loop_start = pc;
match('(');
long cond = expression();
match(')');
if (!cond) {
skip_block();
} else {
2025-11-22 23:15:15 +01:00
int iteration_count = 0;
2025-11-22 22:22:43 +01:00
while (1) {
2025-11-22 23:15:15 +01:00
if (++iteration_count > 1000000) {
error("Potential infinite loop detected");
}
2025-11-22 22:22:43 +01:00
statement();
if (ax == -999) return;
int save_pc = pc;
2025-11-22 23:15:15 +01:00
if (loop_start >= MAX_TOK || loop_start >= tk_idx) {
error("Loop start out of bounds");
}
2025-11-22 22:22:43 +01:00
pc = loop_start;
match('(');
cond = expression();
match(')');
if (!cond) { pc = save_pc; break; }
}
}
}
else if (tokens[pc].type == Return) {
pc++;
2025-11-22 23:15:15 +01:00
if (pc < MAX_TOK && pc < tk_idx && tokens[pc].type != ';') ax = expression();
2025-11-22 22:22:43 +01:00
else ax = 0;
match(';');
ax = -999;
}
else if (tokens[pc].type == Printf) {
pc++;
match('(');
2025-11-22 23:15:15 +01:00
if (pc >= MAX_TOK || pc >= tk_idx) {
error("Token index out of bounds in printf");
}
2025-11-22 22:22:43 +01:00
char *fmt = tokens[pc].text;
2025-11-22 23:15:15 +01:00
if (!fmt) fmt = "";
2025-11-22 22:22:43 +01:00
match(Str);
char *p = fmt;
while (*p) {
if (*p == '%' && (p[1] == 'd' || p[1] == 's')) {
p++;
match(',');
long val = expression();
if (*p == 'd') printf("%ld", val);
2025-11-22 23:15:15 +01:00
else if (*p == 's') {
char *str = (char*)val;
if (str) printf("%s", str);
}
2025-11-22 22:22:43 +01:00
p++;
} else {
putchar(*p++);
}
}
match(')');
match(';');
}
else {
expression();
match(';');
}
}
void scan_functions() {
int i = 0;
2025-11-22 23:15:15 +01:00
while (i < MAX_TOK && i < tk_idx && tokens[i].type != 0) {
if (i + 2 < MAX_TOK && i + 2 < tk_idx &&
(tokens[i].type == Int || tokens[i].type == Char) &&
2025-11-22 22:22:43 +01:00
tokens[i+1].type == Id && tokens[i+2].type == '(') {
2025-11-22 23:15:15 +01:00
if (func_cnt >= 100) {
error("Too many functions defined");
}
2025-11-22 22:22:43 +01:00
Func *f = &funcs[func_cnt++];
Token *name = &tokens[i+1];
strncpy(f->name, name->text, name->val); f->name[name->val] = 0;
i += 3;
int params = 0;
2025-11-22 23:15:15 +01:00
while(i < MAX_TOK && i < tk_idx && tokens[i].type != ')') {
2025-11-22 22:22:43 +01:00
if (tokens[i].type == Int || tokens[i].type == Char) {
params++;
i++;
2025-11-22 23:15:15 +01:00
while (i < MAX_TOK && i < tk_idx && tokens[i].type == '*') i++;
if (i < MAX_TOK && i < tk_idx && tokens[i].type == Id) i++;
2025-11-22 22:22:43 +01:00
} else i++;
}
f->param_count = params;
2025-11-22 23:15:15 +01:00
if (i < MAX_TOK && i < tk_idx) i++;
2025-11-22 22:22:43 +01:00
f->entry_point = i;
int brace = 0;
do {
2025-11-22 23:15:15 +01:00
if (i >= MAX_TOK || i >= tk_idx) {
error("Token index out of bounds in scan_functions");
}
2025-11-22 22:22:43 +01:00
if (tokens[i].type == '{') brace++;
if (tokens[i].type == '}') brace--;
i++;
2025-11-22 23:15:15 +01:00
} while (brace > 0 && i < MAX_TOK && i < tk_idx && tokens[i].type != 0);
2025-11-22 22:22:43 +01:00
} else {
i++;
}
}
}