#include #include #include #include #include "types.h" #include "interpreter.h" #include "parser.h" void error(char *msg) { 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); } exit(1); } void match(int type) { if (pc >= MAX_TOK || pc >= tk_idx) { error("Token index out of bounds in match"); } if (tokens[pc].type == type) pc++; else error("Unexpected token"); } int find_local(char *name, int len) { if (!name || len < 0 || len >= 32) return -1; if (loc_cnt > VAR_MAX) loc_cnt = VAR_MAX; 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) { if (!name || len < 0 || len >= 32) return -1; if (func_cnt > 100) func_cnt = 100; 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) { if (!name || len < 0 || len >= 32) return -1; if (native_func_cnt > 100) native_func_cnt = 100; 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 { if (pc >= MAX_TOK || pc >= tk_idx) { error("Token index out of bounds in skip_block"); } if (tokens[pc].type == '{') brace++; if (tokens[pc].type == '}') brace--; pc++; } while (brace > 0 && pc < MAX_TOK && pc < tk_idx && tokens[pc].type != 0); } void statement() { if (pc >= MAX_TOK || pc >= tk_idx) { error("Token index out of bounds in statement"); } if (tokens[pc].type == '{') { pc++; while (pc < MAX_TOK && pc < tk_idx && tokens[pc].type != '}' && tokens[pc].type != 0) { statement(); if (ax == -999) break; } match('}'); } else if (tokens[pc].type == Int || tokens[pc].type == Char) { pc++; 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; Token *t = &tokens[pc]; match(Id); if (loc_cnt >= VAR_MAX) { error("Too many local variables"); } if (sp >= MEM_SIZE) { error("Stack overflow"); } 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; if (pc < MAX_TOK && pc < tk_idx && tokens[pc].type == '[') { pc++; int size = (int)expression(); match(']'); s->is_array = 1; if (sp + size >= MEM_SIZE) { error("Stack overflow during array allocation"); } sp += size; } else { sp++; } if (pc < MAX_TOK && pc < tk_idx && tokens[pc].type == '=') { pc++; if (addr >= 0 && addr < MEM_SIZE) { memory[addr] = expression(); } else { error("Memory access out of bounds"); } } if (pc < MAX_TOK && pc < tk_idx && tokens[pc].type == ',') pc++; } match(';'); } else if (tokens[pc].type == If) { pc++; match('('); long cond = expression(); match(')'); if (cond) { statement(); if (ax == -999) return; if (pc < MAX_TOK && pc < tk_idx && tokens[pc].type == Else) { pc++; skip_block(); } } else { skip_block(); if (pc < MAX_TOK && pc < tk_idx && tokens[pc].type == Else) { 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 { int iteration_count = 0; while (1) { if (++iteration_count > 1000000) { error("Potential infinite loop detected"); } statement(); if (ax == -999) return; int save_pc = pc; if (loop_start >= MAX_TOK || loop_start >= tk_idx) { error("Loop start out of bounds"); } pc = loop_start; match('('); cond = expression(); match(')'); if (!cond) { pc = save_pc; break; } } } } else if (tokens[pc].type == Return) { pc++; if (pc < MAX_TOK && pc < tk_idx && tokens[pc].type != ';') ax = expression(); else ax = 0; match(';'); ax = -999; } else if (tokens[pc].type == Printf) { pc++; match('('); if (pc >= MAX_TOK || pc >= tk_idx) { error("Token index out of bounds in printf"); } char *fmt = tokens[pc].text; if (!fmt) fmt = ""; 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); else if (*p == 's') { char *str = (char*)val; if (str) printf("%s", str); } p++; } else { putchar(*p++); } } match(')'); match(';'); } else { expression(); match(';'); } } void scan_functions() { int i = 0; 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) && tokens[i+1].type == Id && tokens[i+2].type == '(') { if (func_cnt >= 100) { error("Too many functions defined"); } 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; while(i < MAX_TOK && i < tk_idx && tokens[i].type != ')') { if (tokens[i].type == Int || tokens[i].type == Char) { params++; i++; while (i < MAX_TOK && i < tk_idx && tokens[i].type == '*') i++; if (i < MAX_TOK && i < tk_idx && tokens[i].type == Id) i++; } else i++; } f->param_count = params; if (i < MAX_TOK && i < tk_idx) i++; f->entry_point = i; int brace = 0; do { if (i >= MAX_TOK || i >= tk_idx) { error("Token index out of bounds in scan_functions"); } if (tokens[i].type == '{') brace++; if (tokens[i].type == '}') brace--; i++; } while (brace > 0 && i < MAX_TOK && i < tk_idx && tokens[i].type != 0); } else { i++; } } }