201 lines
5.1 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) {
printf("Error at token %d ('%c'): %s\n", pc, tokens[pc].type, msg);
exit(1);
}
void match(int type) {
if (tokens[pc].type == type) pc++;
else error("Unexpected token");
}
int find_local(char *name, int len) {
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) {
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) {
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 (tokens[pc].type == '{') brace++;
if (tokens[pc].type == '}') brace--;
pc++;
} while (brace > 0 && tokens[pc].type != 0);
}
void statement() {
if (tokens[pc].type == '{') {
pc++;
while (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 (tokens[pc].type != ';') {
while (tokens[pc].type == '*') pc++;
Token *t = &tokens[pc];
match(Id);
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 (tokens[pc].type == '[') {
pc++;
int size = (int)expression();
match(']');
s->is_array = 1;
sp += size;
} else {
sp++;
}
if (tokens[pc].type == '=') {
pc++;
memory[addr] = expression();
}
if (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 (tokens[pc].type == Else) { pc++; skip_block(); }
} else {
skip_block();
if (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 {
while (1) {
statement();
if (ax == -999) return;
int save_pc = pc;
pc = loop_start;
match('(');
cond = expression();
match(')');
if (!cond) { pc = save_pc; break; }
}
}
}
else if (tokens[pc].type == Return) {
pc++;
if (tokens[pc].type != ';') ax = expression();
else ax = 0;
match(';');
ax = -999;
}
else if (tokens[pc].type == Printf) {
pc++;
match('(');
char *fmt = tokens[pc].text;
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') printf("%s", (char*)val);
p++;
} else {
putchar(*p++);
}
}
match(')');
match(';');
}
else {
expression();
match(';');
}
}
void scan_functions() {
int i = 0;
while (tokens[i].type != 0) {
if ((tokens[i].type == Int || tokens[i].type == Char) &&
tokens[i+1].type == Id && tokens[i+2].type == '(') {
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(tokens[i].type != ')') {
if (tokens[i].type == Int || tokens[i].type == Char) {
params++;
i++;
while (tokens[i].type == '*') i++;
if (tokens[i].type == Id) i++;
} else i++;
}
f->param_count = params;
i++;
f->entry_point = i;
int brace = 0;
do {
if (tokens[i].type == '{') brace++;
if (tokens[i].type == '}') brace--;
i++;
} while (brace > 0 && tokens[i].type != 0);
} else {
i++;
}
}
}