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:
co-authored by
Claude Opus 5.5
parent
644bfc0a25
commit
dc7e37ba5c
@@ -421,6 +421,48 @@ static void test_stack_faults(void)
|
||||
CHECK(n.ds.t == 55, "detached, the address is memory");
|
||||
}
|
||||
|
||||
/* D-18: NODE-ERROR as a trap. A store of a non-zero code is a fault of its
|
||||
* own kind: the code is written, the return stack is emptied, the data stack
|
||||
* is left, and P is the sixth word of the table. */
|
||||
static void test_raised_errors(void)
|
||||
{
|
||||
static const unsigned store[] = { V4_OP_STORE_A, V4_OP_STORE_B, V4_OP_STORE_INC };
|
||||
unsigned k;
|
||||
for (k = 0; k < 3; k++) {
|
||||
fresh(); v4_node_fault_attach(&n, HANDLER);
|
||||
v4_node_error_attach(&n, 700);
|
||||
dpush(11); dpush(22); dpush(5); rpush(1); rpush(2);
|
||||
n.a = 700; n.b = 700;
|
||||
n.mem[0] = word6(store[k], V4_OP_DROP, V4_OP_DROP, NOP, NOP, NOP); n.p = 0;
|
||||
CHECK(v4_exec_step_word(&n, &es, &h) == 1, "the store retires and nothing after it runs");
|
||||
CHECK(n.faults == 1 && n.fault_kind == V4_FAULT_RAISED && n.fault_addr == 5 && n.p == HANDLER + (v4_cell)V4_FAULT_RAISED,
|
||||
"a non-zero store to NODE-ERROR raises: kind %u, code %lld", n.fault_kind, (long long)n.fault_addr);
|
||||
CHECK(n.mem[700] == 5, "the code is in NODE-ERROR");
|
||||
CHECK(n.rs.depth == 0 && n.ds.depth == 2 && n.ds.t == 22 && n.ds.s == 11, "the return stack is emptied and the data stack left");
|
||||
/* zero clears it and is no fault */
|
||||
dpush(0); n.a = 700; v4_exec_op(&n, &es, &h, V4_OP_STORE_A, 0, 0);
|
||||
CHECK(n.faults == 1 && n.mem[700] == 0, "a store of zero is an ordinary store");
|
||||
dpush(-1); n.a = 699; v4_exec_op(&n, &es, &h, V4_OP_STORE_A, 0, 0);
|
||||
CHECK(n.faults == 1 && n.mem[699] == -1, "and so is a store next to it");
|
||||
}
|
||||
/* detached: ordinary memory */
|
||||
fresh(); v4_node_fault_attach(&n, HANDLER);
|
||||
CHECK(n.error_reg == -1, "a fresh node has no error trap");
|
||||
dpush(7); n.a = 700; v4_exec_op(&n, &es, &h, V4_OP_STORE_A, 0, 0);
|
||||
CHECK(n.faults == 0 && n.mem[700] == 7, "not attached, NODE-ERROR is memory and the word goes on");
|
||||
/* with no table the node stops */
|
||||
fresh(); v4_node_error_attach(&n, 700);
|
||||
dpush(7); n.a = 700;
|
||||
CHECK(run1(V4_OP_STORE_A) == 1 && n.stopped && n.mem[700] == 7, "with no handler a raised error stops the node");
|
||||
v4_node_reset(&n);
|
||||
CHECK(n.error_reg == -1, "reset detaches the trap");
|
||||
/* the table must be six words inside memory */
|
||||
v4_node_fault_attach(&n, (v4_cell)(V4_NODE_WORDS - V4_FAULT_KINDS));
|
||||
CHECK(n.fault_vector == (v4_cell)(V4_NODE_WORDS - V4_FAULT_KINDS), "a table that ends with memory is accepted");
|
||||
v4_node_fault_attach(&n, (v4_cell)(V4_NODE_WORDS - V4_FAULT_KINDS + 1u));
|
||||
CHECK(n.fault_vector == -1, "one that runs past it is not");
|
||||
}
|
||||
|
||||
/* D-14: an address outside node memory is a fault. The opcode does nothing,
|
||||
* the rest of its word is not executed, and P becomes the handler; with no
|
||||
* handler the node stops. */
|
||||
@@ -542,6 +584,7 @@ int main(void)
|
||||
test_iword_in_wide_cell();
|
||||
#endif
|
||||
test_stack_faults();
|
||||
test_raised_errors();
|
||||
test_address_faults();
|
||||
test_soak();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user