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