This commit is contained in:
retoor 2025-11-22 23:15:15 +01:00
parent e6d75958c8
commit bd8d9d819e
13 changed files with 417 additions and 42 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

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++;
}

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;
}

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);

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;
}
}

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;

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;
}
}

41
tests/edge_cases.rc Normal file
View File

@ -0,0 +1,41 @@
int main() {
printf("Testing Edge Cases:\n\n");
printf("1. Empty string operations:\n");
char *empty = "";
char *result1 = upper(empty);
printf("upper('') = '%s'\n", result1);
printf("\n2. String slicing edge cases:\n");
char *text = "Hello";
char *slice1 = text[0:0];
printf("'Hello'[0:0] = '%s'\n", slice1);
char *slice2 = text[10:20];
printf("'Hello'[10:20] = '%s'\n", slice2);
char *slice3 = text[3:3];
printf("'Hello'[3:3] = '%s'\n", slice3);
printf("\n3. Math with edge cases:\n");
int zero = 0;
printf("abs(0) = %d\n", abs(zero));
printf("sqrt(0) = %d\n", sqrt(zero));
printf("\n4. String concatenation:\n");
char *str1 = "A";
char *str2 = "B";
char *concat = str1 + str2;
printf("'A' + 'B' = '%s'\n", concat);
printf("\n5. String search edge cases:\n");
int pos1 = strpos("test", "xyz");
printf("strpos('test', 'xyz') = %d\n", pos1);
int pos2 = strpos("test", "test");
printf("strpos('test', 'test') = %d\n", pos2);
printf("\n6. Nested operations:\n");
char *nested = upper(lower(upper("TeSt")));
printf("upper(lower(upper('TeSt'))) = '%s'\n", nested);
printf("\nAll edge cases handled safely!\n");
return 0;
}