#include "forth.h" // Input tokenizer (unchanged) 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; } // 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; long long v = strtoll(token, &end, 10); if (end != token && *end == '\0') { if (state == 0) { data_push((int64_t)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(); if (fgets(line_buf, sizeof(line_buf), stdin) == NULL) { break; } input_buf = line_buf; input_buf_cap = sizeof(line_buf); size_t n = strlen(input_buf); if (n > 0 && input_buf[n - 1] == '\n') { input_buf[n - 1] = '\0'; } input_ptr = input_buf; char* tok; while ((tok = next_token()) != NULL) { process_token(tok); } } forth_printf("\n"); }