fix: correct Cell union and add interpreter, main, word implementations

Co-authored-by: aider (openrouter/tencent/hy3-preview:free) <aider@aider.chat>
This commit is contained in:
2026-05-03 16:59:53 +03:00
parent 0d9b7e3424
commit e5c6fdf9d0
4 changed files with 383 additions and 2 deletions
+97
View File
@@ -0,0 +1,97 @@
#include "forth.h"
// Input tokenizer
char* next_token(void) {
if (input_ptr == NULL) return NULL;
while (*input_ptr != '\0' && isspace((unsigned char)*input_ptr)) {
input_ptr++;
}
if (*input_ptr == '\0') return NULL;
char* start = input_ptr;
while (*input_ptr != '\0' && !isspace((unsigned char)*input_ptr)) {
input_ptr++;
}
if (*input_ptr != '\0') {
*input_ptr = '\0';
input_ptr++;
}
return start;
}
// Interpreter functions
void inner_interpreter(void) {
while (ip != NULL) {
Cell current = *ip;
ip++; // Move to next cell
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) { // Colon definition
ret_push(NULL); // Return address to stop interpreter
ip = w->body;
inner_interpreter();
} else { // Primitive word
w->code(w);
}
} else { // Compile mode
if (w->flags & (1 << 7)) { // Immediate word: execute now
if (w->code == do_docolon) {
ret_push(NULL);
ip = w->body;
inner_interpreter();
} else {
w->code(w);
}
} else { // Normal word: compile into current definition
if (compile_idx >= COMPILE_BUF_SIZE) {
printf("Compile buffer full\n");
return;
}
compile_buf[compile_idx++] = (Cell){.word = w};
}
}
} else { // Not a known word: 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
Word* lit_w = lookup_word("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");
return;
}
compile_buf[compile_idx++] = (Cell){.word = lit_w};
compile_buf[compile_idx++] = (Cell){.num = (int32_t)v};
}
} else {
printf("Unknown word: '%s'\n", token);
}
}
}
void outer_interpreter(void) {
while (1) {
printf("ok ");
fflush(stdout);
if (fgets(input_buf, INPUT_BUF_SIZE, stdin) == NULL) {
break; // EOF
}
input_ptr = input_buf;
char* tok;
while ((tok = next_token()) != NULL) {
process_token(tok);
}
}
printf("\n");
}