feat: switch to 64-bit integers and dynamic memory
Co-authored-by: aider (openrouter/deepseek/deepseek-v4-pro) <aider@aider.chat>
This commit is contained in:
+35
-27
@@ -1,6 +1,6 @@
|
||||
#include "forth.h"
|
||||
|
||||
// Input tokenizer
|
||||
// Input tokenizer (unchanged)
|
||||
char* next_token(void) {
|
||||
if (input_ptr == NULL) return NULL;
|
||||
while (*input_ptr != '\0' && isspace((unsigned char)*input_ptr)) {
|
||||
@@ -18,11 +18,25 @@ char* next_token(void) {
|
||||
return start;
|
||||
}
|
||||
|
||||
// Interpreter functions
|
||||
// Ensure compile_buf has room for at least 'needed' more cells
|
||||
void ensure_compile_cap(int32_t needed) {
|
||||
while (compile_idx + needed > compile_cap) {
|
||||
int32_t new_cap = compile_cap ? compile_cap * 2 : 256;
|
||||
Cell *tmp = realloc(compile_buf, new_cap * sizeof(Cell));
|
||||
if (!tmp) {
|
||||
fprintf(stderr, "Out of memory\n");
|
||||
exit(1);
|
||||
}
|
||||
compile_buf = tmp;
|
||||
compile_cap = new_cap;
|
||||
}
|
||||
}
|
||||
|
||||
// Inner interpreter (unchanged)
|
||||
void inner_interpreter(void) {
|
||||
while (ip != NULL) {
|
||||
Cell current = *ip;
|
||||
ip++; // Move to next cell
|
||||
ip++;
|
||||
current.word->code(current.word);
|
||||
}
|
||||
}
|
||||
@@ -31,15 +45,15 @@ void process_token(const char* token) {
|
||||
Word* w = lookup_word(token);
|
||||
if (w != NULL) {
|
||||
if (state == 0) { // Interpret mode
|
||||
if (w->code == do_docolon) { // Colon definition
|
||||
ret_push_ip(NULL); // Return address to stop interpreter
|
||||
if (w->code == do_docolon) {
|
||||
ret_push_ip(NULL);
|
||||
ip = w->body;
|
||||
inner_interpreter();
|
||||
} else { // Primitive word
|
||||
} else {
|
||||
w->code(w);
|
||||
}
|
||||
} else { // Compile mode
|
||||
if (w->flags & (1 << 7)) { // Immediate word: execute now
|
||||
if (w->flags & (1 << 7)) { // Immediate word
|
||||
if (w->code == do_docolon) {
|
||||
ret_push_ip(NULL);
|
||||
ip = w->body;
|
||||
@@ -47,32 +61,26 @@ void process_token(const char* token) {
|
||||
} else {
|
||||
w->code(w);
|
||||
}
|
||||
} else { // Normal word: compile into current definition
|
||||
if (compile_idx >= COMPILE_BUF_SIZE) {
|
||||
printf("Compile buffer full\n");
|
||||
return;
|
||||
}
|
||||
} else { // Compile normal word
|
||||
ensure_compile_cap(1);
|
||||
compile_buf[compile_idx++] = (Cell){.word = w};
|
||||
}
|
||||
}
|
||||
} else { // Not a known word: try to parse as number
|
||||
} else { // Try to parse as number
|
||||
char* end;
|
||||
long v = strtol(token, &end, 10);
|
||||
if (end != token && *end == '\0') { // Valid integer
|
||||
if (state == 0) { // Interpret mode: push number
|
||||
data_push((int32_t)v);
|
||||
} else { // Compile mode: compile lit + number
|
||||
long long v = strtoll(token, &end, 10);
|
||||
if (end != token && *end == '\0') {
|
||||
if (state == 0) {
|
||||
data_push((int64_t)v);
|
||||
} else { // Compile lit + number
|
||||
Word* lit_w = lookup_word_internal("lit");
|
||||
if (lit_w == NULL) {
|
||||
printf("Fatal: lit word not found\n");
|
||||
return;
|
||||
}
|
||||
if (compile_idx + 2 > COMPILE_BUF_SIZE) {
|
||||
printf("Compile buffer full\n");
|
||||
if (!lit_w) {
|
||||
fprintf(stderr, "Fatal: lit word not found\n");
|
||||
return;
|
||||
}
|
||||
ensure_compile_cap(2);
|
||||
compile_buf[compile_idx++] = (Cell){.word = lit_w};
|
||||
compile_buf[compile_idx++] = (Cell){.num = (int32_t)v};
|
||||
compile_buf[compile_idx++] = (Cell){.num = (int64_t)v};
|
||||
}
|
||||
} else {
|
||||
printf("Unknown word: '%s'\n", token);
|
||||
@@ -84,8 +92,8 @@ void outer_interpreter(void) {
|
||||
while (1) {
|
||||
printf("ok ");
|
||||
fflush(stdout);
|
||||
if (fgets(input_buf, INPUT_BUF_SIZE, stdin) == NULL) {
|
||||
break; // EOF
|
||||
if (fgets(input_buf, sizeof(input_buf), stdin) == NULL) {
|
||||
break;
|
||||
}
|
||||
input_ptr = input_buf;
|
||||
char* tok;
|
||||
|
||||
Reference in New Issue
Block a user