feat: switch to 64-bit integers and dynamic memory
Co-authored-by: aider (openrouter/deepseek/deepseek-v4-pro) <aider@aider.chat>
This commit is contained in:
@@ -8,81 +8,76 @@
|
||||
#include <stdint.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
// Configuration
|
||||
#define DATA_STACK_SIZE 256
|
||||
#define RET_STACK_SIZE 256
|
||||
#define DICT_SIZE 256
|
||||
#define BODY_SIZE 1024
|
||||
#define COMPILE_BUF_SIZE 1024
|
||||
#define INPUT_BUF_SIZE 256
|
||||
// Configuration (all hard limits removed)
|
||||
#define MAX_NAME_LEN 31
|
||||
#define COMPILE_STACK_SIZE 256
|
||||
#define USER_MEMORY_SIZE 1024
|
||||
|
||||
// Core types
|
||||
typedef struct Word Word;
|
||||
typedef union Cell {
|
||||
Word* word;
|
||||
int32_t num;
|
||||
union Cell* cell_ptr; // Use union tag here, as typedef Cell is not available yet
|
||||
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
|
||||
uint8_t flags; // Bit7=immediate, Bit6=hidden, Bits0-5=name length
|
||||
char name[MAX_NAME_LEN + 1];
|
||||
void (*code)(Word*);
|
||||
Cell* body;
|
||||
Cell* body; // points to the word’s body (allocated dynamically)
|
||||
};
|
||||
|
||||
// Globals
|
||||
extern int32_t data_stack[DATA_STACK_SIZE];
|
||||
extern int sp;
|
||||
extern Cell ret_stack[RET_STACK_SIZE];
|
||||
extern int rp;
|
||||
extern Cell* ip;
|
||||
// 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[DICT_SIZE];
|
||||
extern int dict_idx;
|
||||
extern Word* dict_head;
|
||||
extern Cell dict_bodies[BODY_SIZE];
|
||||
extern int body_idx;
|
||||
|
||||
extern int state; // 0=interpret, 1=compile
|
||||
extern Cell compile_buf[COMPILE_BUF_SIZE];
|
||||
extern int compile_idx;
|
||||
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[INPUT_BUF_SIZE];
|
||||
extern char input_buf[1024]; // fixed for line input
|
||||
extern char* input_ptr;
|
||||
|
||||
extern Cell* compile_stack[COMPILE_STACK_SIZE];
|
||||
extern int compile_sp;
|
||||
extern int64_t *compile_stack; // holds indices into compile_buf
|
||||
extern int32_t compile_sp;
|
||||
extern int32_t compile_stack_cap;
|
||||
|
||||
extern int32_t user_mem[USER_MEMORY_SIZE];
|
||||
extern int32_t* here;
|
||||
extern Cell *user_mem;
|
||||
extern int64_t user_mem_size; // in cells
|
||||
extern Cell* here;
|
||||
|
||||
// Core function prototypes
|
||||
void data_push(int32_t val);
|
||||
int32_t data_pop(void);
|
||||
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(int32_t val);
|
||||
int32_t ret_pop_num(void);
|
||||
void compile_push(Cell* addr);
|
||||
Cell* compile_pop(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);
|
||||
|
||||
// Primitive word prototypes
|
||||
// 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);
|
||||
@@ -171,4 +166,4 @@ void do_until(Word* w);
|
||||
void do_while(Word* w);
|
||||
void do_repeat(Word* w);
|
||||
|
||||
#endif // FORTH_H
|
||||
#endif
|
||||
|
||||
+85
-66
@@ -1,103 +1,122 @@
|
||||
#include "forth.h"
|
||||
|
||||
// Global variables
|
||||
int32_t data_stack[DATA_STACK_SIZE];
|
||||
int sp = -1;
|
||||
Cell ret_stack[RET_STACK_SIZE];
|
||||
int rp = -1;
|
||||
// Dynamic storage
|
||||
int64_t *data_stack = NULL;
|
||||
int32_t data_sp = -1;
|
||||
int32_t data_cap = 0;
|
||||
|
||||
Cell *ret_stack = NULL;
|
||||
int32_t rp = -1;
|
||||
int32_t ret_cap = 0;
|
||||
Cell* ip = NULL;
|
||||
|
||||
Word dict[DICT_SIZE];
|
||||
int dict_idx = 0;
|
||||
Word* dict_head = NULL;
|
||||
Cell dict_bodies[BODY_SIZE];
|
||||
int body_idx = 0;
|
||||
|
||||
int state = 0;
|
||||
Cell compile_buf[COMPILE_BUF_SIZE];
|
||||
int compile_idx = 0;
|
||||
char compiling_name[MAX_NAME_LEN + 1];
|
||||
Cell *compile_buf = NULL;
|
||||
int32_t compile_idx = 0;
|
||||
int32_t compile_cap = 0;
|
||||
char compiling_name[MAX_NAME_LEN + 1] = {0};
|
||||
|
||||
char input_buf[INPUT_BUF_SIZE];
|
||||
char input_buf[1024] = {0};
|
||||
char* input_ptr = NULL;
|
||||
|
||||
Cell* compile_stack[COMPILE_STACK_SIZE];
|
||||
int compile_sp = -1;
|
||||
int64_t *compile_stack = NULL;
|
||||
int32_t compile_sp = -1;
|
||||
int32_t compile_stack_cap = 0;
|
||||
|
||||
int32_t user_mem[USER_MEMORY_SIZE];
|
||||
int32_t* here = &user_mem[0];
|
||||
Cell *user_mem = NULL;
|
||||
int64_t user_mem_size = 0;
|
||||
Cell* here = NULL;
|
||||
|
||||
// Stack helpers
|
||||
void data_push(int32_t val) {
|
||||
if (sp < DATA_STACK_SIZE - 1) {
|
||||
data_stack[++sp] = val;
|
||||
} else {
|
||||
printf("Data stack overflow\n");
|
||||
// ---------- Data stack ----------
|
||||
void data_push(int64_t val) {
|
||||
if (data_sp + 1 >= data_cap) {
|
||||
int32_t new_cap = data_cap ? data_cap * 2 : 128;
|
||||
int64_t *tmp = realloc(data_stack, new_cap * sizeof(int64_t));
|
||||
if (!tmp) {
|
||||
fprintf(stderr, "Out of memory\n");
|
||||
exit(1);
|
||||
}
|
||||
data_stack = tmp;
|
||||
data_cap = new_cap;
|
||||
}
|
||||
data_stack[++data_sp] = val;
|
||||
}
|
||||
|
||||
int32_t data_pop(void) {
|
||||
if (sp >= 0) {
|
||||
return data_stack[sp--];
|
||||
} else {
|
||||
printf("Data stack underflow\n");
|
||||
int64_t data_pop(void) {
|
||||
if (data_sp < 0) {
|
||||
fprintf(stderr, "Data stack underflow\n");
|
||||
return 0;
|
||||
}
|
||||
return data_stack[data_sp--];
|
||||
}
|
||||
|
||||
// ---------- Return stack (holds Cell values) ----------
|
||||
static void ensure_ret_stack(void) {
|
||||
if (rp + 1 >= ret_cap) {
|
||||
int32_t new_cap = ret_cap ? ret_cap * 2 : 128;
|
||||
Cell *tmp = realloc(ret_stack, new_cap * sizeof(Cell));
|
||||
if (!tmp) {
|
||||
fprintf(stderr, "Out of memory\n");
|
||||
exit(1);
|
||||
}
|
||||
ret_stack = tmp;
|
||||
ret_cap = new_cap;
|
||||
}
|
||||
}
|
||||
|
||||
void ret_push_ip(Cell* val) {
|
||||
if (rp < RET_STACK_SIZE - 1) {
|
||||
rp++;
|
||||
ret_stack[rp].cell_ptr = val;
|
||||
} else {
|
||||
printf("Return stack overflow\n");
|
||||
}
|
||||
ensure_ret_stack();
|
||||
rp++;
|
||||
ret_stack[rp].ptr = val; // store pointer in the 'ptr' member
|
||||
}
|
||||
|
||||
Cell* ret_pop_ip(void) {
|
||||
if (rp >= 0) {
|
||||
Cell* res = ret_stack[rp].cell_ptr;
|
||||
rp--;
|
||||
return res;
|
||||
} else {
|
||||
printf("Return stack underflow\n");
|
||||
if (rp < 0) {
|
||||
fprintf(stderr, "Return stack underflow\n");
|
||||
return NULL;
|
||||
}
|
||||
return ret_stack[rp--].ptr;
|
||||
}
|
||||
|
||||
void ret_push_num(int32_t val) {
|
||||
if (rp < RET_STACK_SIZE - 1) {
|
||||
rp++;
|
||||
ret_stack[rp].num = val;
|
||||
} else {
|
||||
printf("Return stack overflow\n");
|
||||
}
|
||||
void ret_push_num(int64_t val) {
|
||||
ensure_ret_stack();
|
||||
rp++;
|
||||
ret_stack[rp].num = val;
|
||||
}
|
||||
|
||||
int32_t ret_pop_num(void) {
|
||||
if (rp >= 0) {
|
||||
int32_t res = ret_stack[rp].num;
|
||||
rp--;
|
||||
return res;
|
||||
} else {
|
||||
printf("Return stack underflow\n");
|
||||
int64_t ret_pop_num(void) {
|
||||
if (rp < 0) {
|
||||
fprintf(stderr, "Return stack underflow (num)\n");
|
||||
return 0;
|
||||
}
|
||||
return ret_stack[rp--].num;
|
||||
}
|
||||
|
||||
void compile_push(Cell* addr) {
|
||||
if (compile_sp < COMPILE_STACK_SIZE - 1) {
|
||||
compile_stack[++compile_sp] = addr;
|
||||
} else {
|
||||
printf("Compile stack overflow\n");
|
||||
// ---------- Compile stack (indices) ----------
|
||||
static void ensure_compile_stack(void) {
|
||||
if (compile_sp + 1 >= compile_stack_cap) {
|
||||
int32_t new_cap = compile_stack_cap ? compile_stack_cap * 2 : 64;
|
||||
int64_t *tmp = realloc(compile_stack, new_cap * sizeof(int64_t));
|
||||
if (!tmp) {
|
||||
fprintf(stderr, "Out of memory\n");
|
||||
exit(1);
|
||||
}
|
||||
compile_stack = tmp;
|
||||
compile_stack_cap = new_cap;
|
||||
}
|
||||
}
|
||||
|
||||
Cell* compile_pop(void) {
|
||||
if (compile_sp >= 0) {
|
||||
return compile_stack[compile_sp--];
|
||||
} else {
|
||||
printf("Compile stack underflow\n");
|
||||
return NULL;
|
||||
}
|
||||
void compile_push(int64_t idx) {
|
||||
ensure_compile_stack();
|
||||
compile_stack[++compile_sp] = idx;
|
||||
}
|
||||
|
||||
int64_t compile_pop(void) {
|
||||
if (compile_sp < 0) {
|
||||
fprintf(stderr, "Compile stack underflow\n");
|
||||
return -1;
|
||||
}
|
||||
return compile_stack[compile_sp--];
|
||||
}
|
||||
|
||||
+5
-5
@@ -1,11 +1,11 @@
|
||||
#include "forth.h"
|
||||
|
||||
Word* add_primitive(const char* name, void (*code)(Word*), uint8_t flags) {
|
||||
if (dict_idx >= DICT_SIZE) {
|
||||
printf("Dictionary full\n");
|
||||
return NULL;
|
||||
Word* w = malloc(sizeof(Word));
|
||||
if (!w) {
|
||||
fprintf(stderr, "Out of memory\n");
|
||||
exit(1);
|
||||
}
|
||||
Word* w = &dict[dict_idx++];
|
||||
w->prev = dict_head;
|
||||
dict_head = w;
|
||||
|
||||
@@ -21,7 +21,7 @@ Word* add_primitive(const char* name, void (*code)(Word*), uint8_t flags) {
|
||||
|
||||
Word* lookup_word(const char* name) {
|
||||
for (Word* w = dict_head; w != NULL; w = w->prev) {
|
||||
if (w->flags & (1 << 6)) continue; // Skip hidden words
|
||||
if (w->flags & (1 << 6)) continue;
|
||||
if (strcmp(w->name, name) == 0) return w;
|
||||
}
|
||||
return NULL;
|
||||
|
||||
+35
-27
@@ -1,6 +1,6 @@
|
||||
#include "forth.h"
|
||||
|
||||
// Input tokenizer
|
||||
// Input tokenizer (unchanged)
|
||||
char* next_token(void) {
|
||||
if (input_ptr == NULL) return NULL;
|
||||
while (*input_ptr != '\0' && isspace((unsigned char)*input_ptr)) {
|
||||
@@ -18,11 +18,25 @@ char* next_token(void) {
|
||||
return start;
|
||||
}
|
||||
|
||||
// Interpreter functions
|
||||
// Ensure compile_buf has room for at least 'needed' more cells
|
||||
void ensure_compile_cap(int32_t needed) {
|
||||
while (compile_idx + needed > compile_cap) {
|
||||
int32_t new_cap = compile_cap ? compile_cap * 2 : 256;
|
||||
Cell *tmp = realloc(compile_buf, new_cap * sizeof(Cell));
|
||||
if (!tmp) {
|
||||
fprintf(stderr, "Out of memory\n");
|
||||
exit(1);
|
||||
}
|
||||
compile_buf = tmp;
|
||||
compile_cap = new_cap;
|
||||
}
|
||||
}
|
||||
|
||||
// Inner interpreter (unchanged)
|
||||
void inner_interpreter(void) {
|
||||
while (ip != NULL) {
|
||||
Cell current = *ip;
|
||||
ip++; // Move to next cell
|
||||
ip++;
|
||||
current.word->code(current.word);
|
||||
}
|
||||
}
|
||||
@@ -31,15 +45,15 @@ 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
|
||||
if (w->code == do_docolon) {
|
||||
ret_push_ip(NULL);
|
||||
ip = w->body;
|
||||
inner_interpreter();
|
||||
} else { // Primitive word
|
||||
} else {
|
||||
w->code(w);
|
||||
}
|
||||
} else { // Compile mode
|
||||
if (w->flags & (1 << 7)) { // Immediate word: execute now
|
||||
if (w->flags & (1 << 7)) { // Immediate word
|
||||
if (w->code == do_docolon) {
|
||||
ret_push_ip(NULL);
|
||||
ip = w->body;
|
||||
@@ -47,32 +61,26 @@ void process_token(const char* token) {
|
||||
} else {
|
||||
w->code(w);
|
||||
}
|
||||
} else { // Normal word: compile into current definition
|
||||
if (compile_idx >= COMPILE_BUF_SIZE) {
|
||||
printf("Compile buffer full\n");
|
||||
return;
|
||||
}
|
||||
} else { // Compile normal word
|
||||
ensure_compile_cap(1);
|
||||
compile_buf[compile_idx++] = (Cell){.word = w};
|
||||
}
|
||||
}
|
||||
} else { // Not a known word: try to parse as number
|
||||
} else { // 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
|
||||
long long v = strtoll(token, &end, 10);
|
||||
if (end != token && *end == '\0') {
|
||||
if (state == 0) {
|
||||
data_push((int64_t)v);
|
||||
} else { // 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");
|
||||
if (!lit_w) {
|
||||
fprintf(stderr, "Fatal: lit word not found\n");
|
||||
return;
|
||||
}
|
||||
ensure_compile_cap(2);
|
||||
compile_buf[compile_idx++] = (Cell){.word = lit_w};
|
||||
compile_buf[compile_idx++] = (Cell){.num = (int32_t)v};
|
||||
compile_buf[compile_idx++] = (Cell){.num = (int64_t)v};
|
||||
}
|
||||
} else {
|
||||
printf("Unknown word: '%s'\n", token);
|
||||
@@ -84,8 +92,8 @@ void outer_interpreter(void) {
|
||||
while (1) {
|
||||
printf("ok ");
|
||||
fflush(stdout);
|
||||
if (fgets(input_buf, INPUT_BUF_SIZE, stdin) == NULL) {
|
||||
break; // EOF
|
||||
if (fgets(input_buf, sizeof(input_buf), stdin) == NULL) {
|
||||
break;
|
||||
}
|
||||
input_ptr = input_buf;
|
||||
char* tok;
|
||||
|
||||
+338
-477
File diff suppressed because it is too large
Load Diff
@@ -1,31 +1,39 @@
|
||||
#include "forth.h"
|
||||
|
||||
int main(void) {
|
||||
// Register primitive words
|
||||
// Allocate user memory
|
||||
user_mem_size = 1024 * 1024; // 1 Mega cells
|
||||
user_mem = calloc((size_t)user_mem_size, sizeof(Cell));
|
||||
if (!user_mem) {
|
||||
fprintf(stderr, "Failed to allocate user memory\n");
|
||||
return 1;
|
||||
}
|
||||
here = user_mem;
|
||||
|
||||
// Hidden words first
|
||||
add_primitive("exit", do_exit, 0);
|
||||
add_primitive("docolon", do_docolon, 1 << 6); // Hidden
|
||||
add_primitive("lit", do_lit, 1 << 6); // Hidden
|
||||
add_primitive("do_dot_quote_inner", do_dot_quote_inner, 1 << 6); // Hidden
|
||||
add_primitive("0branch", do_zero_branch, 1 << 6); // Hidden (for IF, UNTIL, WHILE)
|
||||
add_primitive("branch", do_branch, 1 << 6); // Hidden (for ELSE, REPEAT)
|
||||
add_primitive("exit", do_exit, 0);
|
||||
add_primitive("docolon", do_docolon, 1 << 6);
|
||||
add_primitive("lit", do_lit, 1 << 6);
|
||||
add_primitive("do_dot_quote_inner", do_dot_quote_inner, 1 << 6);
|
||||
add_primitive("0branch", do_zero_branch, 1 << 6);
|
||||
add_primitive("branch", do_branch, 1 << 6);
|
||||
|
||||
// Public primitives
|
||||
// Stack ops
|
||||
add_primitive("dup", do_dup, 0);
|
||||
add_primitive("drop", do_drop, 0);
|
||||
add_primitive("swap", do_swap, 0);
|
||||
add_primitive("over", do_over, 0);
|
||||
add_primitive("rot", do_rot, 0);
|
||||
add_primitive("minus-rot", do_minus_rot, 0);
|
||||
add_primitive("nip", do_nip, 0);
|
||||
add_primitive("tuck", do_tuck, 0);
|
||||
add_primitive("dup", do_dup, 0);
|
||||
add_primitive("drop", do_drop, 0);
|
||||
add_primitive("swap", do_swap, 0);
|
||||
add_primitive("over", do_over, 0);
|
||||
add_primitive("rot", do_rot, 0);
|
||||
add_primitive("-rot", do_minus_rot, 0);
|
||||
add_primitive("nip", do_nip, 0);
|
||||
add_primitive("tuck", do_tuck, 0);
|
||||
|
||||
// Arithmetic
|
||||
add_primitive("+", do_add, 0);
|
||||
add_primitive("-", do_sub, 0);
|
||||
add_primitive("*", do_mul, 0);
|
||||
add_primitive("/", do_div, 0);
|
||||
add_primitive("+", do_add, 0);
|
||||
add_primitive("-", do_sub, 0);
|
||||
add_primitive("*", do_mul, 0);
|
||||
add_primitive("/", do_div, 0);
|
||||
add_primitive("mod", do_mod, 0);
|
||||
add_primitive("/mod", do_slash_mod, 0);
|
||||
add_primitive("1+", do_one_plus, 0);
|
||||
@@ -33,23 +41,23 @@ int main(void) {
|
||||
add_primitive("2+", do_two_plus, 0);
|
||||
add_primitive("2-", do_two_minus, 0);
|
||||
add_primitive("negate", do_negate, 0);
|
||||
add_primitive("abs", do_abs, 0);
|
||||
add_primitive("min", do_min, 0);
|
||||
add_primitive("max", do_max, 0);
|
||||
add_primitive("abs", do_abs, 0);
|
||||
add_primitive("min", do_min, 0);
|
||||
add_primitive("max", do_max, 0);
|
||||
|
||||
// Logic
|
||||
add_primitive("and", do_and, 0);
|
||||
add_primitive("or", do_or, 0);
|
||||
add_primitive("xor", do_xor, 0);
|
||||
add_primitive("and", do_and, 0);
|
||||
add_primitive("or", do_or, 0);
|
||||
add_primitive("xor", do_xor, 0);
|
||||
add_primitive("invert", do_invert, 0);
|
||||
add_primitive("lshift", do_lshift, 0);
|
||||
add_primitive("rshift", do_rshift, 0);
|
||||
|
||||
// Comparison
|
||||
add_primitive("=", do_eq, 0);
|
||||
add_primitive("=", do_eq, 0);
|
||||
add_primitive("<>", do_neq, 0);
|
||||
add_primitive("<", do_lt, 0);
|
||||
add_primitive(">", do_gt, 0);
|
||||
add_primitive("<", do_lt, 0);
|
||||
add_primitive(">", do_gt, 0);
|
||||
add_primitive("<=", do_lte, 0);
|
||||
add_primitive(">=", do_gte, 0);
|
||||
add_primitive("0=", do_zero_eq, 0);
|
||||
@@ -57,22 +65,22 @@ int main(void) {
|
||||
add_primitive("0>", do_zero_gt, 0);
|
||||
|
||||
// I/O
|
||||
add_primitive(".", do_dot, 0);
|
||||
add_primitive("cr", do_cr, 0);
|
||||
add_primitive("emit", do_emit, 0);
|
||||
add_primitive("key", do_key, 0);
|
||||
add_primitive(".\"", do_dot_quote, 1 << 7); // Immediate
|
||||
add_primitive(".", do_dot, 0);
|
||||
add_primitive("cr", do_cr, 0);
|
||||
add_primitive("emit", do_emit, 0);
|
||||
add_primitive("key", do_key, 0);
|
||||
add_primitive(".\"", do_dot_quote, 1 << 7); // immediate
|
||||
add_primitive("words", do_words, 0);
|
||||
|
||||
// Memory
|
||||
add_primitive("@", do_fetch, 0);
|
||||
add_primitive("!", do_store, 0);
|
||||
add_primitive("@", do_fetch, 0);
|
||||
add_primitive("!", do_store, 0);
|
||||
add_primitive("+!", do_plus_store, 0);
|
||||
add_primitive("c@", do_cfetch, 0);
|
||||
add_primitive("c!", do_cstore, 0);
|
||||
add_primitive("variable", do_variable, 0);
|
||||
add_primitive("constant", do_constant, 0);
|
||||
add_primitive("here", do_here, 0);
|
||||
add_primitive("here", do_here, 0);
|
||||
add_primitive("allot", do_allot, 0);
|
||||
|
||||
// Return stack
|
||||
@@ -81,15 +89,15 @@ int main(void) {
|
||||
add_primitive("r@", do_r_fetch, 0);
|
||||
|
||||
// Compilation / control flow
|
||||
add_primitive(":", do_colon, 0);
|
||||
add_primitive(";", do_semicolon, 1 << 7); // Immediate
|
||||
add_primitive("if", do_if, 1 << 7); // Immediate
|
||||
add_primitive("else", do_else, 1 << 7); // Immediate
|
||||
add_primitive("then", do_then, 1 << 7); // Immediate
|
||||
add_primitive("begin", do_begin, 1 << 7); // Immediate
|
||||
add_primitive("until", do_until, 1 << 7); // Immediate
|
||||
add_primitive("while", do_while, 1 << 7); // Immediate
|
||||
add_primitive("repeat", do_repeat, 1 << 7); // Immediate
|
||||
add_primitive(":", do_colon, 0);
|
||||
add_primitive(";", do_semicolon, 1 << 7);
|
||||
add_primitive("if", do_if, 1 << 7);
|
||||
add_primitive("else", do_else, 1 << 7);
|
||||
add_primitive("then", do_then, 1 << 7);
|
||||
add_primitive("begin", do_begin, 1 << 7);
|
||||
add_primitive("until", do_until, 1 << 7);
|
||||
add_primitive("while", do_while, 1 << 7);
|
||||
add_primitive("repeat", do_repeat, 1 << 7);
|
||||
|
||||
// Start outer interpreter
|
||||
outer_interpreter();
|
||||
|
||||
Reference in New Issue
Block a user