feat: add return_flag and params_start for proper function return handling and parameter scanning

Implement a dedicated return_flag variable to replace the magic number -999 for return statements, enabling correct early exit from nested blocks. Add params_start field to Func struct to track parameter declaration positions, allowing the interpreter to properly map function arguments to local variables during function calls. Extend the test suite with new test files for arrays, comparison operators, logical operators, pointers, functions, trigonometry, and file seek operations, along with corresponding Makefile targets to execute them.
This commit is contained in:
2025-11-23 14:07:19 +00:00
parent 79a06a0be8
commit d669b1da3d
12 changed files with 571 additions and 7 deletions
+1
View File
@@ -16,3 +16,4 @@ char *src_code;
char str_pool[STR_POOL_SIZE];
int str_pool_idx = 0;
long ax = 0;
int return_flag = 0;
+6 -5
View File
@@ -73,7 +73,7 @@ void statement() {
pc++;
while (pc < MAX_TOK && pc < tk_idx && tokens[pc].type != '}' && tokens[pc].type != 0) {
statement();
if (ax == -999 || ax == -998 || ax == -997) {
if (return_flag || ax == -998 || ax == -997) {
int brace = 1;
while (brace > 0 && pc < MAX_TOK && pc < tk_idx && tokens[pc].type != 0) {
if (tokens[pc].type == '{') brace++;
@@ -139,14 +139,14 @@ void statement() {
match(')');
if (cond) {
statement();
if (ax == -999 || ax == -998 || ax == -997) return;
if (return_flag || ax == -998 || ax == -997) 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 || ax == -998 || ax == -997) return;
if (return_flag || ax == -998 || ax == -997) return;
}
}
}
@@ -169,7 +169,7 @@ void statement() {
}
body_start = pc;
statement();
if (ax == -999) return;
if (return_flag) return;
if (ax == -998) {
ax = 0;
pc = body_start;
@@ -186,7 +186,7 @@ void statement() {
if (pc < MAX_TOK && pc < tk_idx && tokens[pc].type != ';') ax = expression();
else ax = 0;
match(';');
ax = -999;
return_flag = 1;
}
else if (tokens[pc].type == Break) {
pc++;
@@ -253,6 +253,7 @@ void scan_functions() {
strncpy(f->name, name->text, name->val); f->name[name->val] = 0;
i += 3;
f->params_start = i;
int params = 0;
while(i < MAX_TOK && i < tk_idx && tokens[i].type != ')') {
if (tokens[i].type == Int || tokens[i].type == Char || tokens[i].type == Double) {
+34 -1
View File
@@ -78,9 +78,9 @@ long factor() {
int f_idx = find_func(t->text, t->val);
if (f_idx == -1) error("Unknown function");
if (f_idx < 0 || f_idx >= func_cnt) return 0;
int call_pc = pc;
pc += 2;
int old_bp = bp;
long args[10];
int argc = 0;
@@ -95,25 +95,58 @@ long factor() {
match(')');
int ret_pc = pc;
int old_loc_cnt = loc_cnt;
int old_bp = bp;
if (sp >= MEM_SIZE) return 0;
if (bp < 0 || bp >= MEM_SIZE) return 0;
memory[sp] = bp; bp = sp++;
if (sp >= MEM_SIZE) return 0;
memory[sp++] = ret_pc;
memory[sp++] = old_loc_cnt;
int param_base = sp;
for(int i=0; i<argc; i++) {
if (sp >= MEM_SIZE) break;
memory[sp++] = args[i];
}
int scan_pc = funcs[f_idx].params_start;
int param_idx = 0;
while (scan_pc < MAX_TOK && scan_pc < tk_idx && tokens[scan_pc].type != ')') {
if (tokens[scan_pc].type == Int || tokens[scan_pc].type == Char || tokens[scan_pc].type == Double) {
scan_pc++;
while (scan_pc < MAX_TOK && tokens[scan_pc].type == '*') scan_pc++;
if (scan_pc < MAX_TOK && tokens[scan_pc].type == Id && param_idx < argc && loc_cnt < VAR_MAX) {
Token *param_name = &tokens[scan_pc];
Symbol *sym = &locals[loc_cnt++];
int name_len = param_name->val;
if (name_len > 31) name_len = 31;
strncpy(sym->name, param_name->text, name_len);
sym->name[name_len] = 0;
sym->type = Int;
sym->addr = param_base + param_idx;
sym->is_array = 0;
param_idx++;
}
}
scan_pc++;
}
pc = funcs[f_idx].entry_point;
return_flag = 0;
statement();
val = ax;
ax = 0;
return_flag = 0;
loc_cnt = old_loc_cnt;
if (bp < 0 || bp >= MEM_SIZE) return 0;
sp = bp;
if (sp < 0 || sp >= MEM_SIZE) return 0;
bp = memory[sp];
if (sp + 1 < MEM_SIZE) ret_pc = memory[sp + 1];
pc = ret_pc;
return val;
}
+2
View File
@@ -30,6 +30,7 @@ typedef struct {
char name[32];
int entry_point;
int param_count;
int params_start;
} Func;
typedef long (*NativeFunc)(long*, int);
@@ -55,5 +56,6 @@ extern char *src_code;
extern char str_pool[STR_POOL_SIZE];
extern int str_pool_idx;
extern long ax;
extern int return_flag;
#endif