Added eval.
This commit is contained in:
@@ -0,0 +1,144 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "../../types.h"
|
||||
#include "../../tokenizer.h"
|
||||
#include "../../interpreter.h"
|
||||
#include "../../native_functions.h"
|
||||
#include "eval_stdlib.h"
|
||||
|
||||
extern Token tokens[];
|
||||
extern int tk_idx;
|
||||
extern int pc;
|
||||
extern long memory[];
|
||||
extern int sp;
|
||||
extern int bp;
|
||||
extern Symbol locals[];
|
||||
extern int loc_cnt;
|
||||
extern long ax;
|
||||
extern int return_flag;
|
||||
extern char str_pool[];
|
||||
extern int str_pool_idx;
|
||||
|
||||
long native_eval(long *args, int argc) {
|
||||
if (argc < 1 || !args) {
|
||||
printf("Error: eval requires at least 1 argument (code string)\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *code = (char*)args[0];
|
||||
if (!code) {
|
||||
printf("Error: eval received null code string\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int code_len = strlen(code);
|
||||
if (code_len == 0) {
|
||||
return 0;
|
||||
}
|
||||
if (code_len > MAX_SRC - 1000) {
|
||||
printf("Error: eval code too large\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int saved_pc = pc;
|
||||
int old_pc_val = pc;
|
||||
|
||||
extern long expression();
|
||||
|
||||
char temp_buffer[1024];
|
||||
if (code_len > 1000) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int inserted_pos = -1;
|
||||
for (int i = 0; i < tk_idx && i < MAX_TOK; i++) {
|
||||
if (tokens[i].type == 0) {
|
||||
inserted_pos = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (inserted_pos == -1) {
|
||||
inserted_pos = tk_idx;
|
||||
}
|
||||
|
||||
if (inserted_pos + 50 >= MAX_TOK) {
|
||||
printf("Error: token buffer full\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int original_tk_idx = tk_idx;
|
||||
|
||||
Token temp_tokens[100];
|
||||
int temp_tk_idx = 0;
|
||||
|
||||
char *eval_copy = (char*)malloc(code_len + 1);
|
||||
if (!eval_copy) {
|
||||
return 0;
|
||||
}
|
||||
strcpy(eval_copy, code);
|
||||
|
||||
char *s = eval_copy;
|
||||
while (*s && temp_tk_idx < 100) {
|
||||
while (*s && (*s == ' ' || *s == '\t' || *s == '\n')) s++;
|
||||
if (!*s) break;
|
||||
|
||||
Token *t = &temp_tokens[temp_tk_idx++];
|
||||
t->text = s;
|
||||
|
||||
if (*s >= '0' && *s <= '9') {
|
||||
t->type = 128;
|
||||
t->val = 0;
|
||||
while (*s >= '0' && *s <= '9') {
|
||||
t->val = t->val * 10 + (*s - '0');
|
||||
s++;
|
||||
}
|
||||
} else if ((*s >= 'a' && *s <= 'z') || (*s >= 'A' && *s <= 'Z')) {
|
||||
t->type = 131;
|
||||
int len = 0;
|
||||
char *start = s;
|
||||
while ((*s >= 'a' && *s <= 'z') || (*s >= 'A' && *s <= 'Z') ||
|
||||
(*s >= '0' && *s <= '9') || *s == '_') {
|
||||
len++;
|
||||
s++;
|
||||
}
|
||||
t->val = len;
|
||||
t->text = start;
|
||||
} else {
|
||||
t->type = *s;
|
||||
s++;
|
||||
}
|
||||
}
|
||||
|
||||
if (temp_tk_idx > 0) {
|
||||
temp_tokens[temp_tk_idx].type = 0;
|
||||
}
|
||||
|
||||
pc = 0;
|
||||
long result = 0;
|
||||
|
||||
if (temp_tk_idx > 0) {
|
||||
for (int i = 0; i < temp_tk_idx && i < 100; i++) {
|
||||
tokens[inserted_pos + i] = temp_tokens[i];
|
||||
}
|
||||
tk_idx = inserted_pos + temp_tk_idx;
|
||||
if (tk_idx < MAX_TOK) {
|
||||
tokens[tk_idx].type = 0;
|
||||
}
|
||||
|
||||
pc = inserted_pos;
|
||||
result = expression();
|
||||
}
|
||||
|
||||
free(eval_copy);
|
||||
|
||||
tk_idx = original_tk_idx;
|
||||
pc = saved_pc;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void register_eval_stdlib() {
|
||||
register_native_func("eval", native_eval);
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#ifndef EVAL_STDLIB_H
|
||||
#define EVAL_STDLIB_H
|
||||
|
||||
void register_eval_stdlib();
|
||||
|
||||
#endif
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "io/socket_stdlib.h"
|
||||
#include "async/async_stdlib.h"
|
||||
#include "constants/constants_stdlib.h"
|
||||
#include "eval/eval_stdlib.h"
|
||||
|
||||
void register_stdlib() {
|
||||
register_string_stdlib();
|
||||
@@ -13,4 +14,5 @@ void register_stdlib() {
|
||||
register_socket_stdlib();
|
||||
register_async_stdlib();
|
||||
register_constants_stdlib();
|
||||
register_eval_stdlib();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user