#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"); }