feat(v4.0.0): # keeps its high quotient on the data stack

`#` held the high quotient on the return stack across its second
UM/MOD, which was the deepest point of pictured output once C! was made
call-free. It now rotates it under the division on the data stack
(-ROT in line: SWAP push SWAP pop).

Headroom, return entries: <# #S #> 2 -> 3, the signed picture 1 -> 2.
Data room is unchanged.

Same 4716 checks per width at 32- and 64-bit cells, optimised and
ASan+UBSan (`make test`, `make sanitize`); the headroom checks now
require the new figures.

Test results on the amd64 host only. This is a development check, not
acceptance (JUSTIFICATION.md section 16).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
rajames
2026-10-03 11:51:03 -04:00
co-authored by Claude Opus 5.5
parent 638aeb6636
commit 7a21f07ad5
2 changed files with 14 additions and 9 deletions
+9 -6
View File
@@ -57,7 +57,7 @@ static v4_cell w_swap, w_or, w_ummod, w_lshift, w_rshift, w_cstore,
#define VGET(a) do { LIT(a); O(BANG_B); O(FETCH_B); } while (0)
#define VSET(a) do { LIT(a); O(BANG_B); O(STORE_B); } while (0)
#define SWAP_INLINE() do { O(OVER); O(PUSH); O(PUSH); O(DROP); O(RPOP); O(RPOP); } while (0)
#define ROT_INLINE() do { O(PUSH); SWAP_INLINE(); O(RPOP); SWAP_INLINE(); } while (0)
#define NROT_INLINE() do { SWAP_INLINE(); O(PUSH); SWAP_INLINE(); O(RPOP); } while (0)
#define SUB_INLINE() do { O(PUSH); O(INV); O(RPOP); O(ADD); O(INV); } while (0)
/* The words pictured output rests on, as in test_foundation.c. */
@@ -238,11 +238,14 @@ static void build_pictured(void)
/* : # ( ud1 -- ud2 )
* ud1 / base in two UM/MOD steps, the high cell first and its remainder
* leading the low cell; the last remainder is the digit.
* 0 (BASE) UM/MOD push (BASE) UM/MOD pop ROT qlo qhi rem
* 0 (BASE) UM/MOD -ROT qhi lo rem1
* (BASE) UM/MOD -ROT qlo qhi rem
* The high quotient waits under the second division on the data stack,
* not on the return stack. -ROT in line is SWAP push SWAP pop.
* dup -10 + -if L1 drop 48 + jump L2 L1: drop 55 + L2: jump HOLD */
w_hash = v4_asm_label(&as);
LIT(0); CALL(w_base); CALL(w_ummod); O(PUSH);
CALL(w_base); CALL(w_ummod); O(RPOP); ROT_INLINE();
LIT(0); CALL(w_base); CALL(w_ummod); NROT_INLINE();
CALL(w_base); CALL(w_ummod); NROT_INLINE();
O(DUP); LIT(-10); O(ADD); a = FWD(MINUS_IF);
O(DROP); LIT(48); O(ADD); b = FWD(JUMP);
HERE_(a);
@@ -510,9 +513,9 @@ int main(void)
int dh, rh;
v4_node_store(&n, BASE, 10);
headroom("<# #S #>", t_ud, 2, 12345, 0, "12345", &dh, &rh);
CHECK(dh >= 2 && rh >= 2, "<# #S #> leaves room");
CHECK(dh >= 2 && rh >= 3, "<# #S #> leaves room");
headroom("signed picture", t_signed, 1, -12345, 0, "-12345", &dh, &rh);
CHECK(dh >= 2 && rh >= 1, "the signed picture leaves room");
CHECK(dh >= 2 && rh >= 2, "the signed picture leaves room");
}
CHECK(v4_node_guards_intact(&n), "guards intact");