feat(v4.0.0): the small single-cell words

NIP SWAP ROT -ROT ?DUP 2DUP, >R R@ R>, @ ! +! -! 2@ 2! CELLS,
- NEGATE 1+ 1- 2+ 2- MIN MAX, OR NOT 0= 0< 0<> 0> = <> < > <= >= U<
WITHIN TRUE FALSE in a new test, and * and / beside UM* and /MOD in
test_foundation.c.  Executed on the golden model at both cell widths
against C on every combination of the edge values and against recorded
transcripts of the v3 binary.

WITHIN is low <= n < high with signed comparisons, which is what v3
computes; the document's circular form differed for low > high.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
rajames
2026-10-03 17:49:30 -04:00
co-authored by Claude Opus 5.5
parent cb66db1107
commit 84c7711763
3 changed files with 479 additions and 35 deletions
+34 -34
View File
@@ -305,10 +305,10 @@ Section numbers match the v3 primitive reference.
| `DROP` | OP | `drop` |
| `DUP` | OP | `dup` |
| `OVER` | OP | `over` |
| `SWAP` | CAP | §4 |
| `?DUP` | CAP | `dup IF dup THEN` |
| `ROT` | CAP | §4 |
| `-ROT` | CAP | `ROT ROT` |
| `SWAP` | CAP | §4. Executed on the golden model (2026-10-03), including a transcript of the v3 binary. Leaves its caller 7 data cells and 6 return entries. |
| `?DUP` | CAP | `if Z dup ; Z: ;` (`dup IF dup THEN` without the extra copy). Executed on the golden model (2026-10-03), including a transcript of the v3 binary. |
| `ROT` | CAP | §4. Executed on the golden model (2026-10-03), including a transcript of the v3 binary. Leaves its caller 6 data cells and 4 return entries; in line, with `SWAP` in line, it calls nothing. |
| `-ROT` | CAP | `SWAP push SWAP pop`, `SWAP` in line (`ROT ROT` in one pass). Executed on the golden model (2026-10-03), including a transcript of the v3 binary. Leaves its caller 6 data cells and 5 return entries. |
| `DEPTH` | RET | No visible stack pointer (D-2). |
| `PICK` | RET | No visible stack pointer (D-2). |
| `ROLL` | RET | No visible stack pointer (D-2); D-7 is moot. |
@@ -317,26 +317,26 @@ Section numbers match the v3 primitive reference.
| Word | Fate | v4 definition |
| --- | --- | --- |
| `>R` | IN | `push` |
| `R>` | IN | `pop` |
| `R@` | IN | `pop dup push` |
| `>R` | IN | `push` — executed on the golden model (2026-10-03) with `R@` and `R>`, including a transcript of the v3 binary. |
| `R>` | IN | `pop` — executed on the golden model (2026-10-03), see `>R`. |
| `R@` | IN | `pop dup push` — executed on the golden model (2026-10-03), see `>R`. |
### 5.3 Memory
| Word | Fate | v4 definition / notes |
| --- | --- | --- |
| `@` | IN | `a! @` |
| `!` | IN | `a! !` |
| `+!` | CAP | `a! @ + !` |
| `-!` | CAP | `a! NEGATE @ + !` |
| `2@` | CAP | `a! @+ @` (low cell at `addr`, high at `addr+1`, as in v3) |
| `2!` | CAP | `a! SWAP !+ !` |
| `@` | IN | `a! @` — executed on the golden model (2026-10-03), including a transcript of the v3 binary. |
| `!` | IN | `a! !` — executed on the golden model (2026-10-03), including a transcript of the v3 binary. |
| `+!` | CAP | `a! @ + !` — executed on the golden model (2026-10-03), including a transcript of the v3 binary. |
| `-!` | CAP | `a! NEGATE @ + !`, `NEGATE` in line — executed on the golden model (2026-10-03), including a transcript of the v3 binary. |
| `2@` | CAP | `a! @+ @` (low cell at `addr`, high at `addr+1`, as in v3) — executed on the golden model (2026-10-03), including a transcript of the v3 binary. |
| `2!` | CAP | `a! SWAP !+ !`, `SWAP` in line — executed on the golden model (2026-10-03), including a transcript of the v3 binary. Leaves its caller 7 data cells and 6 return entries. |
| `C@` | CAP | See below (D-1). Call-free. Executed on the golden model (2026-10-03). Leaves its caller 8 data cells and 7 return entries. |
| `C!` | CAP | See below (D-1). Call-free. Executed on the golden model (2026-10-03). |
| `FILL` | CAP | `( baddr u c -- )`: the low byte of `c`. See below. Nothing for `u = 0`; for `u < 0` nothing is written and `NODE-ERROR` is set (v3 read a negative count as a huge unsigned one). Executed on the golden model (2026-10-03), including a transcript of the v3 binary. Leaves its caller 5 data cells and 5 return entries. Clobbers `A` and, on error, `B`. |
| `MOVE` | CAP | `( src dst u -- )`, bytes: `push over over - -if UP drop pop jump CMOVE> UP: drop pop jump CMOVE` — `CMOVE>` when `src < dst`, else `CMOVE`, so overlapping bytes are read before they are overwritten, as v3's `memmove`. The test is the sign of `src - dst`, in line. Executed on the golden model (2026-10-03), including a transcript of the v3 binary. Leaves its caller 4 data cells and 5 return entries. |
| `ERASE` | CAP | `0 FILL`, as `0 jump FILL`. Executed on the golden model (2026-10-03), including a transcript of the v3 binary. |
| `CELLS` | IN | Empty (word-addressed). Becomes `2* 2*` if D-1 chooses bytes. |
| `CELLS` | IN | Empty (word-addressed, D-1); v3 answers 24 for `3 CELLS`. Executed on the golden model (2026-10-03). |
```forth
\ byte access on a word-addressed node, little-endian: four bytes to a cell at
@@ -377,17 +377,17 @@ Section numbers match the v3 primitive reference.
| Word | Fate | v4 definition / notes |
| --- | --- | --- |
| `+` | OP | `+` |
| `-` | CAP | `NEGATE +` |
| `*` | CAP | `UM* drop` |
| `/` | CAP | `/MOD NIP` |
| `-` | CAP | `NEGATE +`, `NEGATE` in line — executed on the golden model (2026-10-03), including a transcript of the v3 binary. |
| `*` | CAP | `UM* drop` — executed on the golden model (2026-10-03) against C's wrapping product. Leaves its caller 6 data cells and 5 return entries. |
| `/` | CAP | `/MOD NIP`, as `push S>D pop SM/REM push drop pop` (`/MOD`'s body and `NIP` in line, so it runs no deeper than `/MOD`). Truncates toward zero, as v3. Executed on the golden model (2026-10-03) against C wherever the quotient fits a cell. Leaves its caller 5 data cells and 2 return entries. Division by zero is unspecified, as for `UM/MOD` (§4); v3 reported an error and stopped the line. |
| `MOD` `/MOD` `*/` `*/MOD` (§4 versions) | RET | Shadowed duplicates. Only the §6 versions survive. |
| `1+` `1-` `2+` `2-` | IN | `1 +`, `-1 +`, `2 +`, `-2 +` |
| `1+` `1-` `2+` `2-` | IN | `1 +`, `-1 +`, `2 +`, `-2 +` — executed on the golden model (2026-10-03), including a transcript of the v3 binary. |
| `2*` | OP | `2*` |
| `2/` | OP | `2/` |
| `ABS` | CAP | `dup 0< IF NEGATE THEN` — executed on the golden model (2026-10-02). |
| `NEGATE` | CAP | §4 |
| `MIN` | CAP | `2DUP > IF SWAP THEN drop` |
| `MAX` | CAP | `2DUP < IF SWAP THEN drop` |
| `NEGATE` | CAP | §4. Executed on the golden model (2026-10-03), including a transcript of the v3 binary. |
| `MIN` | CAP | `over over < if B drop drop ; B: drop push drop pop ;` — the smaller, signed. Executed on the golden model (2026-10-03), including a transcript of the v3 binary. Leaves its caller 4 data cells and 6 return entries. |
| `MAX` | CAP | `over over < if A drop push drop pop ; A: drop drop ;` — the larger, signed. Executed on the golden model (2026-10-03), including a transcript of the v3 binary. Leaves its caller 4 data cells and 6 return entries. |
### 5.5 Logic and comparison
@@ -395,25 +395,25 @@ Section numbers match the v3 primitive reference.
| --- | --- | --- |
| `AND` | OP | `and` |
| `XOR` | OP | `xor` |
| `OR` | CAP | §4 |
| `OR` | CAP | §4. Executed on the golden model (2026-10-03), including a transcript of the v3 binary. |
| `INVERT` | OP | `inv` |
| `NOT` | CAP | `0=` (FORTH-79 logical not, as in v3) |
| `NOT` | CAP | `0=` (FORTH-79 logical not, as in v3), as `jump 0=`. Executed on the golden model (2026-10-03), including a transcript of the v3 binary. |
| `LSHIFT` | CAP | `BEGIN dup WHILE 1- SWAP 2* SWAP REPEAT drop` — executed on the golden model (2026-10-03). |
| `RSHIFT` | CAP | `BEGIN dup WHILE 1- SWAP 2/ MSB inv and SWAP REPEAT drop` (clears the sign bit each step; `MSB` is the cell-width top-bit constant) — executed on the golden model (2026-10-03). |
| `0=` `0<` | CAP | §4 |
| `0<>` | CAP | `0= 0=` |
| `0>` | CAP | `dup 0< SWAP 0= OR 0=` (correct for the most negative number) |
| `0=` `0<` | CAP | §4. Executed on the golden model (2026-10-03), including a transcript of the v3 binary. |
| `0<>` | CAP | `if Z drop -1 ; Z: ;` (`0= 0=` without calls). Executed on the golden model (2026-10-03), including a transcript of the v3 binary. |
| `0>` | CAP | `-if NN drop 0 ; NN: if Z drop -1 ; Z: ;` — two native sign tests in place of `dup 0< SWAP 0= OR 0=`; correct for the most negative number. Executed on the golden model (2026-10-03), including a transcript of the v3 binary. |
| `=` | CAP | `xor 0=` — executed on the golden model (2026-10-02). |
| `<>` | CAP | `xor 0<>` |
| `<>` | CAP | `xor 0<>`, as `xor jump 0<>`. Executed on the golden model (2026-10-03), including a transcript of the v3 binary. |
| `<` | CAP | `2DUP xor 0< IF drop 0< ELSE - 0< THEN` (overflow-safe) — executed on the golden model (2026-10-02). |
| `>` | CAP | `SWAP <` |
| `<=` | CAP | `> 0=` |
| `>=` | CAP | `< 0=` |
| `U<` | CAP | §4 |
| `>` | CAP | `SWAP <`, as `SWAP jump <` with `SWAP` in line. Executed on the golden model (2026-10-03), including a transcript of the v3 binary. Leaves its caller 6 data cells and 6 return entries. |
| `<=` | CAP | `> 0=`, as `SWAP < jump 0=`. Executed on the golden model (2026-10-03), including a transcript of the v3 binary. Leaves its caller 6 data cells and 6 return entries. |
| `>=` | CAP | `< 0=`, as `< jump 0=`. Executed on the golden model (2026-10-03), including a transcript of the v3 binary. Leaves its caller 6 data cells and 6 return entries. |
| `U<` | CAP | §4. Executed on the golden model (2026-10-03), including a transcript of the v3 binary. Leaves its caller 6 data cells and 7 return entries. |
| `U>` | CAP | `SWAP U<` — executed on the golden model (2026-10-02). |
| `WITHIN` | CAP | `over - push - pop U<` |
| `TRUE` | IN | `-1` |
| `FALSE` | IN | `0` |
| `WITHIN` | CAP | `( n low high -- flag )`: `push over pop < push < inv pop and` — `low <= n < high`, both comparisons signed, which is what v3 computes. It replaces `over - push - pop U<`, the circular form, which answers differently when `low > high` (`5 10 0 WITHIN` is false in v3 and here, true in that form). Executed on the golden model (2026-10-03), including a transcript of the v3 binary. Leaves its caller 4 data cells and 5 return entries. |
| `TRUE` | IN | `-1` — executed on the golden model (2026-10-03), including a transcript of the v3 binary. |
| `FALSE` | IN | `0` — executed on the golden model (2026-10-03), including a transcript of the v3 binary. |
### 5.6 Mixed-precision arithmetic
File diff suppressed because it is too large Load Diff
+18 -1
View File
@@ -79,7 +79,7 @@ static v4_asm as;
static v4_cell w_nip, w_swap, w_or, w_negate, w_rot, w_zless, w_zequal,
w_2dup, w_minus, w_uless, w_umstar, w_ummod,
w_ugreater, w_abs, w_s2d, w_dplus, w_dnegate, w_dabs, w_smrem,
w_slashmod, w_mplus, w_dminus, w_d0equal, w_dequal,
w_slashmod, w_star, w_slash, w_mplus, w_dminus, w_d0equal, w_dequal,
w_qfromint, w_qtoint, w_less, w_equal, w_dless, w_2swap, w_2over,
w_dmax, w_dmin, w_qgt_doc, w_qgt, w_dltkeep, w_qstar, w_d2starc, w_uqdiv, w_qslash, w_qexp, w_qsqrt, w_qlog,
w_qreduce, w_qsin, l_trig, w_qcos,
@@ -394,6 +394,16 @@ static void build(void)
w_slashmod = v4_asm_label(&as);
O(PUSH); CALL(w_s2d); O(RPOP); CALL(w_smrem); O(SEMI);
/* : * UM* drop ; 5.4 */
w_star = v4_asm_label(&as);
CALL(w_umstar); O(DROP); O(SEMI);
/* : / /MOD NIP ; 5.4
* with /MOD's body and NIP in line (push S>D pop SM/REM push drop pop),
* so it runs no deeper than /MOD. */
w_slash = v4_asm_label(&as);
O(PUSH); CALL(w_s2d); O(RPOP); CALL(w_smrem); O(PUSH); O(DROP); O(RPOP); O(SEMI);
/* : M+ S>D D+ ; 5.6 */
w_mplus = v4_asm_label(&as);
CALL(w_s2d); CALL(w_dplus); O(SEMI);
@@ -2082,6 +2092,9 @@ int main(void)
}
if (b != 0 && !(a == (v4_cell)V4_MSB && b == -1))
CHECK(call(w_slashmod, 2, a, b, 0) && left2(a % b, a / b), "/MOD [%u,%u]", i, j);
if (b != 0 && !(a == (v4_cell)V4_MSB && b == -1))
CHECK(call(w_slash, 2, a, b, 0) && left1(a / b), "/ [%u,%u]", i, j);
CHECK(call(w_star, 2, a, b, 0) && left1((v4_cell)(ua * ub)), "* [%u,%u]", i, j);
}
}
@@ -2860,6 +2873,10 @@ int main(void)
headroom("SM/REM", w_smrem, 3, smrem_args, 5, 2, &dh, &rh);
CHECK(rh >= 1, "SM/REM leaves room for /MOD's return address");
headroom("/MOD", w_slashmod, 2, slashmod_args, 4, 2, &dh, &rh);
headroom("/", w_slash, 2, slashmod_args, 4, 1, &dh, &rh);
CHECK(dh >= 3 && rh >= 2, "/ runs no deeper than /MOD");
headroom("*", w_star, 2, slashmod_args, 4, 1, &dh, &rh);
CHECK(dh >= 4 && rh >= 5, "* leaves room");
CHECK(dh >= 0 && rh >= 0, "/MOD runs at all");
}
}