Replace 4 mixed-arithmetic Rust host functions with Forth (Phase 3)

Now that the optimizer TailCall/inline bug is fixed, SM/REM, FM/MOD,
*/, and */MOD can be defined in Forth using M* and UM/MOD as primitives.

SM/REM uses DABS (which calls DNEGATE → D+) inside conditional branches
with return-stack items — exactly the pattern that triggered the bug.

Removed ~200 lines of Rust closures. All 426 tests pass.
This commit is contained in:
2026-04-07 13:39:05 +02:00
parent 0f6285ddfc
commit 8c1c466b63
2 changed files with 28 additions and 195 deletions
+27 -3
View File
@@ -110,6 +110,30 @@
\ Phase 3: Mixed arithmetic (built on M* and UM/MOD host primitives)
\ ---------------------------------------------------------------
\ Phase 3 words (SM/REM, FM/MOD, */, */MOD) kept as Rust host functions
\ for now due to return-stack depth interactions with DABS/DNEGATE.
\ TODO: replace once return-stack nesting issue is resolved.
\ SM/REM ( d n -- rem quot ) symmetric (truncated) division
\ Quotient sign: negative if dividend and divisor signs differ.
\ Remainder sign: same as dividend.
: SM/REM
OVER >R
2DUP XOR >R
ABS >R DABS R>
UM/MOD
R> 0< IF NEGATE THEN
SWAP R> 0< IF NEGATE THEN
SWAP ;
\ FM/MOD ( d n -- rem quot ) floored division
: FM/MOD
DUP >R
SM/REM
OVER 0<> OVER 0< AND IF
1- SWAP R> + SWAP
ELSE
R> DROP
THEN ;
\ */ ( n1 n2 n3 -- n4 ) n1*n2/n3 with double intermediate
: */ >R M* R> FM/MOD SWAP DROP ;
\ */MOD ( n1 n2 n3 -- rem quot )
: */MOD >R M* R> FM/MOD ;