#include "forth.h" // Stack operations void do_dup(Word* w) { if (sp < 0) return; int32_t v = data_stack[sp]; data_push(v); } void do_drop(Word* w) { data_pop(); } void do_swap(Word* w) { if (sp < 1) return; int32_t a = data_stack[sp-1]; int32_t b = data_stack[sp]; data_stack[sp-1] = b; data_stack[sp] = a; } void do_over(Word* w) { if (sp < 1) return; data_push(data_stack[sp-1]); } void do_rot(Word* w) { if (sp < 2) return; int32_t a = data_stack[sp-2]; int32_t b = data_stack[sp-1]; int32_t c = data_stack[sp]; data_stack[sp-2] = c; data_stack[sp-1] = a; data_stack[sp] = b; } void do_minus_rot(Word* w) { if (sp < 2) return; int32_t a = data_stack[sp-2]; int32_t b = data_stack[sp-1]; int32_t c = data_stack[sp]; data_stack[sp-2] = b; data_stack[sp-1] = c; data_stack[sp] = a; } void do_nip(Word* w) { if (sp < 1) return; data_stack[sp-1] = data_stack[sp]; sp--; } void do_tuck(Word* w) { if (sp < 1) return; int32_t a = data_stack[sp-1]; int32_t b = data_stack[sp]; data_push(a); data_stack[sp-2] = b; } // Arithmetic operations void do_add(Word* w) { if (sp < 1) return; int32_t b = data_pop(); int32_t a = data_pop(); data_push(a + b); } void do_sub(Word* w) { if (sp < 1) return; int32_t b = data_pop(); int32_t a = data_pop(); data_push(a - b); } void do_mul(Word* w) { if (sp < 1) return; int32_t b = data_pop(); int32_t a = data_pop(); data_push(a * b); } void do_div(Word* w) { if (sp < 1) return; int32_t b = data_pop(); int32_t a = data_pop(); if (b == 0) { printf("Division by zero\n"); data_push(a); data_push(b); return; } data_push(a / b); } void do_mod(Word* w) { if (sp < 1) return; int32_t b = data_pop(); int32_t a = data_pop(); if (b == 0) { printf("Modulo by zero\n"); data_push(a); data_push(b); return; } data_push(a % b); } void do_slash_mod(Word* w) { if (sp < 1) return; int32_t b = data_pop(); int32_t a = data_pop(); if (b == 0) { printf("Modulo by zero\n"); data_push(a); data_push(b); return; } data_push(a / b); data_push(a % b); } void do_one_plus(Word* w) { if (sp < 0) return; data_stack[sp]++; } void do_one_minus(Word* w) { if (sp < 0) return; data_stack[sp]--; } void do_two_plus(Word* w) { if (sp < 0) return; data_stack[sp] += 2; } void do_two_minus(Word* w) { if (sp < 0) return; data_stack[sp] -= 2; } void do_negate(Word* w) { if (sp < 0) return; data_stack[sp] = -data_stack[sp]; } void do_abs(Word* w) { if (sp < 0) return; int32_t v = data_pop(); data_push(v < 0 ? -v : v); } void do_min(Word* w) { if (sp < 1) return; int32_t b = data_pop(); int32_t a = data_pop(); data_push(a < b ? a : b); } void do_max(Word* w) { if (sp < 1) return; int32_t b = data_pop(); int32_t a = data_pop(); data_push(a > b ? a : b); } // Logic operations void do_and(Word* w) { if (sp < 1) return; int32_t b = data_pop(); int32_t a = data_pop(); data_push(a & b); } void do_or(Word* w) { if (sp < 1) return; int32_t b = data_pop(); int32_t a = data_pop(); data_push(a | b); } void do_xor(Word* w) { if (sp < 1) return; int32_t b = data_pop(); int32_t a = data_pop(); data_push(a ^ b); } void do_invert(Word* w) { if (sp < 0) return; data_stack[sp] = ~data_stack[sp]; } void do_lshift(Word* w) { if (sp < 1) return; int32_t b = data_pop(); int32_t a = data_pop(); data_push(a << b); } void do_rshift(Word* w) { if (sp < 1) return; int32_t b = data_pop(); int32_t a = data_pop(); data_push((int32_t)((uint32_t)a >> b)); } // Comparison operations void do_eq(Word* w) { if (sp < 1) return; int32_t b = data_pop(); int32_t a = data_pop(); data_push(a == b ? -1 : 0); // Forth uses -1 for true, 0 for false } void do_neq(Word* w) { if (sp < 1) return; int32_t b = data_pop(); int32_t a = data_pop(); data_push(a != b ? -1 : 0); } void do_lt(Word* w) { if (sp < 1) return; int32_t b = data_pop(); int32_t a = data_pop(); data_push(a < b ? -1 : 0); } void do_gt(Word* w) { if (sp < 1) return; int32_t b = data_pop(); int32_t a = data_pop(); data_push(a > b ? -1 : 0); } void do_lte(Word* w) { if (sp < 1) return; int32_t b = data_pop(); int32_t a = data_pop(); data_push(a <= b ? -1 : 0); } void do_gte(Word* w) { if (sp < 1) return; int32_t b = data_pop(); int32_t a = data_pop(); data_push(a >= b ? -1 : 0); } void do_zero_eq(Word* w) { if (sp < 0) return; int32_t a = data_pop(); data_push(a == 0 ? -1 : 0); } void do_zero_lt(Word* w) { if (sp < 0) return; int32_t a = data_pop(); data_push(a < 0 ? -1 : 0); } void do_zero_gt(Word* w) { if (sp < 0) return; int32_t a = data_pop(); data_push(a > 0 ? -1 : 0); } // I/O operations void do_dot(Word* w) { if (sp < 0) return; printf("%d ", data_pop()); fflush(stdout); } void do_cr(Word* w) { printf("\n"); fflush(stdout); } void do_emit(Word* w) { if (sp < 0) return; putchar((char)data_pop()); fflush(stdout); } void do_key(Word* w) { int c = getchar(); data_push(c == EOF ? -1 : c); } void do_dot_quote(Word* w) { // Immediate word: parse string until " and print/compile if (state == 0) { // Interpret mode: print immediately //