fcbc810db8
Co-authored-by: aider (openrouter/moonshotai/kimi-k2.6) <aider@aider.chat>
113 lines
3.1 KiB
C
113 lines
3.1 KiB
C
#include "forth.h"
|
|
|
|
// Input tokenizer (unchanged)
|
|
char* next_token(void) {
|
|
if (input_ptr == NULL) return NULL;
|
|
while (*input_ptr != '\0' && forth_isspace((unsigned char)*input_ptr)) {
|
|
input_ptr++;
|
|
}
|
|
if (*input_ptr == '\0') return NULL;
|
|
char* start = input_ptr;
|
|
while (*input_ptr != '\0' && !forth_isspace((unsigned char)*input_ptr)) {
|
|
input_ptr++;
|
|
}
|
|
if (*input_ptr != '\0') {
|
|
*input_ptr = '\0';
|
|
input_ptr++;
|
|
}
|
|
return start;
|
|
}
|
|
|
|
// Ensure compile_buf has room for at least 'needed' more cells
|
|
int ensure_compile_cap(int32_t needed) {
|
|
if (compile_idx + needed > compile_cap) {
|
|
forth_printf("Compile buffer overflow\n");
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
// Inner interpreter (unchanged)
|
|
void inner_interpreter(void) {
|
|
while (ip != NULL) {
|
|
Cell current = *ip;
|
|
ip++;
|
|
current.word->code(current.word);
|
|
}
|
|
}
|
|
|
|
void process_token(const char* token) {
|
|
Word* w = lookup_word(token);
|
|
if (w != NULL) {
|
|
if (state == 0) { // Interpret mode
|
|
if (w->code == do_docolon) {
|
|
ret_push_ip(NULL);
|
|
ip = w->body;
|
|
inner_interpreter();
|
|
} else {
|
|
w->code(w);
|
|
}
|
|
} else { // Compile mode
|
|
if (w->flags & (1 << 7)) { // Immediate word
|
|
if (w->code == do_docolon) {
|
|
ret_push_ip(NULL);
|
|
ip = w->body;
|
|
inner_interpreter();
|
|
} else {
|
|
w->code(w);
|
|
}
|
|
} else { // Compile normal word
|
|
if (!ensure_compile_cap(1)) return;
|
|
compile_buf[compile_idx++] = (Cell){.word = w};
|
|
}
|
|
}
|
|
} else { // Try to parse as number
|
|
char* end;
|
|
int64_t v = forth_strtoll(token, &end, 10);
|
|
if (end != token && *end == '\0') {
|
|
if (state == 0) {
|
|
data_push(v);
|
|
} else { // Compile lit + number
|
|
if (!w_lit) {
|
|
forth_printf("Fatal: lit word not found\n");
|
|
return;
|
|
}
|
|
if (!ensure_compile_cap(2)) return;
|
|
compile_buf[compile_idx++] = (Cell){.word = w_lit};
|
|
compile_buf[compile_idx++] = (Cell){.num = (int64_t)v};
|
|
}
|
|
} else {
|
|
forth_printf("Unknown word: '%s'\n", token);
|
|
}
|
|
}
|
|
}
|
|
|
|
void outer_interpreter(void) {
|
|
static char line_buf[256];
|
|
while (1) {
|
|
forth_printf("ok ");
|
|
forth_fflush();
|
|
size_t i = 0;
|
|
int c;
|
|
while (i < sizeof(line_buf) - 1) {
|
|
c = forth_getchar();
|
|
if (c == FORTH_EOF || c == '\n' || c == '\r') {
|
|
break;
|
|
}
|
|
line_buf[i++] = (char)c;
|
|
}
|
|
line_buf[i] = '\0';
|
|
if (i == 0 && c == FORTH_EOF) {
|
|
break;
|
|
}
|
|
input_buf = line_buf;
|
|
input_buf_cap = sizeof(line_buf);
|
|
input_ptr = input_buf;
|
|
char* tok;
|
|
while ((tok = next_token()) != NULL) {
|
|
process_token(tok);
|
|
}
|
|
}
|
|
forth_printf("\n");
|
|
}
|