This commit is contained in:
2025-11-22 23:15:15 +01:00
parent e6d75958c8
commit bd8d9d819e
13 changed files with 417 additions and 42 deletions
+74 -20
View File
@@ -7,16 +7,25 @@
#include "parser.h"
void error(char *msg) {
printf("Error at token %d ('%c'): %s\n", pc, tokens[pc].type, 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;
@@ -25,6 +34,8 @@ int find_local(char *name, int len) {
}
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;
@@ -33,6 +44,8 @@ int find_func(char *name, int len) {
}
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;
@@ -43,16 +56,22 @@ int find_native_func(char *name, int len) {
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 && tokens[pc].type != 0);
} 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 (tokens[pc].type != '}' && tokens[pc].type != 0) {
while (pc < MAX_TOK && pc < tk_idx && tokens[pc].type != '}' && tokens[pc].type != 0) {
statement();
if (ax == -999) break;
}
@@ -60,32 +79,46 @@ void statement() {
}
else if (tokens[pc].type == Int || tokens[pc].type == Char) {
pc++;
while (tokens[pc].type != ';') {
while (tokens[pc].type == '*') 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 (tokens[pc].type == '[') {
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 (tokens[pc].type == '=') {
if (pc < MAX_TOK && pc < tk_idx && tokens[pc].type == '=') {
pc++;
memory[addr] = expression();
if (addr >= 0 && addr < MEM_SIZE) {
memory[addr] = expression();
} else {
error("Memory access out of bounds");
}
}
if (tokens[pc].type == ',') pc++;
if (pc < MAX_TOK && pc < tk_idx && tokens[pc].type == ',') pc++;
}
match(';');
}
@@ -97,10 +130,10 @@ void statement() {
if (cond) {
statement();
if (ax == -999) return;
if (tokens[pc].type == Else) { pc++; skip_block(); }
if (pc < MAX_TOK && pc < tk_idx && tokens[pc].type == Else) { pc++; skip_block(); }
} else {
skip_block();
if (tokens[pc].type == Else) {
if (pc < MAX_TOK && pc < tk_idx && tokens[pc].type == Else) {
pc++;
statement();
if (ax == -999) return;
@@ -116,10 +149,17 @@ void statement() {
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();
@@ -130,7 +170,7 @@ void statement() {
}
else if (tokens[pc].type == Return) {
pc++;
if (tokens[pc].type != ';') ax = expression();
if (pc < MAX_TOK && pc < tk_idx && tokens[pc].type != ';') ax = expression();
else ax = 0;
match(';');
ax = -999;
@@ -138,7 +178,11 @@ void statement() {
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;
@@ -148,7 +192,10 @@ void statement() {
match(',');
long val = expression();
if (*p == 'd') printf("%ld", val);
else if (*p == 's') printf("%s", (char*)val);
else if (*p == 's') {
char *str = (char*)val;
if (str) printf("%s", str);
}
p++;
} else {
putchar(*p++);
@@ -165,34 +212,41 @@ void statement() {
void scan_functions() {
int i = 0;
while (tokens[i].type != 0) {
if ((tokens[i].type == Int || tokens[i].type == Char) &&
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(tokens[i].type != ')') {
while(i < MAX_TOK && i < tk_idx && 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++;
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;
i++;
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 && tokens[i].type != 0);
} while (brace > 0 && i < MAX_TOK && i < tk_idx && tokens[i].type != 0);
} else {
i++;
}
+15 -2
View File
@@ -17,8 +17,15 @@ int main(int argc, char **argv) {
return 1;
}
src_code = malloc(MAX_SRC);
src_code = malloc(MAX_SRC + 1);
if (!src_code) {
printf("Memory allocation failed.\n");
fclose(f);
return 1;
}
size_t n = fread(src_code, 1, MAX_SRC, f);
if (n >= MAX_SRC) n = MAX_SRC - 1;
src_code[n] = 0;
fclose(f);
@@ -28,17 +35,23 @@ int main(int argc, char **argv) {
scan_functions();
int main_idx = find_func("main", 4);
if (main_idx == -1) {
if (main_idx == -1 || main_idx >= func_cnt) {
printf("No main function found.\n");
return 1;
}
pc = funcs[main_idx].entry_point;
if (sp + 2 >= MEM_SIZE) {
printf("Stack overflow during initialization.\n");
return 1;
}
memory[sp++] = 0;
memory[sp++] = 0;
ax = 0;
statement();
free(src_code);
return 0;
}
+181 -5
View File
@@ -12,6 +12,9 @@
#include "interpreter.h"
void register_native_func(char *name, NativeFunc func) {
if (!name || !func || native_func_cnt >= 100) {
return;
}
NativeFuncDef *nf = &native_funcs[native_func_cnt++];
strncpy(nf->name, name, 31);
nf->name[31] = 0;
@@ -19,6 +22,9 @@ void register_native_func(char *name, NativeFunc func) {
}
long native_socket(long *args, int argc) {
if (!args || argc < 3) {
return -1;
}
int domain = (int)args[0];
int type = (int)args[1];
int protocol = (int)args[2];
@@ -26,6 +32,9 @@ long native_socket(long *args, int argc) {
}
long native_bind(long *args, int argc) {
if (!args || argc < 2) {
return -1;
}
int sockfd = (int)args[0];
int port = (int)args[1];
@@ -39,28 +48,46 @@ long native_bind(long *args, int argc) {
}
long native_listen(long *args, int argc) {
if (!args || argc < 2) {
return -1;
}
int sockfd = (int)args[0];
int backlog = (int)args[1];
return listen(sockfd, backlog);
}
long native_accept(long *args, int argc) {
if (!args || argc < 1) {
return -1;
}
int sockfd = (int)args[0];
return accept(sockfd, NULL, NULL);
}
long native_recv(long *args, int argc) {
if (!args || argc < 4) {
return -1;
}
int sockfd = (int)args[0];
int addr = (int)args[1];
int len = (int)args[2];
int flags = (int)args[3];
if (addr < 0 || addr >= MEM_SIZE) {
return -1;
}
char temp_buf[8192];
if (len > 8192) len = 8192;
if (len < 0) len = 0;
if (addr + len > MEM_SIZE) {
len = MEM_SIZE - addr;
}
int result = recv(sockfd, temp_buf, len, flags);
if (result > 0) {
for (int i = 0; i < result; i++) {
for (int i = 0; i < result && addr + i < MEM_SIZE; i++) {
memory[addr + i] = temp_buf[i];
}
}
@@ -68,19 +95,34 @@ long native_recv(long *args, int argc) {
}
long native_send(long *args, int argc) {
if (!args || argc < 4) {
return -1;
}
int sockfd = (int)args[0];
long buf_arg = args[1];
int len = (int)args[2];
int flags = (int)args[3];
if (len < 0) {
return -1;
}
if (buf_arg > MEM_SIZE * 8 || buf_arg < 0) {
return send(sockfd, (char*)buf_arg, len, flags);
}
if (buf_arg >= MEM_SIZE) {
return -1;
}
char temp_buf[8192];
if (len > 8192) len = 8192;
for (int i = 0; i < len; i++) {
if (buf_arg + len > MEM_SIZE) {
len = MEM_SIZE - buf_arg;
}
for (int i = 0; i < len && buf_arg + i < MEM_SIZE; i++) {
temp_buf[i] = (char)memory[buf_arg + i];
}
@@ -88,12 +130,21 @@ long native_send(long *args, int argc) {
}
long native_close(long *args, int argc) {
if (!args || argc < 1) {
return -1;
}
int fd = (int)args[0];
return close(fd);
}
long native_strlen(long *args, int argc) {
if (!args || argc < 1) {
return 0;
}
char *str = (char*)args[0];
if (!str) {
return 0;
}
return strlen(str);
}
@@ -106,40 +157,70 @@ long native_SOCK_STREAM(long *args, int argc) {
}
long native_sqrt(long *args, int argc) {
if (!args || argc < 1) {
return 0;
}
return (long)sqrt((double)args[0]);
}
long native_pow(long *args, int argc) {
if (!args || argc < 2) {
return 0;
}
return (long)pow((double)args[0], (double)args[1]);
}
long native_sin(long *args, int argc) {
if (!args || argc < 1) {
return 0;
}
return (long)(sin((double)args[0]) * 1000000);
}
long native_cos(long *args, int argc) {
if (!args || argc < 1) {
return 0;
}
return (long)(cos((double)args[0]) * 1000000);
}
long native_tan(long *args, int argc) {
if (!args || argc < 1) {
return 0;
}
return (long)(tan((double)args[0]) * 1000000);
}
long native_abs(long *args, int argc) {
if (!args || argc < 1) {
return 0;
}
return (long)abs((int)args[0]);
}
long native_floor(long *args, int argc) {
if (!args || argc < 1) {
return 0;
}
return (long)floor((double)args[0]);
}
long native_ceil(long *args, int argc) {
if (!args || argc < 1) {
return 0;
}
return (long)ceil((double)args[0]);
}
long native_strpos(long *args, int argc) {
if (!args || argc < 2) {
return -1;
}
char *haystack = (char*)args[0];
char *needle = (char*)args[1];
if (!haystack || !needle) {
return -1;
}
char *pos = strstr(haystack, needle);
if (pos) {
return pos - haystack;
@@ -148,20 +229,33 @@ long native_strpos(long *args, int argc) {
}
long native_substr(long *args, int argc) {
static char empty_str[] = "";
if (!args || argc < 3) {
return (long)empty_str;
}
char *str = (char*)args[0];
if (!str) {
return (long)empty_str;
}
int start = (int)args[1];
int length = (int)args[2];
if (str_pool_idx >= STR_POOL_SIZE) {
error("String pool overflow");
return (long)empty_str;
}
char *result = &str_pool[str_pool_idx];
int str_len = strlen(str);
if (start < 0) start = 0;
if (start >= str_len) return (long)"";
if (start >= str_len) return (long)empty_str;
if (start + length > str_len) length = str_len - start;
if (length < 0) return (long)"";
if (length < 0) return (long)empty_str;
if (str_pool_idx + length + 1 >= STR_POOL_SIZE) {
error("String pool overflow");
return (long)empty_str;
}
strncpy(result, str + start, length);
@@ -172,12 +266,26 @@ long native_substr(long *args, int argc) {
}
long native_upper(long *args, int argc) {
static char empty_str[] = "";
if (!args || argc < 1) {
return (long)empty_str;
}
char *str = (char*)args[0];
if (!str) {
return (long)empty_str;
}
if (str_pool_idx >= STR_POOL_SIZE) {
error("String pool overflow");
return (long)empty_str;
}
char *result = &str_pool[str_pool_idx];
int len = strlen(str);
if (str_pool_idx + len + 1 >= STR_POOL_SIZE) {
error("String pool overflow");
return (long)empty_str;
}
for (int i = 0; i <= len; i++) {
@@ -189,12 +297,26 @@ long native_upper(long *args, int argc) {
}
long native_lower(long *args, int argc) {
static char empty_str[] = "";
if (!args || argc < 1) {
return (long)empty_str;
}
char *str = (char*)args[0];
if (!str) {
return (long)empty_str;
}
if (str_pool_idx >= STR_POOL_SIZE) {
error("String pool overflow");
return (long)empty_str;
}
char *result = &str_pool[str_pool_idx];
int len = strlen(str);
if (str_pool_idx + len + 1 >= STR_POOL_SIZE) {
error("String pool overflow");
return (long)empty_str;
}
for (int i = 0; i <= len; i++) {
@@ -206,7 +328,20 @@ long native_lower(long *args, int argc) {
}
long native_strip(long *args, int argc) {
static char empty_str[] = "";
if (!args || argc < 1) {
return (long)empty_str;
}
char *str = (char*)args[0];
if (!str) {
return (long)empty_str;
}
if (str_pool_idx >= STR_POOL_SIZE) {
error("String pool overflow");
return (long)empty_str;
}
char *result = &str_pool[str_pool_idx];
while (*str && isspace(*str)) str++;
@@ -216,6 +351,7 @@ long native_strip(long *args, int argc) {
if (str_pool_idx + len + 1 >= STR_POOL_SIZE) {
error("String pool overflow");
return (long)empty_str;
}
strncpy(result, str, len);
@@ -226,9 +362,21 @@ long native_strip(long *args, int argc) {
}
long native_replace(long *args, int argc) {
static char empty_str[] = "";
if (!args || argc < 3) {
return (long)empty_str;
}
char *str = (char*)args[0];
char *old_str = (char*)args[1];
char *new_str = (char*)args[2];
if (!str || !old_str || !new_str) {
return (long)empty_str;
}
if (str_pool_idx >= STR_POOL_SIZE) {
error("String pool overflow");
return (long)empty_str;
}
char *result = &str_pool[str_pool_idx];
char *src = str;
@@ -236,10 +384,26 @@ long native_replace(long *args, int argc) {
int old_len = strlen(old_str);
int new_len = strlen(new_str);
if (old_len == 0) {
int str_len = strlen(str);
if (str_pool_idx + str_len + 1 >= STR_POOL_SIZE) {
error("String pool overflow");
return (long)empty_str;
}
strcpy(result, str);
str_pool_idx += str_len + 1;
return (long)result;
}
while (*src) {
if (strncmp(src, old_str, old_len) == 0) {
if (str_pool_idx + (dst - result) + new_len + strlen(src + old_len) + 1 >= STR_POOL_SIZE) {
int remaining = strlen(src + old_len);
int current_pos = dst - result;
if (str_pool_idx + current_pos + new_len + remaining + 1 >= STR_POOL_SIZE) {
error("String pool overflow");
*dst = 0;
str_pool_idx += current_pos + 1;
return (long)result;
}
strcpy(dst, new_str);
dst += new_len;
@@ -256,15 +420,27 @@ long native_replace(long *args, int argc) {
}
long native_startswith(long *args, int argc) {
if (!args || argc < 2) {
return 0;
}
char *str = (char*)args[0];
char *prefix = (char*)args[1];
if (!str || !prefix) {
return 0;
}
int prefix_len = strlen(prefix);
return strncmp(str, prefix, prefix_len) == 0;
}
long native_endswith(long *args, int argc) {
if (!args || argc < 2) {
return 0;
}
char *str = (char*)args[0];
char *suffix = (char*)args[1];
if (!str || !suffix) {
return 0;
}
int str_len = strlen(str);
int suffix_len = strlen(suffix);
+57 -9
View File
@@ -27,6 +27,7 @@ extern int find_native_func(char *name, int len);
extern void statement();
long factor() {
if (pc >= MAX_TOK) return 0;
Token *t = &tokens[pc];
long val = 0;
@@ -45,17 +46,22 @@ long factor() {
return val;
}
else if (t->type == Id) {
if (pc + 1 >= MAX_TOK) return 0;
if (tokens[pc + 1].type == '(') {
int nf_idx = find_native_func(t->text, t->val);
if (nf_idx != -1) {
if (nf_idx < 0 || nf_idx >= native_func_cnt) return 0;
pc += 2;
long args[10];
int argc = 0;
if (pc >= MAX_TOK) return 0;
if (tokens[pc].type != ')') {
do {
if (argc >= 10) break;
args[argc++] = expression();
if (pc >= MAX_TOK) return 0;
} while (tokens[pc].type == ',' && pc++);
}
match(')');
@@ -65,30 +71,42 @@ 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;
pc += 2;
int old_bp = bp;
long args[10];
int argc = 0;
if (pc >= MAX_TOK) return 0;
if (tokens[pc].type != ')') {
do {
if (argc >= 10) break;
args[argc++] = expression();
if (pc >= MAX_TOK) return 0;
} while (tokens[pc].type == ',' && pc++);
}
match(')');
int ret_pc = pc;
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;
for(int i=0; i<argc; i++) memory[sp++] = args[i];
for(int i=0; i<argc; i++) {
if (sp >= MEM_SIZE) break;
memory[sp++] = args[i];
}
pc = funcs[f_idx].entry_point;
statement();
val = ax;
if (bp < 0 || bp >= MEM_SIZE) return 0;
sp = bp;
if (sp < 0 || sp >= MEM_SIZE) return 0;
bp = memory[sp];
pc = ret_pc;
return val;
@@ -96,19 +114,23 @@ long factor() {
else {
int idx = find_local(t->text, t->val);
if (idx == -1) error("Undefined variable");
if (idx < 0 || idx >= loc_cnt) return 0;
pc++;
Symbol *sym = &locals[idx];
if (pc >= MAX_TOK) return 0;
if (tokens[pc].type == '[') {
pc++;
long start_or_index = expression();
if (pc >= MAX_TOK) return 0;
if (tokens[pc].type == ':') {
pc++;
long end = expression();
match(']');
if (sym->addr < 0 || sym->addr >= MEM_SIZE) return 0;
long val = memory[sym->addr];
if (is_string_ptr(val)) {
return slice_string(val, start_or_index, end);
@@ -117,7 +139,9 @@ long factor() {
}
} else {
match(']');
return memory[sym->addr + start_or_index];
long addr = sym->addr + start_or_index;
if (addr < 0 || addr >= MEM_SIZE) return 0;
return memory[addr];
}
}
@@ -125,6 +149,7 @@ long factor() {
return sym->addr;
}
if (sym->addr < 0 || sym->addr >= MEM_SIZE) return 0;
return memory[sym->addr];
}
}
@@ -132,20 +157,24 @@ long factor() {
}
long unary() {
if (pc >= MAX_TOK) return 0;
if (tokens[pc].type == '*') {
pc++;
int addr = unary();
if (addr > MEM_SIZE * 8 || addr < 0) {
return *(char*)addr;
}
if (addr < 0 || addr >= MEM_SIZE) return 0;
return memory[addr];
}
else if (tokens[pc].type == '&') {
pc++;
if (pc >= MAX_TOK) return 0;
Token *t = &tokens[pc];
if (t->type != Id) error("Expected identifier after &");
int idx = find_local(t->text, t->val);
if (idx == -1) error("Undefined variable");
if (idx < 0 || idx >= loc_cnt) return 0;
pc++;
return locals[idx].addr;
}
@@ -158,18 +187,21 @@ long unary() {
long term() {
long val = unary();
while (tokens[pc].type == '*' || tokens[pc].type == '/') {
while (pc < MAX_TOK && (tokens[pc].type == '*' || tokens[pc].type == '/')) {
int op = tokens[pc++].type;
long val2 = unary();
if (op == '*') val = val * val2;
else val = val / val2;
else {
if (val2 != 0) val = val / val2;
else val = 0;
}
}
return val;
}
long add() {
long val = term();
while (tokens[pc].type == '+' || tokens[pc].type == '-') {
while (pc < MAX_TOK && (tokens[pc].type == '+' || tokens[pc].type == '-')) {
int op = tokens[pc++].type;
long val2 = term();
if (op == '+') {
@@ -187,7 +219,7 @@ long add() {
long relational() {
long val = add();
while (tokens[pc].type >= Eq && tokens[pc].type <= Ge) {
while (pc < MAX_TOK && tokens[pc].type >= Eq && tokens[pc].type <= Ge) {
int op = tokens[pc++].type;
long val2 = add();
if (op == Eq) val = val == val2;
@@ -199,9 +231,11 @@ long relational() {
}
long expression() {
if (pc >= MAX_TOK) return 0;
if (tokens[pc].type == '*') {
int save_pc = pc;
unary();
if (pc >= MAX_TOK) return 0;
if (tokens[pc].type == '=') {
pc = save_pc;
pc++;
@@ -214,18 +248,23 @@ long expression() {
pc = save_pc;
}
if (pc >= MAX_TOK) return 0;
if (tokens[pc].type == Id) {
if (pc + 1 >= MAX_TOK) return 0;
if (tokens[pc+1].type == '[') {
int idx = find_local(tokens[pc].text, tokens[pc].val);
if (idx == -1) error("Assign to unknown var");
if (idx < 0 || idx >= loc_cnt) return 0;
pc += 2;
long start_or_index = expression();
if (pc >= MAX_TOK) return 0;
if (tokens[pc].type == ':') {
pc++;
long end = expression();
match(']');
if (locals[idx].addr < 0 || locals[idx].addr >= MEM_SIZE) return 0;
long val = memory[locals[idx].addr];
if (is_string_ptr(val)) {
return slice_string(val, start_or_index, end);
@@ -236,19 +275,28 @@ long expression() {
match(']');
int addr = locals[idx].addr;
if (pc >= MAX_TOK) return 0;
if (tokens[pc].type == '=') {
pc++;
long val = expression();
memory[addr + start_or_index] = val;
long target_addr = addr + start_or_index;
if (target_addr >= 0 && target_addr < MEM_SIZE) {
memory[target_addr] = val;
}
return val;
}
return memory[addr + start_or_index];
long read_addr = addr + start_or_index;
if (read_addr < 0 || read_addr >= MEM_SIZE) return 0;
return memory[read_addr];
} else if (tokens[pc+1].type == '=') {
int idx = find_local(tokens[pc].text, tokens[pc].val);
if (idx == -1) error("Assign to unknown var");
if (idx < 0 || idx >= loc_cnt) return 0;
pc += 2;
long val = expression();
memory[locals[idx].addr] = val;
if (locals[idx].addr >= 0 && locals[idx].addr < MEM_SIZE) {
memory[locals[idx].addr] = val;
}
return val;
}
}
+36 -2
View File
@@ -4,12 +4,29 @@
#include "interpreter.h"
int is_string_ptr(long val) {
return val > MEM_SIZE * 8;
if (val < 0) {
return 0;
}
if (val > MEM_SIZE * 8) {
return 1;
}
return 0;
}
long concat_strings(long ptr1, long ptr2) {
static char empty_str[] = "";
char *s1 = (char*)ptr1;
char *s2 = (char*)ptr2;
if (!s1 || !s2) {
return (long)empty_str;
}
if (str_pool_idx >= STR_POOL_SIZE) {
error("String pool overflow");
return (long)empty_str;
}
char *result = &str_pool[str_pool_idx];
int len1 = strlen(s1);
@@ -17,6 +34,7 @@ long concat_strings(long ptr1, long ptr2) {
if (str_pool_idx + len1 + len2 + 1 >= STR_POOL_SIZE) {
error("String pool overflow");
return (long)empty_str;
}
strcpy(result, s1);
@@ -28,7 +46,18 @@ long concat_strings(long ptr1, long ptr2) {
}
long slice_string(long str_ptr, int start, int end) {
static char empty_str[] = "";
char *str = (char*)str_ptr;
if (!str) {
return (long)empty_str;
}
if (str_pool_idx >= STR_POOL_SIZE) {
error("String pool overflow");
return (long)empty_str;
}
char *result = &str_pool[str_pool_idx];
int str_len = strlen(str);
@@ -36,14 +65,19 @@ long slice_string(long str_ptr, int start, int end) {
if (end < 0) end = str_len;
if (end > str_len) end = str_len;
if (start > end) start = end;
if (start > str_len) start = str_len;
int length = end - start;
if (length < 0) length = 0;
if (str_pool_idx + length + 1 >= STR_POOL_SIZE) {
error("String pool overflow");
return (long)empty_str;
}
strncpy(result, str + start, length);
if (length > 0 && start < str_len) {
strncpy(result, str + start, length);
}
result[length] = 0;
str_pool_idx += length + 1;
+13 -4
View File
@@ -6,13 +6,19 @@
void tokenize(char *src) {
char *s = src;
if (!src) return;
while (*s) {
if (isspace(*s)) { s++; continue; }
if (tk_idx >= MAX_TOK - 1) {
return;
}
Token *t = &tokens[tk_idx++];
t->text = s;
if (*s == '/' && *(s+1) == '/') {
if (*s == '/' && s[1] && s[1] == '/') {
while (*s && *s != '\n') s++;
tk_idx--;
continue;
@@ -20,9 +26,10 @@ void tokenize(char *src) {
if (isalpha(*s)) {
int len = 0;
while (isalnum(s[len]) || s[len] == '_') len++;
while (s[len] && (isalnum(s[len]) || s[len] == '_') && len < 31) len++;
char buf[32];
if (len > 31) len = 31;
strncpy(buf, s, len); buf[len] = 0;
if (!strcmp(buf, "int")) t->type = Int;
@@ -52,7 +59,7 @@ void tokenize(char *src) {
char *d = s;
while (*s && *s != '"') {
if (*s == '\\' && *(s+1) == 'n') {
if (*s == '\\' && s[1] && s[1] == 'n') {
*d++ = '\n'; s+=2;
} else {
*d++ = *s++;
@@ -76,5 +83,7 @@ void tokenize(char *src) {
t->type = *s++;
}
tokens[tk_idx].type = 0;
if (tk_idx < MAX_TOK) {
tokens[tk_idx].type = 0;
}
}