feat(v4.0.0): every error is raised and ends the line (D-18)

Ruled 2026-10-04: guard all errors.  The errors that set NODE-ERROR and
let the line run on now stop it at once, with a message.

- A store of a non-zero code to NODE-ERROR is a trap, a sixth kind of
  fault: nothing after it executes, the return stack is emptied, and the
  data stack is left as the word left it.  Not attached, NODE-ERROR is
  plain memory, as the tests below the prompt use it.
- The capsule's words store a code where they stored -1, and the prompt's
  (RAISED) prints its message: Negative count, Not a number, Number too
  long, Not a character, Dictionary full, Name missing, Control structure
  mismatch, Control structures too deep.
- ' and COMPILE and [COMPILE] of a word that is not there say
  UNKNOWN WORD: 'xxx', as the interpreter does.
- tests: the trap in test_exec.c; every message from the prompt, with the
  rest of the line not run and the stack kept, in test_host_quit.c.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
rajames
2026-10-04 20:13:23 -04:00
co-authored by Claude Opus 5.5
parent 644bfc0a25
commit dc7e37ba5c
12 changed files with 181 additions and 38 deletions
+5 -1
View File
@@ -257,7 +257,11 @@ unsigned v4_exec_step_word(v4_node *n, v4_exec_state *es, v4_heat *h)
unsigned faults = n->faults;
v4_exec_op(n, es, h, op, iw, slot);
if (n->faults != faults) break; /* P is the handler now, or the node has stopped */
if (n->faults != faults) { /* P is the handler now, or the node has stopped */
/* a store that raised an error (D-18) did execute; any other fault means the opcode did not */
if (n->fault_kind == V4_FAULT_RAISED) executed++;
break;
}
executed++;
if (again) {