Files
ai-forth-experiment/forth.h
T
haxala1r b115744991 fix: qdup/tuck/2swap bugs, getline, and cached word pointers
Co-authored-by: aider (openrouter/moonshotai/kimi-k2.6) <aider@aider.chat>
2026-05-03 21:39:52 +03:00

192 lines
4.3 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#ifndef FORTH_H
#define FORTH_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdint.h>
#include <inttypes.h>
#include <sys/types.h>
// Configuration (all hard limits removed)
#define MAX_NAME_LEN 31
#define F_IMMEDIATE (1 << 7)
#define F_HIDDEN (1 << 6)
// Core types
typedef struct Word Word;
typedef union Cell {
Word* word;
int64_t num;
void* ptr; // used for return stack (holds Cell*)
} Cell;
struct Word {
Word* prev;
uint8_t flags; // Bit7=immediate, Bit6=hidden, Bits0-5=name length
char name[MAX_NAME_LEN + 1];
void (*code)(Word*);
Cell* body; // points to the words body (allocated dynamically)
};
// Globals (all dynamic)
extern int64_t *data_stack;
extern int32_t data_sp; // stack indices are small enough for int32_t
extern int32_t data_cap;
extern Cell *ret_stack;
extern int32_t rp;
extern int32_t ret_cap;
extern Cell* ip; // instruction pointer
extern Word* dict_head;
extern int state;
extern Cell *compile_buf;
extern int32_t compile_idx;
extern int32_t compile_cap;
extern char compiling_name[MAX_NAME_LEN + 1];
extern char* input_buf; // line buffer (dynamic, managed by getline)
extern size_t input_buf_cap;
extern char* input_ptr;
extern int64_t *compile_stack; // holds indices into compile_buf
extern int32_t compile_sp;
extern int32_t compile_stack_cap;
extern Cell *user_mem;
extern int64_t user_mem_size; // in cells
extern Cell* here;
// Pointers to critical hidden/primitive words (set during init)
extern Word* w_exit;
extern Word* w_docolon;
extern Word* w_lit;
extern Word* w_branch;
extern Word* w_zbranch;
extern Word* w_dot_quote_inner;
// Core function prototypes
void data_push(int64_t val);
int64_t data_pop(void);
void ret_push_ip(Cell* val);
Cell* ret_pop_ip(void);
void ret_push_num(int64_t val);
int64_t ret_pop_num(void);
void compile_push(int64_t idx);
int64_t compile_pop(void);
Word* add_primitive(const char* name, void (*code)(Word*), uint8_t flags);
Word* lookup_word(const char* name);
Word* lookup_word_internal(const char* name);
char* next_token(void);
void inner_interpreter(void);
void process_token(const char* token);
void outer_interpreter(void);
// Ensure compile_buf has at least 'needed' free cells
void ensure_compile_cap(int32_t needed);
// Stack ops
void do_dup(Word* w);
void do_drop(Word* w);
void do_swap(Word* w);
void do_over(Word* w);
void do_rot(Word* w);
void do_minus_rot(Word* w);
void do_nip(Word* w);
void do_tuck(Word* w);
// Arithmetic
void do_add(Word* w);
void do_sub(Word* w);
void do_mul(Word* w);
void do_div(Word* w);
void do_mod(Word* w);
void do_slash_mod(Word* w);
void do_one_plus(Word* w);
void do_one_minus(Word* w);
void do_two_plus(Word* w);
void do_two_minus(Word* w);
void do_negate(Word* w);
void do_abs(Word* w);
void do_min(Word* w);
void do_max(Word* w);
// Logic
void do_and(Word* w);
void do_or(Word* w);
void do_xor(Word* w);
void do_invert(Word* w);
void do_lshift(Word* w);
void do_rshift(Word* w);
// Comparison
void do_eq(Word* w);
void do_neq(Word* w);
void do_lt(Word* w);
void do_gt(Word* w);
void do_lte(Word* w);
void do_gte(Word* w);
void do_zero_eq(Word* w);
void do_zero_lt(Word* w);
void do_zero_gt(Word* w);
// I/O
void do_dot(Word* w);
void do_cr(Word* w);
void do_emit(Word* w);
void do_key(Word* w);
void do_dot_quote(Word* w);
void do_dot_quote_inner(Word* w);
void do_words(Word* w);
// Memory
void do_fetch(Word* w);
void do_store(Word* w);
void do_plus_store(Word* w);
void do_cfetch(Word* w);
void do_cstore(Word* w);
void do_variable(Word* w);
void do_constant(Word* w);
void do_do_var(Word* w);
void do_do_const(Word* w);
void do_here(Word* w);
void do_allot(Word* w);
// Return stack
void do_to_r(Word* w);
void do_r_from(Word* w);
void do_r_fetch(Word* w);
// Control flow
void do_exit(Word* w);
void do_docolon(Word* w);
void do_lit(Word* w);
void do_colon(Word* w);
void do_semicolon(Word* w);
void do_branch(Word* w);
void do_zero_branch(Word* w);
void do_if(Word* w);
void do_else(Word* w);
void do_then(Word* w);
void do_begin(Word* w);
void do_until(Word* w);
void do_while(Word* w);
void do_repeat(Word* w);
/* Additional stack words */
void do_depth(Word* w);
void do_pick(Word* w);
void do_roll(Word* w);
void do_qdup(Word* w);
void do_2dup(Word* w);
void do_2drop(Word* w);
void do_2swap(Word* w);
#endif