From 4bdb210a9904526fbdc016e875feadf64f65a6b4 Mon Sep 17 00:00:00 2001 From: rajames Date: Wed, 7 Oct 2026 10:59:02 -0400 Subject: [PATCH] feat(v4.0.0): POST is the kernel's -- the boot feeds the cases, and nothing of the harness is on the node The boot runs POST with the runner (v4/system/post.c) after the capsules: it feeds the 538 cases to the node and judges them from outside. A case's printing no longer reaches the console. What the cases define stays in the dictionary, as in v3; the system is sealed after POST and the boot prints PARITY:V4_SYSTEM word_count=N dict_hash=..., as v3 prints its parity after POST. Gone: capsules/v4/post79.4th and its blocks 7000 up; the harness words; (CATCH) and (EMIT-HOOK), with what EMIT and the prompt loop did for them. The generator runs v3 on the lines as the kernel sends them, without the capsule's "T| ". One expected result follows from that: >IN.initial prints 6, not 9. make -C v4 test, sanitize and hosted-check pass; amd64, aarch64 and riscv64 boot, POST 538 of 538, word_count=411, dict_hash 0x6fb1d09418b189ee on all six: logs/20261007-105118, -105335, -105651. T{ is unknown at the prompt; RS1 prints 42 42 before and after COLD. A scratch build with one expectation changed names the case and ends PARITY:FAIL, POST: FAILED. Co-Authored-By: Claude Opus 5.5 --- capsules/BLOCK_MAP.md | 69 +- capsules/v4/nucleus-64.f18 | Bin 52520 -> 52288 bytes capsules/v4/post79.4th | 1796 ----------------- docs/v4.0.0/MESH.md | 26 +- docs/v4.0.0/POST79.md | 26 +- kernel/Makefile | 4 +- .../amd64/qemu-amd64-20261007-105118.log | 158 ++ .../aarch64/qemu-aarch64-20261007-105335.log | 131 ++ .../riscv64/qemu-riscv64-20261007-105651.log | 201 ++ v4/Makefile | 4 +- v4/README.md | 24 +- v4/capsule/core.v4 | 14 +- v4/capsule/quit.v4 | 19 +- v4/system/boot.c | 101 +- v4/system/post_cases.c | 2 +- v4/tests/host_map.h | 4 - v4/tests/test_host_quit.c | 7 +- v4/tests/test_host_unit.c | 42 +- v4/tools/mkpost.py | 8 +- v4/tools/post79_rules.py | 4 +- 20 files changed, 659 insertions(+), 1981 deletions(-) delete mode 100644 capsules/v4/post79.4th create mode 100644 logs/20261007-105118/amd64/qemu-amd64-20261007-105118.log create mode 100644 logs/20261007-105335/aarch64/qemu-aarch64-20261007-105335.log create mode 100644 logs/20261007-105651/riscv64/qemu-riscv64-20261007-105651.log diff --git a/capsules/BLOCK_MAP.md b/capsules/BLOCK_MAP.md index 0154e10a..546abd8e 100644 --- a/capsules/BLOCK_MAP.md +++ b/capsules/BLOCK_MAP.md @@ -1,5 +1,5 @@ # Capsule Block Manifest — Auto-generated - + @@ -31,7 +31,6 @@ | `user-font-demo.4th` | 4200, 4201, 4202 | `0xce1fd7d1b581a56d` | n/a | | `v4:forth79.4th` | 6000, 6001, 6002 | `0x4055641ee17d176b` | n/a | | `v4:hera.4th` | 8000, 8001, 8002, 8003, 8004 | `0x526252bfef9b722b` | n/a | -| `v4:post79.4th` | 7000, 7001, 7002, 7003, 7004, 7005, 7006, 7007, 7008, 7009, 7010, 7011, 7012, 7013, 7014, 7015, 7016, 7017, 7018, 7019, 7020, 7021, 7022, 7023, 7024, 7025, 7026, 7027, 7028, 7029, 7030, 7031, 7032, 7033, 7034, 7035, 7036, 7037, 7038, 7039, 7040, 7041, 7042, 7043, 7044, 7045, 7046, 7047, 7048, 7049, 7050, 7051, 7052, 7053, 7054, 7055, 7056, 7057, 7058, 7059, 7060, 7061, 7062, 7063 | `0xb26d1b974884179d` | n/a | | `workload-0.4th` | 2200, 2201 | `0x93f86f60aeba8feb` | n/a | | `workload-1-lite.4th` | 5058, 5059 | `0x44a7a7e3176dcc8d` | n/a | | `workload-1.4th` | 4406, 4415, 4425, 4435 | `0x63e251adb0a03613` | n/a | @@ -372,70 +371,6 @@ | 6000 | `v4:forth79.4th` | `0x4055641ee17d176b` | ok | | 6001 | `v4:forth79.4th` | `0x4055641ee17d176b` | ok | | 6002 | `v4:forth79.4th` | `0x4055641ee17d176b` | ok | -| 7000 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7001 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7002 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7003 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7004 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7005 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7006 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7007 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7008 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7009 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7010 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7011 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7012 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7013 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7014 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7015 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7016 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7017 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7018 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7019 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7020 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7021 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7022 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7023 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7024 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7025 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7026 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7027 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7028 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7029 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7030 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7031 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7032 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7033 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7034 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7035 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7036 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7037 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7038 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7039 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7040 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7041 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7042 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7043 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7044 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7045 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7046 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7047 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7048 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7049 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7050 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7051 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7052 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7053 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7054 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7055 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7056 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7057 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7058 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7059 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7060 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7061 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7062 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | -| 7063 | `v4:post79.4th` | `0xb26d1b974884179d` | ok | | 8000 | `v4:hera.4th` | `0x526252bfef9b722b` | ok | | 8001 | `v4:hera.4th` | `0x526252bfef9b722b` | ok | | 8002 | `v4:hera.4th` | `0x526252bfef9b722b` | ok | @@ -447,4 +382,4 @@ None. --- -*39 capsule(s) scanned. Re-run `mkcapsule --manifest ` to refresh.* +*38 capsule(s) scanned. Re-run `mkcapsule --manifest ` to refresh.* diff --git a/capsules/v4/nucleus-64.f18 b/capsules/v4/nucleus-64.f18 index b604f3dd9c6b1e30c6c15314482925cf76ddd9d1..f842ffa8e9030279f9678eb6dff32b227a3ca44e 100644 GIT binary patch literal 52288 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 literal 52520 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 Ee?PAzhX4Qo diff --git a/capsules/v4/post79.4th b/capsules/v4/post79.4th deleted file mode 100644 index 882b9225..00000000 --- a/capsules/v4/post79.4th +++ /dev/null @@ -1,1796 +0,0 @@ -Block 7000 -( post79.4th -- POST for the FORTH-79 Required Word Set on v4. ) -( Generated by v4/tools/mkpost.py from v3's POST cases: do not ) -( edit. docs/v4.0.0/NUCLEUS.md section 6. ) -VARIABLE T# VARIABLE TPASS VARIABLE TFAIL VARIABLE TOPEN -VARIABLE TBAD VARIABLE TWANT VARIABLE TLEN VARIABLE TSUM -VARIABLE TDEP -CREATE TBUF 64 ALLOT CREATE TSTK 16 ALLOT CREATE TNAME 8 ALLOT -0 T# ! 0 TPASS ! 0 TFAIL ! 0 TOPEN ! -: TB ( -- baddr ) TBUF 4 * ; -: TN ( -- baddr ) TNAME 4 * ; -( T-EMIT is given every character a case prints: the first 255 ) -( are kept, all are counted and summed. ) -: T-EMIT ( c -- ) - 255 AND DUP TSUM @ 31 * + 16777215 AND TSUM ! - TLEN @ 255 < IF TB TLEN @ + C! ELSE DROP THEN 1 TLEN +! ; -Block 7001 -: T-CLEAR ( i*x -- ) BEGIN DEPTH WHILE DROP REPEAT ; -: T. ( n -- ) 0 <# #S #> TYPE ; -( what a failing case printed, and the stack it left ) -: T-SHOW ( -- ) - ." out<" TB TLEN @ 255 MIN TYPE ." > stack<" - TDEP @ BEGIN DUP WHILE 1- DUP TSTK + @ . REPEAT DROP ." >" ; -( the verdict on the case that is open, if one is ) -: T-CLOSE ( -- ) - TOPEN @ IF - (CATCH) @ -1 = TWANT @ = 0= IF 1 TBAD ! THEN - TBAD @ IF 1 TFAIL +! - ." POST FAIL: " TN COUNT TYPE T-SHOW CR - ELSE 1 TPASS +! THEN - 0 TOPEN ! 0 (CATCH) ! - THEN ; -Block 7002 -( T{ name begin a case: clean stack, decimal, FORTH ) -: T{ ( i*x -- ) T-CLOSE T-CLEAR - DECIMAL [COMPILE] FORTH DEFINITIONS - BL WORD COUNT 31 MIN DUP TN C! TN 1+ SWAP CMOVE - 1 T# +! 1 TOPEN ! 0 TBAD ! 0 TWANT ! 0 TLEN ! 0 TSUM ! - 0 TDEP ! 1 (CATCH) ! ; -( T| ... a line of the case, what it prints captured ) -: T| ' T-EMIT (EMIT-HOOK) ! ; IMMEDIATE -: T-END ( -- ) 0 (EMIT-HOOK) ! DECIMAL ; -( -> ... the case is over: set its stack aside, top first ) -: -> ( i*x -- ) T-END 0 - BEGIN DEPTH 1 > WHILE - DUP 16 < IF SWAP OVER TSTK + ! ELSE SWAP DROP 1 TBAD ! THEN - 1+ REPEAT - 16 MIN TDEP ! ; -Block 7003 -( ->ERR the case is over, and must have ended in an error ) -: ->ERR ( i*x -- ) T-END -1 TWANT ! T-CLEAR ; -( ... }T the stack the case must have left, in order ) -: }T ( i*x -- ) - DEPTH TDEP @ = 0= IF 1 TBAD ! T-CLEAR EXIT THEN - 0 BEGIN DEPTH 1 > WHILE - SWAP OVER TSTK + @ = 0= IF 1 TBAD ! THEN 1+ REPEAT DROP ; -( n }TD only how many values the case must have left ) -: }TD ( n -- ) TDEP @ = 0= IF 1 TBAD ! THEN ; -( len sum T= what the case must have printed ) -: T= ( len sum -- ) TSUM @ = 0= IF 1 TBAD ! THEN - TLEN @ = 0= IF 1 TBAD ! THEN ; -Block 7004 -( the tally; a failure is an error, which ends the boot ) -: T-REPORT ( -- ) T-CLOSE 0 (CATCH) ! DECIMAL - ." PARITY:V4_POST tests=" T# @ T. ." pass=" TPASS @ T. - ." fail=" TFAIL @ T. CR - TFAIL @ IF -1 NODE-ERROR ! THEN ; -Block 7005 -T{ DUP.basic -T| 5 DUP . . CR --> }T 5 16397428 T= -T{ DUP.zero -T| 0 DUP . . CR --> }T 5 11775018 T= -T{ DUP.negative -T| -42 DUP . . CR --> }T 9 15322016 T= -T{ DUP.max_int -T| 2147483647 DUP . . CR --> }T 23 2334858 T= -T{ DUP.min_int -T| -2147483648 DUP . . CR --> }T 25 386046 T= -Block 7006 -T{ DUP.empty_stack -T| DUP -->ERR -T{ DROP.basic -T| 5 7 DROP . CR --> }T 3 51935 T= -T{ DROP.zero -T| 42 0 DROP . CR --> }T 4 1598184 T= -T{ DROP.negative -T| 10 -5 DROP . CR --> }T 4 1506889 T= -T{ DROP.double_drop -T| 1 2 3 DROP DROP . CR --> }T 3 48091 T= -Block 7007 -T{ DROP.triple_drop -T| 1 2 3 4 DROP DROP DROP . CR --> }T 3 48091 T= -T{ DROP.sequential -T| 5 DROP 6 DROP 7 . CR --> }T 3 53857 T= -T{ DROP.single_item -T| 99 DROP DEPTH . CR --> }T 3 47130 T= -T{ DROP.depth_change -T| DEPTH 1 2 DROP DEPTH SWAP - . CR --> 0 }T 3 48091 T= -T{ DROP.preserve_depth -T| DEPTH 5 6 DROP DROP DEPTH = . CR --> }T 3 47130 T= -Block 7008 -T{ DROP.max_int -T| 2147483647 DROP DEPTH . CR --> }T 3 47130 T= -T{ DROP.min_int -T| -2147483648 DROP DEPTH . CR --> }T 3 47130 T= -T{ DROP.with_dup -T| 5 DUP DROP . CR --> }T 3 51935 T= -T{ DROP.with_swap -T| 1 2 SWAP DROP . CR --> }T 3 49052 T= -T{ DROP.complex -T| 1 2 3 ROT DROP SWAP DROP . CR --> }T 3 50013 T= -Block 7009 -T{ DROP.empty_stack -T| DROP -->ERR -T{ SWAP.basic -T| 5 7 SWAP . . CR --> }T 5 16399350 T= -T{ SWAP.same_values -T| 42 42 SWAP . . CR --> }T 7 15838026 T= -T{ SWAP.zero_nonzero -T| 0 99 SWAP . . CR --> }T 6 12996858 T= -T{ SWAP.negative -T| -5 10 SWAP . . CR --> }T 7 12792257 T= -Block 7010 -T{ SWAP.one_item -T| 42 SWAP -->ERR -T{ SWAP.empty_stack -T| SWAP -->ERR -T{ OVER.basic -T| 5 7 OVER . . . CR --> }T 7 6011851 T= -T{ OVER.zeros -T| 0 0 OVER . . . CR --> }T 7 7986234 T= -T{ OVER.mixed -T| -1 42 OVER . . . CR --> }T 10 1455732 T= -Block 7011 -T{ OVER.one_item -T| 42 OVER -->ERR -T{ OVER.empty_stack -T| OVER -->ERR -T{ ROT.basic -T| 1 2 3 ROT . . . CR --> }T 7 9069952 T= -T{ ROT.zeros -T| 0 0 0 ROT . . . CR --> }T 7 7986234 T= -T{ ROT.mixed -T| -1 0 1 ROT . . . CR --> }T 8 201263 T= -Block 7012 -T{ ROT.two_items -T| 1 2 ROT -->ERR -T{ ROT.one_item -T| 42 ROT -->ERR -T{ ROT.empty_stack -T| ROT -->ERR -T{ DEPTH.empty -T| DEPTH . CR --> }T 3 47130 T= -T{ DEPTH.one_item -T| 42 DEPTH . CR --> 42 }T 3 48091 T= -Block 7013 -T{ DEPTH.multiple -T| 1 2 3 DEPTH . CR --> 1 2 3 }T 3 50013 T= -T{ PICK.pick_0 -T| 1 2 3 0 PICK . CR -->ERR -T{ PICK.pick_1 -T| 1 2 3 1 PICK . CR --> 1 2 3 }T 3 50013 T= -T{ PICK.pick_2 -T| 1 2 3 2 PICK . CR --> 1 2 3 }T 3 49052 T= -T{ ROLL.roll_1 -T| 1 2 3 1 ROLL . . . CR --> }T 7 4767936 T= -Block 7014 -T{ ROLL.roll_2 -T| 1 2 3 2 ROLL . . . CR --> }T 7 7380224 T= -T{ ?DUP.nonzero -T| 42 ?DUP . . CR --> }T 7 15838026 T= -T{ ?DUP.negative -T| -5 ?DUP . . CR --> }T 7 12677898 T= -T{ ?DUP.zero -T| 0 ?DUP DEPTH . CR --> 0 }T 3 48091 T= -T{ ?DUP.empty_stack -T| ?DUP -->ERR -Block 7015 -T{ >R.basic -T| : RS1 42 >R R@ . R> . CR ; RS1 --> }T 7 15838026 T= -T{ >R.zero -T| : RS2 0 >R R@ . R> . CR ; RS2 --> }T 5 11775018 T= -T{ >R.negative -T| : RS3 -123 >R R@ . R> . CR ; RS3 --> }T 11 14101290 T= -T{ >R.multiple -T| : RS4 1 2 >R >R R@ . R> . R@ . R> . CR ; RS4 --> }T 9 12265744 T= -T{ >R.empty_stack -T| >R -->ERR -Block 7016 -T{ R>.basic -T| : RS5 42 >R R> . CR ; RS5 --> }T 4 1598184 T= -T{ R>.lifo_order -T| : RS6 1 2 >R >R R> . R> . CR ; RS6 --> }T 5 12700461 T= -T{ R>.empty_rstack -T| R> -->ERR -T{ R@.basic -T| : RS7 42 >R R@ . R> DROP CR ; RS7 --> }T 4 1598184 T= -T{ R@.non_destructive -T| : RS8 99 >R R@ R@ = . R> DROP CR ; RS8 --> }T 4 1388686 T= -Block 7017 -T{ R@.empty_rstack -T| R@ -->ERR -T{ !.basic -T| 42 HERE ! HERE @ . CR --> }T 4 1598184 T= -T{ !.zero -T| 0 HERE ! HERE @ . CR --> }T 3 47130 T= -T{ !.negative -T| -999 HERE ! HERE @ . CR --> }T 6 529078 T= -T{ !.overwrite -T| 111 HERE ! 222 HERE ! HERE @ . CR --> }T 5 14160220 T= -Block 7018 -T{ !.max_int -T| 2147483647 HERE ! HERE @ . CR --> }T 12 4848918 T= -T{ !.min_int -T| -2147483648 HERE ! HERE @ . CR --> }T 13 5383556 T= -T{ !.empty_stack -T| ! -->ERR -T{ !.one_item -T| 42 ! -->ERR -T{ @.after_store -T| 123 HERE ! HERE @ . CR --> }T 5 13237660 T= -Block 7019 -T{ @.multiple_reads -T| 456 HERE ! HERE @ HERE @ = . CR --> }T 4 1388686 T= -T{ @.empty_stack -T| @ -->ERR -T{ ,.basic -T| 42 , HERE 1 - @ . CR --> }T 4 1598184 T= -T{ ,.negative -T| -999 , HERE 1 - @ . CR --> }T 6 529078 T= -T{ HERE.basic -T| HERE HERE = . CR --> }T 4 1388686 T= -Block 7020 -T{ HERE.after_comma -T| HERE 42 , HERE SWAP - 1 CELLS = 0 SWAP / --> 0 }T 0 0 T= -T{ ALLOT.basic -T| HERE 10 ALLOT HERE SWAP - . CR --> }T 4 1506889 T= -T{ ALLOT.zero -T| HERE 0 ALLOT HERE SWAP - . CR --> }T 3 47130 T= -T{ ALLOT.negative -T| HERE -4 ALLOT HERE SWAP - . CR --> }T 4 1391569 T= -T{ PAD.basic -T| PAD PAD = . CR --> }T 4 1388686 T= -Block 7021 -T{ PAD.different_from_here -T| PAD HERE = . CR --> }T 3 47130 T= -T{ +!.basic -T| 10 HERE ! 5 HERE +! HERE @ . CR --> }T 4 1511694 T= -T{ +!.by_zero -T| 42 HERE ! 0 HERE +! HERE @ . CR --> }T 4 1598184 T= -T{ +!.negative -T| 10 HERE ! -3 HERE +! HERE @ . CR --> }T 3 53857 T= -T{ +!.accumulate -T| 0 HERE ! 1 HERE +! 2 HERE +! 3 HERE +! HERE @ . CR --> }T 3 52896 T= -Block 7022 -T{ +!.empty_stack -T| +! -->ERR -T{ FILL.zero_n -T| HERE 0 88 FILL --> }T 0 0 T= -T{ FILL.empty_stack -T| FILL -->ERR -T{ MOVE.basic -T| 65 HERE ! 66 HERE 1+ ! HERE HERE 16 + 2 MOVE HERE 16 + @ . -T| HERE 17 + @ . CR --> }T 7 14525291 T= -T{ MOVE.zero_n -T| HERE HERE 8 + 0 MOVE --> }T 0 0 T= -Block 7023 -T{ MOVE.empty_stack -T| MOVE -->ERR -T{ +.basic -T| 5 7 + . CR --> }T 4 1508811 T= -T{ +.zero_add -T| 42 0 + . CR --> }T 4 1598184 T= -T{ +.negative -T| -5 3 + . CR --> }T 4 1389647 T= -T{ +.both_negative -T| -5 -3 + . CR --> }T 4 1395413 T= -Block 7024 -T{ +.overflow -T| 2147483647 1 + . CR --> }T 12 4849879 T= -T{ +.underflow -T| -2147483648 -1 + . CR --> }T 13 5384517 T= -T{ +.empty_stack -T| + -->ERR -T{ +.one_item -T| 42 + -->ERR -T{ -.basic -T| 10 3 - . CR --> }T 3 53857 T= -Block 7025 -T{ -.zero_sub -T| 42 0 - . CR --> }T 4 1598184 T= -T{ -.from_zero -T| 0 5 - . CR --> }T 4 1392530 T= -T{ -.negative -T| 5 -3 - . CR --> }T 3 54818 T= -T{ -.same_values -T| 42 42 - . CR --> }T 3 47130 T= -T{ -.overflow -T| -2147483648 1 - . CR --> }T 13 5384517 T= -Block 7026 -T{ -.underflow -T| 2147483647 -1 - . CR --> }T 12 4849879 T= -T{ -.empty_stack -T| - -->ERR -T{ -.one_item -T| 42 - -->ERR -T{ *.basic -T| 6 7 * . CR --> }T 4 1598184 T= -T{ *.by_zero -T| 42 0 * . CR --> }T 3 47130 T= -Block 7027 -T{ *.by_one -T| 42 1 * . CR --> }T 4 1598184 T= -T{ *.by_negative -T| 6 -7 * . CR --> }T 5 9602197 T= -T{ *.negative_negative -T| -6 -7 * . CR --> }T 4 1598184 T= -T{ *.large_numbers -T| 32767 2 * . CR --> }T 7 273505 T= -T{ *.overflow -T| 65536 65536 * . CR --> }T 12 6984600 T= -Block 7028 -T{ *.empty_stack -T| * -->ERR -T{ *.one_item -T| 42 * -->ERR -T{ /.basic -T| 15 3 / . CR --> }T 3 51935 T= -T{ /.by_one -T| 42 1 / . CR --> }T 4 1598184 T= -T{ /.negative_dividend -T| -15 3 / . CR --> }T 4 1392530 T= -Block 7029 -T{ /.negative_divisor -T| 15 -3 / . CR --> }T 4 1392530 T= -T{ /.both_negative -T| -15 -3 / . CR --> }T 3 51935 T= -T{ /.truncation -T| 7 3 / . CR --> }T 3 49052 T= -T{ /.by_zero -T| 42 0 / -->ERR -T{ /.empty_stack -T| / -->ERR -Block 7030 -T{ /.one_item -T| 42 / -->ERR -T{ MOD.basic -T| 17 5 MOD . CR --> }T 3 49052 T= -T{ MOD.exact_division -T| 15 3 MOD . CR --> }T 3 47130 T= -T{ MOD.by_one -T| 42 1 MOD . CR --> }T 3 47130 T= -T{ MOD.negative_dividend -T| -17 5 MOD . CR --> }T 4 1389647 T= -Block 7031 -T{ MOD.negative_divisor -T| 17 -5 MOD . CR --> }T 3 49052 T= -T{ MOD.small_by_large -T| 3 7 MOD . CR --> }T 3 50013 T= -T{ MOD.by_zero -T| 42 0 MOD -->ERR -T{ MOD.empty_stack -T| MOD -->ERR -T{ MOD.one_item -T| 42 MOD -->ERR -Block 7032 -T{ /MOD.basic -T| 17 5 /MOD . . CR --> }T 5 14547503 T= -T{ /MOD.exact -T| 15 3 /MOD . . CR --> }T 5 16392623 T= -T{ /MOD.negative -T| -17 5 /MOD . . CR --> }T 7 5748361 T= -T{ /MOD.by_zero -T| 42 0 /MOD -->ERR -T{ /MOD.empty_stack -T| /MOD -->ERR -Block 7033 -T{ /MOD.one_item -T| 42 /MOD -->ERR -T{ ABS.positive -T| 42 ABS . CR --> }T 4 1598184 T= -T{ ABS.negative -T| -42 ABS . CR --> }T 4 1598184 T= -T{ ABS.zero -T| 0 ABS . CR --> }T 3 47130 T= -T{ ABS.min_int -T| -2147483648 ABS . CR --> }T 12 4849879 T= -Block 7034 -T{ ABS.empty_stack -T| ABS -->ERR -T{ NEGATE.positive -T| 42 NEGATE . CR --> }T 5 9602197 T= -T{ NEGATE.negative -T| -42 NEGATE . CR --> }T 4 1598184 T= -T{ NEGATE.zero -T| 0 NEGATE . CR --> }T 3 47130 T= -T{ NEGATE.min_int -T| -2147483648 NEGATE . CR --> }T 12 4849879 T= -Block 7035 -T{ NEGATE.empty_stack -T| NEGATE -->ERR -T{ MIN.basic -T| 5 3 MIN . CR --> }T 3 50013 T= -T{ MIN.equal -T| 42 42 MIN . CR --> }T 4 1598184 T= -T{ MIN.negative -T| -5 -3 MIN . CR --> }T 4 1392530 T= -T{ MIN.mixed -T| -1 1 MIN . CR --> }T 4 1388686 T= -Block 7036 -T{ MIN.one_item -T| 42 MIN -->ERR -T{ MIN.empty_stack -T| MIN -->ERR -T{ MAX.basic -T| 5 3 MAX . CR --> }T 3 51935 T= -T{ MAX.equal -T| 42 42 MAX . CR --> }T 4 1598184 T= -T{ MAX.negative -T| -5 -3 MAX . CR --> }T 4 1390608 T= -Block 7037 -T{ MAX.mixed -T| -1 1 MAX . CR --> }T 3 48091 T= -T{ MAX.one_item -T| 42 MAX -->ERR -T{ MAX.empty_stack -T| MAX -->ERR -T{ 1+.basic -T| 5 1+ . CR --> }T 3 52896 T= -T{ 1+.zero -T| 0 1+ . CR --> }T 3 48091 T= -Block 7038 -T{ 1+.negative -T| -1 1+ . CR --> }T 3 47130 T= -T{ 1+.chain -T| 3 1+ 1+ 1+ . CR --> }T 3 52896 T= -T{ 1+.overflow -T| 2147483647 1+ . CR --> }T 12 4849879 T= -T{ 1+.empty_stack -T| 1+ -->ERR -T{ 1-.basic -T| 5 1- . CR --> }T 3 50974 T= -Block 7039 -T{ 1-.to_zero -T| 1 1- . CR --> }T 3 47130 T= -T{ 1-.to_negative -T| 0 1- . CR --> }T 4 1388686 T= -T{ 1-.chain -T| 6 1- 1- 1- . CR --> }T 3 50013 T= -T{ 1-.underflow -T| -2147483648 1- . CR --> }T 13 5384517 T= -T{ 1-.empty_stack -T| 1- -->ERR -Block 7040 -T{ 2+.basic -T| 5 2+ . CR --> }T 3 53857 T= -T{ 2+.zero -T| 0 2+ . CR --> }T 3 49052 T= -T{ 2+.negative -T| -3 2+ . CR --> }T 4 1388686 T= -T{ 2+.empty_stack -T| 2+ -->ERR -T{ 2-.basic -T| 7 2- . CR --> }T 3 51935 T= -Block 7041 -T{ 2-.zero -T| 2 2- . CR --> }T 3 47130 T= -T{ 2-.negative -T| 0 2- . CR --> }T 4 1389647 T= -T{ 2-.empty_stack -T| 2- -->ERR -T{ AND.both_true -T| -1 -1 AND . CR --> }T 4 1388686 T= -T{ AND.first_false -T| 0 -1 AND . CR --> }T 3 47130 T= -Block 7042 -T{ AND.second_false -T| -1 0 AND . CR --> }T 3 47130 T= -T{ AND.both_false -T| 0 0 AND . CR --> }T 3 47130 T= -T{ AND.bitwise -T| 85 51 AND . CR --> }T 4 1513616 T= -T{ AND.empty_stack -T| AND -->ERR -T{ AND.one_item -T| 42 AND -->ERR -Block 7043 -T{ OR.both_true -T| -1 -1 OR . CR --> }T 4 1388686 T= -T{ OR.first_false -T| 0 -1 OR . CR --> }T 4 1388686 T= -T{ OR.second_false -T| -1 0 OR . CR --> }T 4 1388686 T= -T{ OR.both_false -T| 0 0 OR . CR --> }T 3 47130 T= -T{ OR.bitwise -T| 85 51 OR . CR --> }T 5 13213635 T= -Block 7044 -T{ OR.empty_stack -T| OR -->ERR -T{ OR.one_item -T| 42 OR -->ERR -T{ XOR.both_true -T| -1 -1 XOR . CR --> }T 3 47130 T= -T{ XOR.first_false -T| 0 -1 XOR . CR --> }T 4 1388686 T= -T{ XOR.second_false -T| -1 0 XOR . CR --> }T 4 1388686 T= -Block 7045 -T{ XOR.both_false -T| 0 0 XOR . CR --> }T 3 47130 T= -T{ XOR.bitwise -T| 85 51 XOR . CR --> }T 5 13177117 T= -T{ XOR.empty_stack -T| XOR -->ERR -T{ XOR.one_item -T| 42 XOR -->ERR -T{ NOT.true -T| -1 NOT . CR --> }T 3 47130 T= -Block 7046 -T{ NOT.false -T| 0 NOT . CR --> }T 4 1388686 T= -T{ NOT.positive -T| 42 NOT . CR --> }T 3 47130 T= -T{ NOT.negative -T| -42 NOT . CR --> }T 3 47130 T= -T{ NOT.empty_stack -T| NOT -->ERR -T{ =.equal -T| 42 42 = . CR --> }T 4 1388686 T= -Block 7047 -T{ =.not_equal -T| 42 43 = . CR --> }T 3 47130 T= -T{ =.zero_equal -T| 0 0 = . CR --> }T 4 1388686 T= -T{ =.negative_equal -T| -42 -42 = . CR --> }T 4 1388686 T= -T{ =.negative_positive -T| -42 42 = . CR --> }T 3 47130 T= -T{ =.empty_stack -T| = -->ERR -Block 7048 -T{ =.one_item -T| 42 = -->ERR -T{ <.less_than -T| 5 7 < . CR --> }T 4 1388686 T= -T{ <.greater_than -T| 7 5 < . CR --> }T 3 47130 T= -T{ <.equal -T| 5 5 < . CR --> }T 3 47130 T= -T{ <.negative_positive -T| -5 5 < . CR --> }T 4 1388686 T= -Block 7049 -T{ <.negative_negative -T| -7 -5 < . CR --> }T 4 1388686 T= -T{ <.empty_stack -T| < -->ERR -T{ <.one_item -T| 42 < -->ERR -T{ >.greater_than -T| 7 5 > . CR --> }T 4 1388686 T= -T{ >.less_than -T| 5 7 > . CR --> }T 3 47130 T= -Block 7050 -T{ >.equal -T| 5 5 > . CR --> }T 3 47130 T= -T{ >.positive_negative -T| 5 -5 > . CR --> }T 4 1388686 T= -T{ >.negative_negative -T| -5 -7 > . CR --> }T 4 1388686 T= -T{ >.empty_stack -T| > -->ERR -T{ >.one_item -T| 42 > -->ERR -Block 7051 -T{ 0=.zero -T| 0 0= . CR --> }T 4 1388686 T= -T{ 0=.positive -T| 42 0= . CR --> }T 3 47130 T= -T{ 0=.negative -T| -42 0= . CR --> }T 3 47130 T= -T{ 0=.empty_stack -T| 0= -->ERR -T{ 0<.negative -T| -42 0< . CR --> }T 4 1388686 T= -Block 7052 -T{ 0<.zero -T| 0 0< . CR --> }T 3 47130 T= -T{ 0<.positive -T| 42 0< . CR --> }T 3 47130 T= -T{ 0<.empty_stack -T| 0< -->ERR -T{ 0>.positive -T| 42 0> . CR --> }T 4 1388686 T= -T{ 0>.zero -T| 0 0> . CR --> }T 3 47130 T= -Block 7053 -T{ 0>.negative -T| -42 0> . CR --> }T 3 47130 T= -T{ 0>.empty_stack -T| 0> -->ERR -T{ U<.less -T| 3 5 U< . CR --> }T 4 1388686 T= -T{ U<.equal -T| 5 5 U< . CR --> }T 3 47130 T= -T{ U<.greater -T| 7 5 U< . CR --> }T 3 47130 T= -Block 7054 -T{ U<.zero_one -T| 0 1 U< . CR --> }T 4 1388686 T= -T{ U<.empty_stack -T| U< -->ERR -T{ */.basic -T| 6 7 4 */ . CR --> }T 4 1506889 T= -T{ */.exact_division -T| 12 5 3 */ . CR --> }T 4 1536680 T= -T{ */.zero_multiply -T| 0 999 123 */ . CR --> }T 3 47130 T= -Block 7055 -T{ */.by_one -T| 42 5 1 */ . CR --> }T 5 14128507 T= -T{ */.truncation -T| 7 3 2 */ . CR --> }T 4 1506889 T= -T{ */.negative_multiply -T| -6 7 4 */ . CR --> }T 5 9510902 T= -T{ */.negative_divisor -T| 6 7 -4 */ . CR --> }T 5 9510902 T= -T{ */.div_by_zero -T| 6 7 0 */ -->ERR -Block 7056 -T{ */.empty_stack -T| */ -->ERR -T{ */.two_items -T| 1 2 */ -->ERR -T{ */MOD.basic -T| 17 3 5 */MOD . . CR --> }T 6 5318234 T= -T{ */MOD.exact_division -T| 15 4 3 */MOD . . CR --> }T 6 391992 T= -T{ */MOD.zero_multiply -T| 0 999 123 */MOD . . CR --> }T 5 11775018 T= -Block 7057 -T{ */MOD.by_one -T| 42 5 1 */MOD . . CR --> }T 7 4765003 T= -T{ */MOD.remainder -T| 7 8 5 */MOD . . CR --> }T 6 6241755 T= -T{ */MOD.negative -T| -7 3 4 */MOD . . CR --> }T 7 12674054 T= -T{ */MOD.div_by_zero -T| 6 7 0 */MOD -->ERR -T{ */MOD.empty_stack -T| */MOD -->ERR -Block 7058 -T{ D+.basic -T| 100 200 300 400 D+ . . CR --> }T 9 6378548 T= -T{ D+.zero_add -T| 42 99 0 0 D+ . . CR --> }T 7 6471656 T= -T{ D+.negative -T| -100 -200 50 75 D+ . . CR --> }T 10 13971193 T= -T{ D+.carry -T| 2147483647 0 1 0 D+ . . CR --> }T 14 4234951 T= -T{ D+.both_negative -T| -100 -200 -300 -400 D+ . . CR --> }T 11 5003369 T= -Block 7059 -T{ D+.three_items -T| 1 2 3 D+ -->ERR -T{ D+.empty_stack -T| D+ -->ERR -T{ DNEGATE.positive -T| 100 200 DNEGATE . . CR --> }T 11 13922440 T= -T{ DNEGATE.negative -T| -100 -200 DNEGATE . . CR --> }T 9 14912460 T= -T{ DNEGATE.zero -T| 0 0 DNEGATE . . CR --> }T 5 11775018 T= -Block 7060 -T{ DNEGATE.max_positive -T| 2147483647 0 DNEGATE . . CR --> }T 16 11447367 T= -T{ DNEGATE.one_item -T| 42 DNEGATE -->ERR -T{ DNEGATE.empty_stack -T| DNEGATE -->ERR -T{ D<.less_than -T| 100 200 300 400 D< . CR --> }T 4 1388686 T= -T{ D<.greater_than -T| 300 400 100 200 D< . CR --> }T 3 47130 T= -Block 7061 -T{ D<.equal -T| 100 200 100 200 D< . CR --> }T 3 47130 T= -T{ D<.negative_positive -T| -100 -1 100 0 D< . CR --> }T 4 1388686 T= -T{ D<.negative_negative -T| -300 -1 -100 -1 D< . CR --> }T 4 1388686 T= -T{ D<.high_word_diff -T| 100 200 100 300 D< . CR --> }T 4 1388686 T= -T{ D<.three_items -T| 1 2 3 D< -->ERR -Block 7062 -T{ D<.empty_stack -T| D< -->ERR -T{ BASE.decimal -T| DECIMAL 42 . CR --> }T 4 1598184 T= -T{ BASE.hex -T| HEX FF . CR --> }T 4 2153642 T= -T{ BASE.octal -T| OCTAL 52 . CR --> }T 4 1627975 T= -T{ BASE.base_store -T| 16 BASE ! 255 . CR --> }T 5 14252476 T= -Block 7063 -T{ BASE.base_fetch -T| BASE @ . CR --> }T 4 1506889 T= -T{ DECIMAL.from_hex -T| HEX FF DECIMAL . CR --> }T 5 14252476 T= -T{ DECIMAL.from_octal -T| OCTAL 52 DECIMAL . CR --> }T 4 1598184 T= -T{ DECIMAL.state_persist -T| DECIMAL 42 . CR 42 . CR HEX 42 . CR --> }T 12 9440440 T= -T{ <#.basic -T| DECIMAL 42 S>D <# #S #> TYPE CR --> }T 3 51532 T= -Block 7064 -T{ <#.empty -T| 0 0 <# #> TYPE CR --> }T 1 10 T= -T{ <#.negative -T| -42 DUP ABS 0 <# #S ROT SIGN #> TYPE CR --> }T 4 1392127 T= -T{ #.single_digit -T| 15 0 <# # #> TYPE CR --> }T 2 1653 T= -T{ #.multiple -T| 15 0 <# # # #> TYPE CR --> }T 3 48742 T= -T{ #.zero_pad -T| 5 0 <# # # #> TYPE CR --> }T 3 47781 T= -Block 7065 -T{ #S.basic -T| 42 0 <# #S #> TYPE CR --> }T 3 51532 T= -T{ #S.zero -T| 0 0 <# #S #> TYPE CR --> }T 2 1498 T= -T{ #S.large -T| 1234567890 0 <# #S #> TYPE CR --> }T 11 7265487 T= -T{ SIGN.negative -T| -42 DUP ABS 0 <# #S ROT SIGN #> TYPE CR --> }T 4 1392127 T= -T{ SIGN.positive -T| 42 DUP ABS 0 <# #S ROT SIGN #> TYPE CR --> }T 3 51532 T= -Block 7066 -T{ SIGN.zero -T| 0 DUP ABS 0 <# #S ROT SIGN #> TYPE CR --> }T 2 1498 T= -T{ #>.normal -T| 42 0 <# #S #> TYPE CR --> }T 3 51532 T= -T{ #>.empty -T| 0 0 <# #> TYPE CR --> }T 1 10 T= -T{ #>.stack_effect -T| 42 0 <# #S #> SWAP DROP . CR --> }T 3 49052 T= -T{ HOLD.basic -T| 42 0 <# 46 HOLD #S #> TYPE CR --> }T 4 1598618 T= -Block 7067 -T{ HOLD.overflow -T| <# 257 HOLD #> -->ERR -T{ COUNT.basic -T| 4 PAD C! PAD COUNT . PAD - . CR --> }T 5 15470063 T= -T{ COUNT.empty -T| 0 PAD C! PAD COUNT . PAD - . CR --> }T 5 11775979 T= -T{ COUNT.max_length -T| 255 PAD C! PAD COUNT . PAD - . CR --> }T 7 6459661 T= -T{ COUNT.empty_stack -T| COUNT -->ERR -Block 7068 -T{ -TRAILING.basic -T| HERE S" Test " -TRAILING TYPE CR --> 1 }TD 6 6975864 T= -T{ -TRAILING.all_spaces -T| HERE S" " -TRAILING TYPE CR --> 1 }TD 1 10 T= -T{ -TRAILING.no_spaces -T| HERE S" Test" -TRAILING TYPE CR --> 1 }TD 5 13589912 T= -T{ -TRAILING.empty -T| HERE 0 -TRAILING TYPE CR --> }T 1 10 T= -T{ CMOVE.basic -T| 65 PAD C! 66 PAD 1+ C! PAD PAD 10 + 2 CMOVE PAD 10 + C@ . PAD -T| 11 + C@ . CR --> }T 7 14525291 T= -Block 7069 -T{ CMOVE.empty -T| HERE HERE 10 + 0 CMOVE --> }T 0 0 T= -T{ >IN.initial -T| >IN @ . CR --> }T 3 55779 T= -T{ >IN.advances -T| : TWIN >IN @ >IN @ - . CR ; TWIN --> }T 3 47130 T= -T{ ..positive -T| 42 . CR --> }T 4 1598184 T= -T{ ..negative -T| -42 . CR --> }T 5 9602197 T= -Block 7070 -T{ ..zero -T| 0 . CR --> }T 3 47130 T= -T{ ..max_int -T| 2147483647 . CR --> }T 12 4848918 T= -T{ ..min_int -T| -2147483648 . CR --> }T 13 5383556 T= -T{ ..multiple -T| 1 2 3 . . . CR --> }T 7 4767936 T= -T{ ..empty_stack -T| . -->ERR -Block 7071 -T{ CR.basic -T| 42 . CR 43 . CR --> }T 8 16061841 T= -T{ CR.multiple -T| CR CR CR --> }T 3 9930 T= -T{ CR.no_stack_effect -T| DEPTH CR DEPTH = . CR --> }T 4 345040 T= -T{ CR.after_output -T| 1 2 3 . . . CR --> }T 7 4767936 T= -T{ SPACE.basic -T| 42 . SPACE 43 . CR --> }T 8 2824871 T= -Block 7072 -T{ SPACE.multiple -T| SPACE SPACE SPACE --> }T 3 31776 T= -T{ SPACE.no_stack_effect -T| DEPTH SPACE DEPTH = . CR --> }T 4 1000442 T= -T{ SPACE.with_text -T| 65 EMIT SPACE 66 EMIT CR --> }T 4 1969223 T= -T{ SPACES.zero -T| 0 SPACES --> }T 0 0 T= -T{ SPACES.one -T| 1 SPACES --> }T 1 32 T= -Block 7073 -T{ SPACES.multiple -T| 5 SPACES --> }T 5 13760544 T= -T{ SPACES.large -T| 20 SPACES --> }T 20 10692608 T= -T{ SPACES.negative -T| -5 SPACES --> }T 0 0 T= -T{ SPACES.with_output -T| 42 . 3 SPACES 43 . CR --> }T 10 11278119 T= -T{ SPACES.empty_stack -T| SPACES -->ERR -Block 7074 -T{ EMIT.letter_A -T| 65 EMIT CR --> }T 2 2025 T= -T{ EMIT.letter_Z -T| 90 EMIT CR --> }T 2 2800 T= -T{ EMIT.digit -T| 48 EMIT CR --> }T 2 1498 T= -T{ EMIT.space_char -T| 32 EMIT CR --> }T 2 1002 T= -T{ EMIT.newline -T| 10 EMIT --> }T 1 10 T= -Block 7075 -T{ EMIT.high_ascii -T| 127 EMIT CR --> }T 2 3947 T= -T{ EMIT.truncation -T| 321 EMIT CR --> }T 2 2025 T= -T{ EMIT.negative -T| -1 EMIT CR --> }T 2 7915 T= -T{ EMIT.sequence -T| 72 EMIT 73 EMIT 10 EMIT --> }T 3 71465 T= -T{ EMIT.empty_stack -T| EMIT -->ERR -Block 7076 -T{ TYPE.basic_string -T| 72 PAD C! 105 PAD 1+ C! PAD 2 TYPE CR --> }T 3 72457 T= -T{ TYPE.empty_string -T| HERE 0 TYPE CR --> }T 1 10 T= -T{ TYPE.numbers -T| 49 PAD C! 50 PAD 1+ C! PAD 2 TYPE CR --> }T 3 48649 T= -T{ TYPE.zero_length -T| PAD 0 TYPE --> }T 0 0 T= -T{ TYPE.one_item -T| PAD TYPE -->ERR -Block 7077 -T{ TYPE.empty_stack -T| TYPE -->ERR -T{ COUNT.basic~2 -T| 4 PAD C! PAD COUNT . PAD - . CR --> }T 5 15470063 T= -T{ COUNT.empty~2 -T| 0 PAD C! PAD COUNT . PAD - . CR --> }T 5 11775979 T= -T{ COUNT.max_length~2 -T| 255 PAD C! PAD COUNT . PAD - . CR --> }T 7 6459661 T= -T{ COUNT.empty_stack~2 -T| COUNT -->ERR -Block 7078 -T{ WORD.empty_stack -T| WORD -->ERR -T{ BLOCK.basic -T| 1 BLOCK DUP . CR --> 1 }TD -T{ BLOCK.zero_block -T| 0 BLOCK -->ERR -T{ BLOCK.large_block -T| 65536 BLOCK -->ERR -T{ BLOCK.negative -T| -1 BLOCK -->ERR -Block 7079 -T{ BLOCK.empty_stack -T| BLOCK -->ERR -T{ BUFFER.basic -T| 1 BUFFER DUP . CR --> 1 }TD -T{ BUFFER.zero_block -T| 0 BUFFER -->ERR -T{ BUFFER.flush_dirty -T| 2 BLOCK 1+ 2 BUFFER --> 2 }TD 0 0 T= -T{ BUFFER.empty_stack -T| BUFFER -->ERR -Block 7080 -T{ UPDATE.basic -T| 1 BLOCK UPDATE --> 1 }TD 0 0 T= -T{ UPDATE.multiple -T| 1 BLOCK UPDATE UPDATE --> 1 }TD 0 0 T= -T{ UPDATE.no_block -T| 0 SCR ! UPDATE --> }T 0 0 T= -T{ SAVE-BUFFERS.basic -T| SAVE-BUFFERS --> }T 0 0 T= -T{ SAVE-BUFFERS.dirty_blocks -T| 1 BLOCK UPDATE SAVE-BUFFERS --> 1 }TD 0 0 T= -Block 7081 -T{ SAVE-BUFFERS.no_dirty -T| SAVE-BUFFERS --> }T 0 0 T= -T{ EMPTY-BUFFERS.basic -T| EMPTY-BUFFERS --> }T 0 0 T= -T{ EMPTY-BUFFERS.after_use -T| 1 BLOCK EMPTY-BUFFERS --> 1 }TD 0 0 T= -T{ EMPTY-BUFFERS.dirty_blocks -T| 1 BLOCK UPDATE EMPTY-BUFFERS --> 1 }TD 0 0 T= -T{ LOAD.basic -T| 1 LOAD --> }T 0 0 T= -Block 7082 -T{ LOAD.zero_block -T| 0 LOAD -->ERR -T{ LOAD.nonexistent -T| 9999 LOAD -->ERR -T{ LOAD.empty_stack -T| LOAD -->ERR -T{ LIST.basic -T| 1 LIST --> 0 }TD -T{ LIST.zero_block -T| 0 LIST -->ERR -Block 7083 -T{ LIST.nonexistent -T| 9999 LIST -->ERR -T{ LIST.empty_stack -T| LIST -->ERR -T{ SCR.basic -T| SCR @ . CR --> }T 3 48091 T= -T{ SCR.after_list -T| 1 LIST SCR @ . CR --> 0 }TD -T{ SCR.after_load -T| 1 LOAD SCR @ . CR --> }T 3 48091 T= -Block 7084 -T{ HERE.basic~2 -T| HERE HERE = . CR --> }T 4 1388686 T= -T{ HERE.after_comma~2 -T| HERE 42 , HERE SWAP - 1 CELLS = 0 SWAP / --> 0 }T 0 0 T= -T{ HERE.after_c_comma -T| HERE 65 C, HERE SWAP - . CR --> }T 3 48091 T= -T{ HERE.after_allot -T| HERE 10 ALLOT HERE SWAP - . CR --> }T 4 1506889 T= -T{ HERE.stability -T| HERE DUP HERE = . CR --> 1 }TD 4 1388686 T= -Block 7085 -T{ ALLOT.basic~2 -T| HERE 10 ALLOT HERE SWAP - . CR --> }T 4 1506889 T= -T{ ALLOT.zero~2 -T| HERE 0 ALLOT HERE SWAP - . CR --> }T 3 47130 T= -T{ ALLOT.negative~2 -T| HERE -4 ALLOT HERE SWAP - . CR --> }T 4 1391569 T= -T{ ALLOT.large -T| HERE 100 ALLOT HERE SWAP - . CR --> }T 5 13175195 T= -T{ ALLOT.after_use -T| ALIGN HERE 10 ALLOT 42 OVER ! @ . CR --> }T 4 1598184 T= -Block 7086 -T{ ALLOT.empty_stack -T| ALLOT -->ERR -T{ ,.basic~2 -T| 42 , HERE 1 CELLS - @ . CR --> }T 4 1598184 T= -T{ ,.negative~2 -T| -999 , HERE 1 CELLS - @ . CR --> }T 6 529078 T= -T{ ,.zero -T| 0 , HERE 1 CELLS - @ . CR --> }T 3 47130 T= -T{ ,.max_int -T| 2147483647 , HERE 1 CELLS - @ . CR --> }T 12 4848918 T= -Block 7087 -T{ ,.min_int -T| -2147483648 , HERE 1 CELLS - @ . CR --> }T 13 5383556 T= -T{ ,.multiple -T| 10 , 20 , HERE 1 CELLS - @ . HERE 1 CELLS - @ . CR --> }T 7 12227402 T= -T{ ,.empty_stack -T| , -->ERR -T{ PAD.basic~2 -T| PAD PAD = . CR --> }T 4 1388686 T= -T{ PAD.different_from_here~2 -T| PAD HERE = . CR --> }T 3 47130 T= -Block 7088 -T{ PAD.stability -T| PAD DUP PAD = . CR --> 1 }TD 4 1388686 T= -T{ CREATE.basic -T| CREATE test1 42 , test1 @ . CR --> }T 4 1598184 T= -T{ CREATE.empty_name -T| CREATE -->ERR -T{ CREATE.redefine_shadows -T| CREATE T 1 , CREATE T 2 , T @ . CR --> }T 3 49052 T= -T{ CREATE.duplicate -T| CREATE test2 CREATE test2 --> }T 0 0 T= -Block 7089 -T{ CREATE.long_name -T| CREATE abcdefghijklmnopqrstuvwxyz --> }T 0 0 T= -T{ FORGET.basic -T| CREATE temp1 FORGET temp1 --> }T 0 0 T= -T{ IMMEDIATE.basic -T| : test3 42 ; IMMEDIATE test3 . CR --> }T 4 1598184 T= -T{ IMMEDIATE.already_immediate -T| : test4 43 ; IMMEDIATE IMMEDIATE --> }T 0 0 T= -T{ FIND.existing -T| FIND DUP . CR --> 0 }TD -Block 7090 -T{ FIND.user_word -T| : test5 44 ; FIND test5 . CR --> 0 }TD -T{ FIND.nonexistent -T| FIND nonexistent . CR --> }T 3 47130 T= -T{ FIND.empty -T| FIND --> 0 }T 0 0 T= -T{ DEFINITIONS.basic -T| FORTH DEFINITIONS --> }T 0 0 T= -T{ DEFINITIONS.multiple -T| FORTH DEFINITIONS DEFINITIONS --> }T 0 0 T= -Block 7091 -T{ VOCABULARY.basic -T| VOCABULARY TEST-VOC1 TEST-VOC1 DEFINITIONS --> }T 0 0 T= -T{ VOCABULARY.create_and_switch -T| VOCABULARY MYVOC MYVOC DEFINITIONS CONTEXT @ . CR --> 0 }TD -T{ VOCABULARY.word_isolation -T| VOCABULARY ISOLATED ISOLATED DEFINITIONS : ISOWORD 99 ; FORTH -T| DEFINITIONS --> }T 0 0 T= -T{ VOCABULARY.cross_vocab_access -T| VOCABULARY V1 V1 DEFINITIONS : V1WORD 11 ; FORTH V1WORD . CR -->ERR -T{ VOCABULARY.multiple_vocabs -T| VOCABULARY VA VOCABULARY VB VOCABULARY VC VA DEFINITIONS --> }T 0 0 T= -Block 7092 -T{ VOCABULARY.duplicate -T| VOCABULARY TESTVOC VOCABULARY TESTVOC --> }T 0 0 T= -T{ VOCABULARY.empty_name -T| VOCABULARY -->ERR -T{ FORTH.basic -T| FORTH DEFINITIONS --> }T 0 0 T= -T{ FORTH.persistence -T| FORTH : TEST1 42 ; TEST1 . CR --> }T 4 1598184 T= -T{ FORTH.from_other -T| VOCABULARY OTHER-VOC OTHER-VOC FORTH --> }T 0 0 T= -Block 7093 -T{ DEFINITIONS.basic~2 -T| FORTH DEFINITIONS --> }T 0 0 T= -T{ DEFINITIONS.new_vocab -T| VOCABULARY TEST-VOC6 TEST-VOC6 DEFINITIONS --> }T 0 0 T= -T{ DEFINITIONS.word_creation -T| VOCABULARY TEST-VOC7 TEST-VOC7 DEFINITIONS : TEST2 43 ; --> }T 0 0 T= -T{ CONTEXT.basic -T| CONTEXT @ . CR --> 0 }TD -T{ CONTEXT.initial -T| FORTH CONTEXT @ . CR --> 0 }TD -Block 7094 -T{ CURRENT.basic -T| CURRENT @ . CR --> 0 }TD -T{ CURRENT.after_def -T| VOCABULARY TEST-VOC8 TEST-VOC8 DEFINITIONS CURRENT @ . CR --> 0 }TD -T{ ABORT.basic -T| ABORT --> }T 0 0 T= -T{ ABORT.with_data -T| 1 2 3 ABORT DEPTH . CR --> }T 0 0 T= -T{ ABORT.in_definition_runtime -T| : BAD-WORD ABORT ; 123 BAD-WORD DEPTH . CR --> }T 0 0 T= -Block 7095 -T{ :.basic -T| : TEST1 42 ; TEST1 . CR --> }T 4 1598184 T= -T{ :.empty_name -T| : -->ERR -T{ ;.alone -T| ; -->ERR -T{ ;.immediate -T| : TEST4 42 ; IMMEDIATE TEST4 . CR --> }T 4 1598184 T= -T{ CONSTANT.basic -T| 42 CONSTANT MEANING MEANING . CR --> }T 4 1598184 T= -Block 7096 -T{ CONSTANT.zero -T| 0 CONSTANT ZERO ZERO . CR --> }T 3 47130 T= -T{ CONSTANT.negative -T| -1 CONSTANT MINUS MINUS . CR --> }T 4 1388686 T= -T{ CONSTANT.empty_stack -T| CONSTANT -->ERR -T{ VARIABLE.basic -T| VARIABLE VAR1 42 VAR1 ! VAR1 @ . CR --> }T 4 1598184 T= -T{ VARIABLE.multiple -T| VARIABLE VAR2 VARIABLE VAR3 --> }T 0 0 T= -Block 7097 -T{ VARIABLE.store_fetch -T| VARIABLE VAR4 -99 VAR4 ! VAR4 @ . CR --> }T 5 9757879 T= -T{ CREATE.basic~2 -T| CREATE OBJ1 --> }T 0 0 T= -T{ CREATE.with_data -T| CREATE OBJ2 42 , OBJ2 @ . CR --> }T 4 1598184 T= -T{ CREATE.empty_name~2 -T| CREATE -->ERR -T{ DOES>.basic -T| : CONST CREATE , DOES> @ ; 42 CONST MEANING MEANING . CR --> }T 4 1598184 T= -Block 7098 -T{ DOES>.multiple -T| : ARRAY CREATE DOES> SWAP CELLS + ; CREATE ARR 10 CELLS ALLOT --> }T 0 0 T= -T{ DOES>.outside -T| DOES> -->ERR -T{ [.basic -T| : TEST5 [ 42 ] LITERAL ; TEST5 . CR --> }T 4 1598184 T= -T{ [.outside -T| [ --> }T 0 0 T= -T{ ].nested -T| : TEST6 [ ] 42 ; TEST6 . CR --> }T 4 1598184 T= -Block 7099 -T{ IF.true -T| : TEST1 IF 42 ELSE 24 THEN ; -1 TEST1 . CR --> }T 4 1598184 T= -T{ IF.false -T| : TEST2 IF 42 ELSE 24 THEN ; 0 TEST2 . CR --> }T 4 1540524 T= -T{ IF.nested -T| : TEST3 IF IF 1 ELSE 2 THEN ELSE 3 THEN ; -1 -1 TEST3 . CR --> }T 3 48091 T= -T{ IF.no_else -T| : TEST4 IF 42 THEN ; -1 TEST4 . CR --> }T 4 1598184 T= -T{ IF.empty_stack -T| IF -->ERR -Block 7100 -T{ ELSE.alone -T| ELSE -->ERR -T{ THEN.alone -T| THEN -->ERR -T{ BEGIN.until -T| : TEST5 0 BEGIN 1+ DUP 5 = UNTIL ; TEST5 . CR --> }T 3 51935 T= -T{ BEGIN.while -T| : TEST6 0 BEGIN DUP 5 < WHILE 1+ REPEAT ; TEST6 . CR --> }T 3 51935 T= -T{ BEGIN.alone -T| BEGIN -->ERR -Block 7101 -T{ UNTIL.basic -T| : TEST8 BEGIN DUP 1- DUP 0= UNTIL ; 5 TEST8 . CR --> 5 4 3 2 1 }T 3 47130 T= -T{ UNTIL.immediate -T| : TEST9 BEGIN 1 UNTIL ; IMMEDIATE --> }T 0 0 T= -T{ UNTIL.no_begin -T| UNTIL -->ERR -T{ WHILE.basic -T| : TEST10 BEGIN DUP 5 < WHILE 1+ REPEAT ; 0 TEST10 . CR --> }T 3 51935 T= -T{ WHILE.zero_times -T| : TEST11 BEGIN DUP 0< WHILE 1+ REPEAT ; 0 TEST11 . CR --> }T 3 47130 T= -Block 7102 -T{ WHILE.no_begin -T| WHILE -->ERR -T{ REPEAT.basic -T| : TEST12 BEGIN DUP 5 < WHILE 1+ REPEAT ; 0 TEST12 . CR --> }T 3 51935 T= -T{ REPEAT.no_while -T| REPEAT -->ERR -T{ DO.basic -T| : TEST13 5 0 DO I . LOOP ; TEST13 CR --> }T 11 12528484 T= -T{ DO.negative -T| : TEST14 -1 -5 DO I . LOOP ; TEST14 CR --> }T 13 11696776 T= -Block 7103 -T{ DO.empty -T| : TEST15 0 0 DO LOOP ; --> }T 0 0 T= -T{ DO.nested -T| : TEST16 3 0 DO 3 0 DO J I + . LOOP LOOP ; TEST16 CR --> }T 19 14426156 T= -T{ LOOP.basic -T| : TEST20 5 0 DO I . LOOP ; TEST20 CR --> }T 11 12528484 T= -T{ LOOP.no_do -T| LOOP -->ERR -T{ +LOOP.basic -T| : TEST21 10 0 DO I . 2 +LOOP ; TEST21 CR --> }T 11 16410222 T= -Block 7104 -T{ +LOOP.negative -T| : TEST22 0 10 DO I . -1 +LOOP ; TEST22 CR --> }T 24 15411990 T= -T{ +LOOP.variable -T| : TEST23 10 0 DO I . DUP +LOOP ; 3 TEST23 CR --> 3 }T 9 8104156 T= -T{ I.basic -T| : TI 4 0 DO I . LOOP CR ; TI --> }T 9 7781840 T= -T{ I.single -T| : TI1 1 0 DO I . LOOP CR ; TI1 --> }T 3 47130 T= -T{ I.offset -T| : TI2 5 3 DO I . LOOP CR ; TI2 --> }T 5 14549425 T= -Block 7105 -T{ I.in_expr -T| : TI3 3 0 DO I 2 * . LOOP CR ; TI3 --> }T 7 9837120 T= -T{ J.basic -T| : TJ 2 0 DO 3 0 DO J . LOOP LOOP CR ; TJ --> }T 13 4074221 T= -T{ J.paired -T| : TJ2 2 0 DO 2 0 DO J I + . LOOP LOOP CR ; TJ2 --> }T 9 6857358 T= -T{ EXIT.early_return -T| : TEX 5 EXIT 99 ; TEX . CR --> }T 3 51935 T= -T{ EXIT.cond_exit_pos -T| : TEX2 DUP 0> IF EXIT THEN NEGATE ; 3 TEX2 . CR --> }T 3 50013 T= -Block 7106 -T{ EXIT.cond_exit_neg -T| : TEX2 DUP 0> IF EXIT THEN NEGATE ; -4 TEX2 . CR --> }T 3 50974 T= -T{ EXIT.no_skipped -T| : TEX3 1 2 EXIT 3 ; TEX3 . . CR --> }T 5 13623021 T= -T{ LEAVE.basic -T| : TLV 0 5 0 DO I 3 = IF LEAVE THEN 1+ LOOP ; TLV . CR --> }T 3 50974 T= -T{ LEAVE.at_start -T| : TLV2 0 5 0 DO LEAVE 1+ LOOP ; TLV2 . CR --> }T 3 48091 T= -T{ LEAVE.qdloop -T| : TLV3 0 5 0 ?DO I 2 = IF LEAVE THEN 1+ LOOP ; TLV3 . CR --> }T 3 50013 T= -Block 7107 -T{ U*.small -T| 3 4 U* . . CR --> }T 6 12751803 T= -T{ U*.zero -T| 0 5 U* . . CR --> }T 5 11775018 T= -T{ U*.full -T| -1 -1 U* 2+ . 1 = . CR --> }T 6 12631678 T= -T{ U/MOD.small -T| 7 0 2 U/MOD . . CR --> }T 5 14546542 T= -T{ U/MOD.exact -T| 12 0 4 U/MOD . . CR --> }T 5 14545581 T= -Block 7108 -T{ U/MOD.double -T| 0 1 2 U/MOD 2* . . CR --> }T 5 11775018 T= -T{ U/MOD.inverse -T| -1 -1 U* -1 U/MOD 1+ . . CR --> }T 5 11775018 T= -T{ U/MOD.carry -T| -1 -2 -1 U/MOD 1+ . 2+ . CR --> }T 5 11775018 T= -T{ U/MOD.by_zero -T| 1 0 0 U/MOD -->ERR -T{ ?.basic -T| VARIABLE Q1 42 Q1 ! Q1 ? CR --> }T 4 1598184 T= -Block 7109 -T{ EXECUTE.found -T| : E1 7 ; FIND E1 EXECUTE . CR --> }T 3 53857 T= -T{ U..small -T| 42 U. CR --> }T 4 1598184 T= -T{ U..unsigned -T| -1 U. CR --> }T 22 3892143 T= -T{ CONVERT.digits -T| : C1 0 0 BL WORD CONVERT DROP ; C1 123 . . CR --> }T 7 9448876 T= -T{ '.found -T| ' DUP 0= . CR --> }T 3 47130 T= -Block 7110 -T{ .".in_definition -T| : Q3 ." hi there" ; Q3 CR --> }T 9 13319717 T= -T{ LITERAL.basic -T| : Q4 [ 5 ] LITERAL ; Q4 . CR --> }T 3 51935 T= -T{ STATE.interpreting -T| STATE @ . CR --> }T 3 47130 T= -T{ STATE.compiling -T| : Q5 STATE @ 0= . ; IMMEDIATE : Q6 Q5 ; CR --> }T 3 47130 T= -T{ COMPILE.basic -T| : Q7 COMPILE DUP ; IMMEDIATE : Q8 Q7 ; 3 Q8 . . CR --> }T 5 14548464 T= -Block 7111 -T{ [COMPILE].basic -T| : Q9 [COMPILE] IF ; IMMEDIATE : Q10 Q9 1 ELSE 2 THEN ; 0 Q10 -T| . -1 Q10 . CR --> }T 5 13623021 T= -T{ (.comment -T| 1 ( 2 ) 3 . . CR --> }T 5 14546542 T= -T{ BLK.terminal -T| BLK @ . CR --> }T 3 47130 T= -T{ 79-STANDARD.present -T| 79-STANDARD --> }T 0 0 T= -T{ WORD.next_word -T| : W1 BL WORD COUNT TYPE ; W1 HELLO --> }T 5 1515698 T= -Block 7112 -T{ WORD.delimiter -T| : W2 44 WORD COUNT TYPE ; W2 A B, --> }T 3 63523 T= -T{ WORD.count -T| : W3 BL WORD C@ . ; W3 ABC --> }T 2 1613 T= -T{ WORD.skips_leading -T| : W4 BL WORD COUNT TYPE ; W4 X --> }T 1 88 T= -Block 7113 -T-REPORT -FORGET T# DECIMAL diff --git a/docs/v4.0.0/MESH.md b/docs/v4.0.0/MESH.md index 3d7fb99f..ea2e8d87 100644 --- a/docs/v4.0.0/MESH.md +++ b/docs/v4.0.0/MESH.md @@ -705,8 +705,30 @@ Each is tested, committed and pushed before the next. release by asking, holes. Its acceptance is to be approved before it is built. **6b. POST is the kernel's.** Ruled 2026-10-07 (section 9); design - approved 2026-10-07, `NUCLEUS.md` 6.3 and section 7. Acceptance, as - approved: + approved 2026-10-07, `NUCLEUS.md` 6.3 and section 7. + **Done 2026-10-07.** + - *The cases* (`v4/system/post_cases.c`, written by `v4/tools/mkpost.py`): + the same 538, checked against the capsule case by case. One expected + result changed: `>IN.initial` prints 6 where it printed 9, because a + case's line no longer begins with the capsule's `T| `; the generator + now runs v3 on the lines as the kernel sends them. + - *The runner* (`v4/system/post.c`), tested in + `v4/tests/test_host_quit.c` with cases that must pass and cases that + must fail. + - *The boot* (`v4/system/boot.c`) runs it after the capsules, prints + `PARITY:V4_SYSTEM`, and seals. `capsules/v4/post79.4th`, `(CATCH)` and + `(EMIT-HOOK)` are gone. + - *Verified.* `make -C v4 test`, `sanitize` and `hosted-check`; three + bare-metal boots, `logs/20261007-105118` (amd64), `-105335` + (aarch64), `-105651` (riscv64). On all six: POST 538 of 538, + `word_count=411`, `dict_hash=0x6fb1d09418b189ee`. At the prompt `T{` + is unknown, and `RS1`, which a case defines, prints `42 42` before and + after `COLD`. A hosted program built with one case's expected output + changed names the case and ends `PARITY:FAIL`, `POST: FAILED`. + - What the cases define takes 1,385 cells of the dictionary space's + 5,632. + + Acceptance, as approved: 1. *Same verdict.* The three hosted programs and the three bare-metal boots print `PARITY:V4_POST tests=538 pass=538 fail=0`, `PARITY:V4_SYSTEM word_count=N dict_hash=0x...`, `PARITY:OK` and diff --git a/docs/v4.0.0/POST79.md b/docs/v4.0.0/POST79.md index 59853f05..60d28ae9 100644 --- a/docs/v4.0.0/POST79.md +++ b/docs/v4.0.0/POST79.md @@ -33,7 +33,7 @@ standard's and not v3's. | `+!.negative` | `10 HERE ! -3 HERE +! HERE @ . CR` | error | unchanged | stack `empty`, prints `7 \n` | v3 raises an error FORTH-79 does not ask for: a store to HERE | | `+!.accumulate` | `0 HERE ! 1 HERE +! 2 HERE +! 3 HERE +! HERE @ . CR` | error | unchanged | stack `empty`, prints `6 \n` | v3 raises an error FORTH-79 does not ask for: a store to HERE | | `HERE.after_comma~2` | `HERE 42 , HERE SWAP - 1 CELLS = 0 SWAP /` | error | unchanged | stack `0`, prints nothing | the case divides by zero unless HERE moved by one cell; on v3 it had moved by 8 | -| `MOVE.basic` | `HERE 65 OVER C! HERE 1+ 66 OVER C! HERE HERE 16 + 2 MOVE HERE 16 + C@ . HERE 17 + C@ . CR` | stack `302 303`, printed `65 66 \n` | `65 HERE ! 66 HERE 1+ ! HERE HERE 16 + 2 MOVE HERE 16 + @ . HERE 17 + @ . CR` | stack `empty`, prints `65 66 \n` | FORTH-79: MOVE moves cells; and v3's address unit is a byte; a v4 address unit is a cell (D-1) | +| `MOVE.basic` | `HERE 65 OVER C! HERE 1+ 66 OVER C! HERE HERE 16 + 2 MOVE HERE 16 + C@ . HERE 17 + C@ . CR` | stack `294 295`, printed `65 66 \n` | `65 HERE ! 66 HERE 1+ ! HERE HERE 16 + 2 MOVE HERE 16 + @ . HERE 17 + @ . CR` | stack `empty`, prints `65 66 \n` | FORTH-79: MOVE moves cells; and v3's address unit is a byte; a v4 address unit is a cell (D-1) | | `BASE.base_store` | `16 BASE ! 255 . CR` | stack `empty`, printed `597 \n` | unchanged | stack `empty`, prints `255 \n` | 255 read in base 16 and printed in base 16 is 255; v3 printed 467 | | `<#.basic` | `DECIMAL 42 S>D <# #S #> TYPE CR` | stack `empty`, printed `774763251095801167872\n` | unchanged | stack `empty`, prints `42\n` | v3 prints 774763251095801167872 for 42 S>D <# #S #> | | `<#.empty` | `0 <# #> TYPE CR` | stack `0`, printed `\n` | `0 0 <# #> TYPE CR` | stack `empty`, prints `\n` | FORTH-79: <# # #S #> work on a double number; v3 takes a single | @@ -51,20 +51,20 @@ standard's and not v3's. | `#>.empty` | `0 <# #> TYPE CR` | stack `0`, printed `\n` | `0 0 <# #> TYPE CR` | stack `empty`, prints `\n` | FORTH-79: <# # #S #> work on a double number; v3 takes a single | | `#>.stack_effect` | `42 <# #S #> SWAP . . CR` | stack `empty`, printed `24 2 \n` | `42 0 <# #S #> SWAP DROP . CR` | stack `empty`, prints `2 \n` | FORTH-79: <# # #S #> work on a double number; v3 takes a single | | `HOLD.basic` | `42 <# 46 HOLD #S #> TYPE CR` | stack `empty`, printed `42.\n` | `42 0 <# 46 HOLD #S #> TYPE CR` | stack `empty`, prints `42.\n` | FORTH-79: <# # #S #> work on a double number; v3 takes a single | -| `COUNT.basic` | `HERE S" Test" DROP COUNT . . CR` | stack `302`, printed `84 303 \n` | `4 PAD C! PAD COUNT . PAD - . CR` | stack `empty`, prints `4 1 \n` | v3's address unit is a byte; a v4 address unit is a cell (D-1); and S" is not FORTH-79 | -| `COUNT.empty` | `HERE 0 OVER C! COUNT . . CR` | stack `empty`, printed `0 308 \n` | `0 PAD C! PAD COUNT . PAD - . CR` | stack `empty`, prints `0 1 \n` | v3's address unit is a byte; a v4 address unit is a cell (D-1) | -| `COUNT.max_length` | `HERE 255 OVER C! COUNT . . CR` | stack `empty`, printed `255 308 \n` | `255 PAD C! PAD COUNT . PAD - . CR` | stack `empty`, prints `255 1 \n` | v3's address unit is a byte; a v4 address unit is a cell (D-1) | -| `COUNT.basic~2` | `HERE S" Test" DROP C@ HERE 1+ SWAP COUNT . . CR` | stack `412 418`, printed `0 85 \n` | `4 PAD C! PAD COUNT . PAD - . CR` | stack `empty`, prints `4 1 \n` | v3's address unit is a byte; a v4 address unit is a cell (D-1) | -| `COUNT.empty~2` | `HERE 0 OVER C! COUNT . . CR` | stack `empty`, printed `0 418 \n` | `0 PAD C! PAD COUNT . PAD - . CR` | stack `empty`, prints `0 1 \n` | v3's address unit is a byte; a v4 address unit is a cell (D-1) | -| `COUNT.max_length~2` | `HERE 255 OVER C! COUNT . . CR` | stack `empty`, printed `255 418 \n` | `255 PAD C! PAD COUNT . PAD - . CR` | stack `empty`, prints `255 1 \n` | v3's address unit is a byte; a v4 address unit is a cell (D-1) | -| `CMOVE.basic` | `HERE S" Test" DUP >R HERE 10 + SWAP CMOVE CR` | stack `325`, printed `\n` | `65 PAD C! 66 PAD 1+ C! PAD PAD 10 + 2 CMOVE PAD 10 + C@ . PAD 11 + C@ . CR` | stack `empty`, prints `65 66 \n` | v3's address unit is a byte; a v4 address unit is a cell (D-1); and the v3 case leaves a value on the return stack | -| `TYPE.basic_string` | `HERE S" Hello" DUP >R HERE SWAP CMOVE HERE R> TYPE CR` | stack `400`, printed `Hello\n` | `72 PAD C! 105 PAD 1+ C! PAD 2 TYPE CR` | stack `empty`, prints `Hi\n` | v3's address unit is a byte; a v4 address unit is a cell (D-1); and FORTH-79: >R R> R@ are for use inside a definition; v4 refuses them at the prompt | -| `TYPE.numbers` | `HERE S" 12345" DUP >R HERE SWAP CMOVE HERE R> TYPE CR` | stack `406`, printed `12345\n` | `49 PAD C! 50 PAD 1+ C! PAD 2 TYPE CR` | stack `empty`, prints `12\n` | v3's address unit is a byte; a v4 address unit is a cell (D-1); and FORTH-79: >R R> R@ are for use inside a definition; v4 refuses them at the prompt | -| `>IN.initial` | `>IN @ . CR` | stack `empty`, printed `860486384 \n` | unchanged | stack `empty`, prints `9 \n` | FORTH-79: >IN is the offset into the input, 9 here; v3 prints an address | +| `COUNT.basic` | `HERE S" Test" DROP COUNT . . CR` | stack `294`, printed `84 295 \n` | `4 PAD C! PAD COUNT . PAD - . CR` | stack `empty`, prints `4 1 \n` | v3's address unit is a byte; a v4 address unit is a cell (D-1); and S" is not FORTH-79 | +| `COUNT.empty` | `HERE 0 OVER C! COUNT . . CR` | stack `empty`, printed `0 300 \n` | `0 PAD C! PAD COUNT . PAD - . CR` | stack `empty`, prints `0 1 \n` | v3's address unit is a byte; a v4 address unit is a cell (D-1) | +| `COUNT.max_length` | `HERE 255 OVER C! COUNT . . CR` | stack `empty`, printed `255 300 \n` | `255 PAD C! PAD COUNT . PAD - . CR` | stack `empty`, prints `255 1 \n` | v3's address unit is a byte; a v4 address unit is a cell (D-1) | +| `COUNT.basic~2` | `HERE S" Test" DROP C@ HERE 1+ SWAP COUNT . . CR` | stack `404 410`, printed `0 85 \n` | `4 PAD C! PAD COUNT . PAD - . CR` | stack `empty`, prints `4 1 \n` | v3's address unit is a byte; a v4 address unit is a cell (D-1) | +| `COUNT.empty~2` | `HERE 0 OVER C! COUNT . . CR` | stack `empty`, printed `0 410 \n` | `0 PAD C! PAD COUNT . PAD - . CR` | stack `empty`, prints `0 1 \n` | v3's address unit is a byte; a v4 address unit is a cell (D-1) | +| `COUNT.max_length~2` | `HERE 255 OVER C! COUNT . . CR` | stack `empty`, printed `255 410 \n` | `255 PAD C! PAD COUNT . PAD - . CR` | stack `empty`, prints `255 1 \n` | v3's address unit is a byte; a v4 address unit is a cell (D-1) | +| `CMOVE.basic` | `HERE S" Test" DUP >R HERE 10 + SWAP CMOVE CR` | stack `317`, printed `\n` | `65 PAD C! 66 PAD 1+ C! PAD PAD 10 + 2 CMOVE PAD 10 + C@ . PAD 11 + C@ . CR` | stack `empty`, prints `65 66 \n` | v3's address unit is a byte; a v4 address unit is a cell (D-1); and the v3 case leaves a value on the return stack | +| `TYPE.basic_string` | `HERE S" Hello" DUP >R HERE SWAP CMOVE HERE R> TYPE CR` | stack `392`, printed `Hello\n` | `72 PAD C! 105 PAD 1+ C! PAD 2 TYPE CR` | stack `empty`, prints `Hi\n` | v3's address unit is a byte; a v4 address unit is a cell (D-1); and FORTH-79: >R R> R@ are for use inside a definition; v4 refuses them at the prompt | +| `TYPE.numbers` | `HERE S" 12345" DUP >R HERE SWAP CMOVE HERE R> TYPE CR` | stack `398`, printed `12345\n` | `49 PAD C! 50 PAD 1+ C! PAD 2 TYPE CR` | stack `empty`, prints `12\n` | v3's address unit is a byte; a v4 address unit is a cell (D-1); and FORTH-79: >R R> R@ are for use inside a definition; v4 refuses them at the prompt | +| `>IN.initial` | `>IN @ . CR` | stack `empty`, printed `657828592 \n` | unchanged | stack `empty`, prints `6 \n` | FORTH-79: >IN is the offset into the input, 6 here; v3 prints an address | | `UPDATE.no_block` | `0 SCR ! UPDATE` | error | unchanged | stack `empty`, prints nothing | v3 raises an error FORTH-79 does not ask for | | `SCR.after_load` | `1 LOAD SCR @ . CR` | stack `empty`, printed `` | unchanged | stack `empty`, prints `1 \n` | v3 prints nothing after 1 LOAD; SCR is still 1 from the LIST before | -| `FIND.existing` | `FIND DUP . CR` | stack `empty`, printed `860485744 \n` | unchanged | 0 value(s) left; output not compared | FORTH-79: FIND takes the next word, DUP here, and leaves its address, which is printed | -| `FIND.user_word` | `: test5 44 ; FIND test5 . CR` | stack `empty`, printed `860812560 \n` | unchanged | 0 value(s) left; output not compared | the address FIND leaves is printed | +| `FIND.existing` | `FIND DUP . CR` | stack `empty`, printed `657827952 \n` | unchanged | 0 value(s) left; output not compared | FORTH-79: FIND takes the next word, DUP here, and leaves its address, which is printed | +| `FIND.user_word` | `: test5 44 ; FIND test5 . CR` | stack `empty`, printed `658154448 \n` | unchanged | 0 value(s) left; output not compared | the address FIND leaves is printed | | `FIND.empty` | `FIND` | error | unchanged | stack `0`, prints nothing | FORTH-79: FIND leaves 0 when there is no word; v3 raises an error | | `VOCABULARY.cross_vocab_access` | `VOCABULARY V1 V1 DEFINITIONS : V1WORD 11 ; FORTH V1WORD . CR` | stack `empty`, printed `11 \n` | unchanged | an error | FORTH-79: a word defined in another vocabulary is not found from FORTH; v3 finds it | | `VOCABULARY.duplicate` | `VOCABULARY TESTVOC VOCABULARY TESTVOC` | error | unchanged | stack `empty`, prints nothing | v3 raises an error FORTH-79 does not ask for: defining a name again | diff --git a/kernel/Makefile b/kernel/Makefile index 123aad80..bc9bdd47 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -620,8 +620,8 @@ LOADER_EXTRA_SRCS += $(KERNEL_SRC)/v4/sk_v4.c KERNEL_EXTRA_SRCS += $(KERNEL_SRC)/v4/sk_v4.c # v4/system/boot.c is the boot the hosted v4 system runs too: nucleus, then # the capsules from this kernel's own capsule directory, then the prompt. -LOADER_V4_OBJS := $(patsubst v4/src/%.c,$(LOADER_OBJ_DIR)/v4engine/%.o,$(V4_ENGINE_SRCS)) $(LOADER_OBJ_DIR)/v4engine/v4_image.o $(LOADER_OBJ_DIR)/v4system/boot.o $(LOADER_OBJ_DIR)/v4system/blocks.o -KERNEL_V4_OBJS := $(patsubst v4/src/%.c,$(KERNEL_OBJ_DIR)/v4engine/%.o,$(V4_ENGINE_SRCS)) $(KERNEL_OBJ_DIR)/v4engine/v4_image.o $(KERNEL_OBJ_DIR)/v4system/boot.o $(KERNEL_OBJ_DIR)/v4system/blocks.o +LOADER_V4_OBJS := $(patsubst v4/src/%.c,$(LOADER_OBJ_DIR)/v4engine/%.o,$(V4_ENGINE_SRCS)) $(LOADER_OBJ_DIR)/v4engine/v4_image.o $(LOADER_OBJ_DIR)/v4system/boot.o $(LOADER_OBJ_DIR)/v4system/blocks.o $(LOADER_OBJ_DIR)/v4system/post.o $(LOADER_OBJ_DIR)/v4system/post_cases.o +KERNEL_V4_OBJS := $(patsubst v4/src/%.c,$(KERNEL_OBJ_DIR)/v4engine/%.o,$(V4_ENGINE_SRCS)) $(KERNEL_OBJ_DIR)/v4engine/v4_image.o $(KERNEL_OBJ_DIR)/v4system/boot.o $(KERNEL_OBJ_DIR)/v4system/blocks.o $(KERNEL_OBJ_DIR)/v4system/post.o $(KERNEL_OBJ_DIR)/v4system/post_cases.o endif LOADER_SRCS := $(LOADER_SRCS_BASE) $(LOADER_EXTRA_SRCS) diff --git a/logs/20261007-105118/amd64/qemu-amd64-20261007-105118.log b/logs/20261007-105118/amd64/qemu-amd64-20261007-105118.log new file mode 100644 index 00000000..408182d1 --- /dev/null +++ b/logs/20261007-105118/amd64/qemu-amd64-20261007-105118.log @@ -0,0 +1,158 @@ +[=3hBdsDxe: loading Boot0002 "UEFI QEMU DVD-ROM QM00005 " from PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x2,0xFFFF,0x0) +BdsDxe: starting Boot0002 "UEFI QEMU DVD-ROM QM00005 " from PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x2,0xFFFF,0x0) +[=3hStarKernel UEFI Loader +Loading kernel from ESP... +[CKPT 001] Entered efi_main - ConOut live +RAW SERIAL UP +[CKPT 002] Serial (COM1) initialized +Monolithic build - kernel linked directly +Collecting boot information... +CmdLine: parsed OK +[CKPT 004] Command line parsed +[CKPT 005] Kernel stack allocation decided +[CKPT 006] Boot info collected (ACPI table located) +GOP: linear framebuffer found +[CKPT 007] GOP: linear framebuffer found +[CKPT 008] About to enter ExitBootServices retry loop +EBS... +EBS OK +Calling kernel_main (monolithic)... + + + _____ _ _ __ _ + / ____| | | |/ / | | + | (___ | |_ __ _ _ __| ' / ___ _ __ _ __ ___| | + \___ \| __/ _` | '__| < / _ \ '__| '_ \ / _ \ | + ____) | || (_| | | | . \ __/ | | | | | __/ | + |_____/ \__\__,_|_| |_|\_\___|_| |_| |_|\___|_| + +LithosAnanke v2.1.0 +Architecture: amd64 +Build: Oct 7 2026 10:50:50 + +UEFI BootServices: EXITED + +=== StarKernel Boot Information === +Memory map entries: 131 +Total memory: 1023 MB +Usable memory: 966 MB +=================================== + +PMM initialized. +PMM statistics: + Total pages: 248741 + Free pages : 247218 + Used pages : 1523 + Total MB : 971 + Free MB : 965 + Used MB : 5 + +VMM initialized (mapped RAM, CR3 switched) +VMM initialized (mapped RAM, CR3 switched) +VMM self-test: mapped OK at 0xffff800000000000 +VMM self-test complete. + +IDT installed. + +APIC: init... +APIC: IA32_APIC_BASE MSR=0x00000000fee00900 +APIC: stale-ISR drain: 0 EOI(s) issued +APIC: initialized (xAPIC MMIO, TPR=0, SIVR=0x1FF, EOI-clear) +APIC: init done + +I/O APIC: init... +I/O APIC: base=0xfec00000, gsi_base=0, overrides=5 + override: source=00 gsi=2 flags=0x0000 + override: source=05 gsi=5 flags=0x000d + override: source=09 gsi=9 flags=0x000d + override: source=0a gsi=10 flags=0x000d + override: source=0b gsi=11 flags=0x000d +i8042: keyboard ACKed enable-scanning +i8042: IRQ1 enabled in controller config byte +I/O APIC: keyboard IRQ1 routed (masked) + +Timer: init... +Timer: init start +Timer: PM_TMR_BLK discovered from FADT at port 1544 +Timer: VM mode detected (hypervisor present). +Timer: HPET calibration disabled (VM-exit MMIO would poison timing). +Timer: WARNING: invariant TSC not present under hypervisor. +Timer: continuing in RELATIVE mode (no determinism guarantees). +Timer: RDTSCP not present; using RDTSC (less serialized). +Timer: CPUID frequency unavailable; trying PM Timer... +Timer: trust=1 (0=NONE,1=REL,2=ABS), TSC=2149499758 Hz +Timer: init done + +Kernel heap initialized. +Heap statistics: + Total bytes: 536870872 + Free bytes: 536870872 + Used bytes: 0 + Peak bytes: 0 + Heap base addr: 24641536 + Heap end addr: 561512448 + +Heartbeat: init... +APIC Timer: calibrating... +APIC Timer: apic_hz=1031765227, tick_hz=100, initial_count=10317652 +APIC Timer: configured (masked, ready to start) +Heartbeat: init done +Kernel initialization complete. +Boot successful! + +StarForth v4: one host node, the F18-derived engine +V4: capsule v4:nucleus-64.f18 signature: missing (unsigned) +PARITY:V4_NUCLEUS name=v4:nucleus-64.f18 capsule_id=0x467b3793e193b467 capsule_hash=0x467b3793e193b467 words=308 +V4: capsule v4:forth79.4th signature: missing (unsigned) +PARITY:V4_CAPSULE name=v4:forth79.4th capsule_id=0x4055641ee17d176b capsule_hash=0x4055641ee17d176b dict_hash=0xf268e314e12931c4 +PARITY:V4_POST tests=538 pass=538 fail=0 +PARITY:V4_SYSTEM word_count=411 dict_hash=0x6fb1d09418b189ee +PARITY:OK +POST: PASSED +[HADES][INFO ] [KRELTSC: 0] blk: raw device LBN 2048..3071 (1024 blocks) +PCI: init... +PCI: ECAM mapped (amd64) +virtio-blk: found device +Artemis: virtio-blk attached +[HADES][INFO ] [KRELTSC: 78934212] blk: disk 'StarForth Volume' v2 LBN 3072..789009 (785938 user b +ok> : SQ DUP * ; + ok +ok> 7 SQ . 3 4 U* . . +49 0 12 ok +ok> T{ +UNKNOWN WORD: 'T{' + ERROR +ok> RS1 +42 42 + ok +ok> COLD +FORTH-79 Cold Start +System initialized. + ok +ok> RS1 +42 42 + ok +ok> 3 4 U* . . +0 12 ok +ok> FORGET U* +Protected word + ERROR +ok> 9 KERNEL-WORD ASK9 ASK9 +Argument out of range + ERROR +ok> 1 BLOCK C@ . 2047 BLOCK C@ . +0 0 ok +ok> 2100 BLOCK 1024 BLANK 65 2100 BLOCK C! UPDATE SAVE-BUFFERS EMPTY-BUFFERS 2100 BLOCK C@ . +65 ok +ok> 3072 BLOCK C@ . +0 ok +ok> 3072 BLOCK DROP UPDATE SAVE-BUFFERS +Storage refused + ERROR +ok> 9999999 BLOCK +Block out of range + ERROR +ok> HERE . +9585 ok +ok> BYE +BYE: cold restart diff --git a/logs/20261007-105335/aarch64/qemu-aarch64-20261007-105335.log b/logs/20261007-105335/aarch64/qemu-aarch64-20261007-105335.log new file mode 100644 index 00000000..aa3b6393 --- /dev/null +++ b/logs/20261007-105335/aarch64/qemu-aarch64-20261007-105335.log @@ -0,0 +1,131 @@ +UEFI firmware (version 2025.11-3ubuntu7.3 built at 15:40:26 on Sep 23 2026) +[=3hBdsDxe: failed to load Boot0002 "UEFI Misc Device" from PciRoot(0x0)/Pci(0x2,0x0): Not Found +BdsDxe: failed to load Boot0003 "UEFI QEMU QEMU USB HARDDRIVE 1-0000:00:04.0-1" from PciRoot(0x0)/Pci(0x4,0x0)/USB(0x0,0x0): Not Found +BdsDxe: loading Boot0004 "UEFI Misc Device 2" from PciRoot(0x0)/Pci(0x6,0x0) +BdsDxe: starting Boot0004 "UEFI Misc Device 2" from PciRoot(0x0)/Pci(0x6,0x0) +[=3hStarKernel UEFI Loader +Loading kernel from ESP... +[CKPT 001] Entered efi_main - ConOut live +Collecting boot information... +[CKPT 004] Command line parsed +[CKPT 005] Kernel stack allocation decided +[CKPT 006] Boot info collected (ACPI table located) +[CKPT 007] GOP: linear framebuffer found +[CKPT 008] About to enter ExitBootServices retry loop + + + _____ _ _ __ _ + / ____| | | |/ / | | + | (___ | |_ __ _ _ __| ' / ___ _ __ _ __ ___| | + \___ \| __/ _` | '__| < / _ \ '__| '_ \ / _ \ | + ____) | || (_| | | | . \ __/ | | | | | __/ | + |_____/ \__\__,_|_| |_|\_\___|_| |_| |_|\___|_| + +LithosAnanke v2.1.0 +Architecture: aarch64 +Build: Oct 7 2026 10:53:09 + +UEFI BootServices: EXITED + +=== StarKernel Boot Information === +Memory map entries: 108 +Total memory: 4093 MB +Usable memory: 4054 MB +=================================== + +PMM initialized. +PMM statistics: + Total pages: 1039357 + Free pages : 1037946 + Used pages : 1411 + Total MB : 4059 + Free MB : 4054 + Used MB : 5 + +VMM initialized (mapped RAM, CR3 switched) +VMM initialized (mapped RAM, CR3 switched) +VMM self-test: mapped OK at 0xffff800000000000 +VMM self-test complete. + +AArch64: running at EL1 +IDT installed. + +APIC: init... +PSCI: no DTB -- using HVC (QEMU virt-machine default) +GICv2: no DTB GIC node -- using QEMU virt-machine defaults +GICv2: distributor+CPU interface enabled, PPI 30 +APIC: init done + +Timer: init... +Timer: AArch64 generic timer initialised. +Timer: init done + +Kernel heap initialized. +Heap statistics: + Total bytes: 2147483608 + Free bytes: 2147483608 + Used bytes: 0 + Peak bytes: 0 + Heap base addr: 1207959552 + Heap end addr: 3355443200 + +Heartbeat: init... +Heartbeat: init done +Kernel initialization complete. +Boot successful! + +StarForth v4: one host node, the F18-derived engine +V4: capsule v4:nucleus-64.f18 signature: missing (unsigned) +PARITY:V4_NUCLEUS name=v4:nucleus-64.f18 capsule_id=0x467b3793e193b467 capsule_hash=0x467b3793e193b467 words=308 +V4: capsule v4:forth79.4th signature: missing (unsigned) +PARITY:V4_CAPSULE name=v4:forth79.4th capsule_id=0x4055641ee17d176b capsule_hash=0x4055641ee17d176b dict_hash=0xf268e314e12931c4 +PARITY:V4_POST tests=538 pass=538 fail=0 +PARITY:V4_SYSTEM word_count=411 dict_hash=0x6fb1d09418b189ee +PARITY:OK +POST: PASSED +[HADES][INFO ] [KRELTSC: 0] blk: raw device LBN 2048..3071 (1024 blocks) +PCI: init... +virtio-blk: found device +Artemis: virtio-blk attached +[HADES][INFO ] [KRELTSC: 1501177] blk: disk 'StarForth Volume' v2 LBN 3072..789009 (785938 user b +ok> : SQ DUP * ; + ok +ok> 7 SQ . 3 4 U* . . +49 0 12 ok +ok> T{ +UNKNOWN WORD: 'T{' + ERROR +ok> RS1 +42 42 + ok +ok> COLD +FORTH-79 Cold Start +System initialized. + ok +ok> RS1 +42 42 + ok +ok> 3 4 U* . . +0 12 ok +ok> FORGET U* +Protected word + ERROR +ok> 9 KERNEL-WORD ASK9 ASK9 +Argument out of range + ERROR +ok> 1 BLOCK C@ . 2047 BLOCK C@ . +0 0 ok +ok> 2100 BLOCK 1024 BLANK 65 2100 BLOCK C! UPDATE SAVE-BUFFERS EMPTY-BUFFERS 2100 BLOCK C@ . +65 ok +ok> 3072 BLOCK C@ . +0 ok +ok> 3072 BLOCK DROP UPDATE SAVE-BUFFERS +Storage refused + ERROR +ok> 9999999 BLOCK +Block out of range + ERROR +ok> HERE . +9585 ok +ok> BYE +BYE: cold restart diff --git a/logs/20261007-105651/riscv64/qemu-riscv64-20261007-105651.log b/logs/20261007-105651/riscv64/qemu-riscv64-20261007-105651.log new file mode 100644 index 00000000..8b1b0a8c --- /dev/null +++ b/logs/20261007-105651/riscv64/qemu-riscv64-20261007-105651.log @@ -0,0 +1,201 @@ + +OpenSBI v1.8 + ____ _____ ____ _____ + / __ \ / ____| _ \_ _| + | | | |_ __ ___ _ __ | (___ | |_) || | + | | | | '_ \ / _ \ '_ \ \___ \| _ < | | + | |__| | |_) | __/ | | |____) | |_) || |_ + \____/| .__/ \___|_| |_|_____/|____/_____| + | | + |_| + +Platform Name : riscv-virtio,qemu +Platform Features : medeleg +Platform HART Count : 1 +Platform HART Protection : pmp +Platform IPI Device : aclint-mswi +Platform Timer Device : aclint-mtimer @ 10000000Hz +Platform Console Device : uart8250 +Platform HSM Device : --- +Platform PMU Device : --- +Platform Reboot Device : syscon-reboot +Platform Shutdown Device : syscon-poweroff +Platform Suspend Device : --- +Platform CPPC Device : --- +Firmware Base : 0x80000000 +Firmware Size : 321 KB +Firmware RW Offset : 0x40000 +Firmware RW Size : 65 KB +Firmware Heap Offset : 0x47000 +Firmware Heap Size : 37 KB (total), 0 KB (reserved), 12 KB (used), 23 KB (free) +Firmware Scratch Size : 4096 B (total), 1464 B (used), 2632 B (free) +Runtime SBI Version : 3.0 +Standard SBI Extensions : ipi,pmu,srst,sse,hsm,rfnc,fwft,time,base,legacy,dbcn,dbtr +Experimental SBI Extensions : none + +Domain0 Name : root +Domain0 Boot HART : 0 +Domain0 HARTs : 0* +Domain0 Region00 : 0x0000000080040000-0x000000008005ffff M: (F,R,W) S/U: () +Domain0 Region01 : 0x0000000080000000-0x000000008003ffff M: (F,R,X) S/U: () +Domain0 Region02 : 0x0000000000100000-0x0000000000100fff M: (I,R,W) S/U: (R,W) +Domain0 Region03 : 0x0000000010000000-0x0000000010000fff M: (I,R,W) S/U: (R,W) +Domain0 Region04 : 0x0000000002000000-0x000000000200ffff M: (I,R,W) S/U: () +Domain0 Region05 : 0x000000000c400000-0x000000000c5fffff M: (I,R,W) S/U: (R,W) +Domain0 Region06 : 0x000000000c000000-0x000000000c3fffff M: (I,R,W) S/U: (R,W) +Domain0 Region07 : 0x0000000000000000-0xffffffffffffffff M: () S/U: (R,W,X) +Domain0 Next Address : 0x0000000020000000 +Domain0 Next Arg1 : 0x00000000bfe00000 +Domain0 Next Mode : S-mode +Domain0 SysReset : yes +Domain0 SysSuspend : yes + +Boot HART ID : 0 +Boot HART Domain : root +Boot HART Priv Version : v1.12 +Boot HART Base ISA : rv64imafdch +Boot HART ISA Extensions : sstc,zicntr,zihpm,zicboz,zicbom,sdtrig,svadu +Boot HART PMP Count : 16 +Boot HART PMP Granularity : 2 bits +Boot HART PMP Address Bits : 54 +Boot HART MHPM Info : 16 (0x0007fff8) +Boot HART Debug Triggers : 2 triggers +Boot HART MIDELEG : 0x0000000000001666 +Boot HART MEDELEG : 0x0000000000f4b509 +[=3hRISC-V EDK2 firmware version 2025.11-3ubuntu7.3 +Press ESCAPE within 5 seconds for boot options ERROR: C40000002:V03051002 I0 6D33944A-EC75-4855-A54D-809C75241F6C 83FFF850 +BdsDxe: failed to load Boot0001 "UEFI Misc Device" fr +om PciRoot(0x0)/Pci(0x1,0x0): Not Found +[=3hStarKernel UEFI Loader +Loading kernel from ESP... +[CKPT 001] Entered efi_main - ConOut live +Monolithic build - kernel linked directly +Collecting boot information... +CmdLine: parsed OK +[CKPT 004] Command line parsed +[CKPT 005] Kernel stack allocation decided +[CKPT 006] Boot info collected (ACPI table located) +GOP: linear framebuffer found +[CKPT 007] GOP: linear framebuffer found +[CKPT 008] About to enter ExitBootServices retry loop +Calling kernel_main (monolithic)... +riscv64 item 4.3.5a: satp state at kernel entry (before switch) + satp.MODE = 0x000000000000000a + satp.PPN = 0x00000000000bf868 + __kernel_start = 0x00000000bdca29f8 +riscv64: satp cleared -- Bare mode, explicit (item 4.3.5a) + + + _____ _ _ __ _ + / ____| | | |/ / | | + | (___ | |_ __ _ _ __| ' / ___ _ __ _ __ ___| | + \___ \| __/ _` | '__| < / _ \ '__| '_ \ / _ \ | + ____) | || (_| | | | . \ __/ | | | | | __/ | + |_____/ \__\__,_|_| |_|\_\___|_| |_| |_|\___|_| + +LithosAnanke v2.1.0 +Architecture: riscv64 +Build: Oct 7 2026 10:56:11 + +UEFI BootServices: EXITED + +=== StarKernel Boot Information === +Memory map entries: 100 +Total memory: 1020 MB +Usable memory: 975 MB +=================================== + +PMM initialized. +PMM statistics: + Total pages: 250273 + Free pages : 249621 + Used pages : 652 + Total MB : 977 + Free MB : 975 + Used MB : 2 + +VMM initialized (mapped RAM, CR3 switched) +VMM initialized (mapped RAM, CR3 switched) +VMM self-test: mapped OK at 0xffff800000000000 +VMM self-test complete. + +IDT installed. + +APIC: init... +PLIC: no DTB PLIC node -- using QEMU virt-machine default (base=0x0c000000) +PLIC: init (S-mode context 1, threshold=0) +APIC: init done + +Timer: init... +Timer: RISC-V time CSR @ 10000000 Hz (FALLBACK, no devicetree) +Timer: init done + +Kernel heap initialized. +Heap statistics: + Total bytes: 536870872 + Free bytes: 536870872 + Used bytes: 0 + Peak bytes: 0 + Heap base addr: 2214588416 + Heap end addr: 2751459328 + +Heartbeat: init... +Heartbeat: init done +Kernel initialization complete. +Boot successful! + +StarForth v4: one host node, the F18-derived engine +V4: capsule v4:nucleus-64.f18 signature: missing (unsigned) +PARITY:V4_NUCLEUS name=v4:nucleus-64.f18 capsule_id=0x467b3793e193b467 capsule_hash=0x467b3793e193b467 words=308 +V4: capsule v4:forth79.4th signature: missing (unsigned) +PARITY:V4_CAPSULE name=v4:forth79.4th capsule_id=0x4055641ee17d176b capsule_hash=0x4055641ee17d176b dict_hash=0xf268e314e12931c4 +PARITY:V4_POST tests=538 pass=538 fail=0 +PARITY:V4_SYSTEM word_count=411 dict_hash=0x6fb1d09418b189ee +PARITY:OK +POST: PASSED +[HADES][INFO ] [KRELTSC: 0] blk: raw device LBN 2048..3071 (1024 blocks) +PCI: init... +virtio-blk: found device +Artemis: virtio-blk attached +[HADES][INFO ] [KRELTSC: 40981668] blk: disk 'StarForth Volume' v2 LBN 3072..789009 (785938 user b +ok> : SQ DUP * ; + ok +ok> 7 SQ . 3 4 U* . . +49 0 12 ok +ok> T{ +UNKNOWN WORD: 'T{' + ERROR +ok> RS1 +42 42 + ok +ok> COLD +FORTH-79 Cold Start +System initialized. + ok +ok> RS1 +42 42 + ok +ok> 3 4 U* . . +0 12 ok +ok> FORGET U* +Protected word + ERROR +ok> 9 KERNEL-WORD ASK9 ASK9 +Argument out of range + ERROR +ok> 1 BLOCK C@ . 2047 BLOCK C@ . +0 0 ok +ok> 2100 BLOCK 1024 BLANK 65 2100 BLOCK C! UPDATE SAVE-BUFFERS EMPTY-BUFFERS 2100 BLOCK C@ . +65 ok +ok> 3072 BLOCK C@ . +0 ok +ok> 3072 BLOCK DROP UPDATE SAVE-BUFFERS +Storage refused + ERROR +ok> 9999999 BLOCK +Block out of range + ERROR +ok> HERE . +9585 ok +ok> BYE +BYE: cold restart diff --git a/v4/Makefile b/v4/Makefile index 14f4582a..b2563050 100644 --- a/v4/Makefile +++ b/v4/Makefile @@ -139,7 +139,7 @@ CAPSULE_DIR_C := $(BINDIR)/capsule_generated.c # the kernel's capsule code: find, check the hash, verify the signature, # split a payload into blocks -SYSTEM_SRCS := $(HERE)/system/boot.c \ +SYSTEM_SRCS := $(HERE)/system/boot.c $(HERE)/system/post.c $(HERE)/system/post_cases.c \ $(addprefix $(ROOT)/kernel/src/capsule/,capsule_find.c capsule_validate.c capsule_sig.c capsule_blocks.c) \ $(ROOT)/kernel/src/hash/xxhash64.c $(ROOT)/kernel/src/crypto/x509_ed25519.c $(CRYPTO_SRCS) # The kernel's sources are held to the kernel's warnings, not this model's. @@ -169,7 +169,7 @@ $(foreach i,$(HOSTED_ISAS),$(eval $(call HOSTED_RULE,$(i)))) # `make post` boots the amd64 system alone, which is the quick check after a # change to the vocabulary: nucleus, forth79.4th, POST, prompt. `make -# post79` writes the POST capsule, ../capsules/v4/post79.4th, again from +# post79` writes POST's cases, system/post_cases.c, again from # v3's cases and tools/post79_rules.py (tools/mkpost.py); it needs the # hosted v3 binary. .PHONY: post post79 diff --git a/v4/README.md b/v4/README.md index c6e3de1e..d622b0ea 100644 --- a/v4/README.md +++ b/v4/README.md @@ -159,21 +159,25 @@ a time with POST after each, is the next step (`NUCLEUS.md` section 8). ## POST -`capsules/v4/post79.4th`: 538 cases in blocks 7000 up, covering 126 of the -130 words of the FORTH-79 Required Word Set. 443 are v3's cases with what -the hosted v3 binary did as the expected result. The other 107, and the 27 -v3 cases left out, are listed with reasons in `docs/v4.0.0/POST79.md`. +POST is the kernel's, as in v3 (`MESH.md` step 6b, `NUCLEUS.md` 6.3). The +kernel holds the cases, `v4/system/post_cases.c`: 538 of them, covering 126 +of the 130 words of the FORTH-79 Required Word Set. 431 are v3's cases with +what the hosted v3 binary did as the expected result; every other case, +and the v3 cases left out, are listed with reasons in +`docs/v4.0.0/POST79.md`. - `make -C v4 post` boots the amd64 system: the quick check after a change. - `make -C v4 hosted-check` boots all three hosted ISAs and compares them. -- `make -C v4 post79` writes the capsule again (`tools/mkpost.py`, +- `make -C v4 post79` writes the cases again (`tools/mkpost.py`, `tools/post79_rules.py`); it needs the hosted v3 binary. -POST is FORTH: a harness of FORTH-79 words and two nucleus hooks, `(CATCH)` -and `(EMIT-HOOK)`. It forgets itself when it has finished. The boot passes -only on seeing POST's tally line with `fail=0` (`v4/system/boot.c`). A colon -definition broken on purpose (`U/MOD` without its last `SWAP`) fails five -cases and the boot stops with `POST: FAILED`. +The runner, `v4/system/post.c`, feeds each case to the node a line at a +time, keeps what the node prints, reads its data stack from outside, and +judges: an error exactly if one is expected, and otherwise the stack and +every character printed. Nothing of POST is in the node's dictionary. What +the cases define stays there, as in v3, and the system is sealed after +POST. The boot then prints `PARITY:V4_SYSTEM word_count=N dict_hash=0x...`, +and passes only if no case failed (`v4/system/boot.c`). Not tested: `KEY`, `EXPECT`, `QUERY` (the keyboard) and `QUIT` (it returns without ` ok`). diff --git a/v4/capsule/core.v4 b/v4/capsule/core.v4 index fa29129e..d086d23d 100644 --- a/v4/capsule/core.v4 +++ b/v4/capsule/core.v4 @@ -251,18 +251,12 @@ header CMOVE (OUT) (OUT^) a! ! ; NONE: drop ; -\ EMIT puts the character with what has been printed, unless (EMIT-HOOK) -\ holds the xt of a word: then that word is given it instead ( c -- ), and -\ returns to EMIT's caller. Everything the node prints goes through EMIT, -\ so a hook sees all of it. The hook is taken off when the text being -\ interpreted ends (quit.v4), so that nothing can leave a node silent. -\ POST uses it to compare what a case prints (docs/v4.0.0/NUCLEUS.md 6.3). -\ A is kept: the words that print have always been free to use it across -\ an EMIT. As v3, only the low 8 bits of the character are printed. +\ EMIT puts the character with what has been printed. Everything the node +\ prints goes through EMIT. A is kept: the words that print have always +\ been free to use it across an EMIT. As v3, only the low 8 bits of the +\ character are printed. header EMIT : EMIT ( c -- ) - (EMIT-HOOK) b! @b if NONE push ; - NONE: drop 255 and a push push \ A, and then the character, to the return stack (OUT^) b! @b a! pop !+ a !b \ the character goes where (OUT^) points, which moves on a (OUT)+256 xor if FULL drop pop a! ; diff --git a/v4/capsule/quit.v4 b/v4/capsule/quit.v4 index 41cdf6f8..d458ede5 100644 --- a/v4/capsule/quit.v4 +++ b/v4/capsule/quit.v4 @@ -48,18 +48,10 @@ macro R-CLEAR RSTACK-DEPTH b! a !b endmacro \ structures. A definition that was under way stays hidden. : (RESET) 0 STATE a! ! (CG-RESET) CFBASE (CFP) a! ! ; -\ CATCHING A LINE'S ERROR. While the variable (CATCH) is not zero, a line -\ that ends in an error -- a fault, or a code in NODE-ERROR -- does not say -\ ERROR: (CATCH) is set to -1 and the line is reported as completed. Whatever message the -\ error printed has gone wherever EMIT was sending it. POST uses this to -\ go on to its next case, and to check the cases that must fail -\ (docs/v4.0.0/NUCLEUS.md 6.3). (EMIT-HOOK), core.v4, is set to 0 here at -\ the end of every line, caught or not. -\ \ ( s -- ) the text is done with. What it printed is sent, then a message \ saying how it ended -- 0 QUIT, 1 completed, 2 an error -- and the node waits -\ for the next. (DONE) is entered with the same number and decides whether -\ an error was one to catch; it is always jumped to, never called, by +\ for the next. (DONE) is entered with the same number and, for an error, +\ stops compiling first; it is always jumped to, never called, by \ something that has emptied the return stack (or by a fault, which empties \ it). (LINE-STATUS) keeps how the last text ended. : (FINISH) ( s -- ) @@ -70,11 +62,8 @@ macro R-CLEAR RSTACK-DEPTH b! a !b endmacro jump (IDLE) : (DONE) - (EMIT-HOOK) b! 0 !b \ what is printed is printed again if GO -1 + if OK - drop (RESET) - (CATCH) b! @b if LOUD drop -1 !b 1 jump (DONE) \ caught: the text completed - LOUD: drop 2 jump (FINISH) + drop (RESET) 2 jump (FINISH) OK: drop 1 jump (FINISH) GO: drop 0 jump (FINISH) @@ -247,13 +236,11 @@ header (SEAL) \ further, the message for the code is printed (-1: the word has printed \ its own) and the line ends with ERROR. The codes are listed in core.v4. header NODE-ERROR inline : NODE-ERROR' NODE-ERROR ; -header (CATCH) inline : (CATCH)' (CATCH) ; header (ME) inline : (ME)' (ME) ; header (CONSOLE) inline : (CONSOLE)' (CONSOLE) ; header (LOST) inline : (LOST)' (LOST) ; header (WORD-DEFINED) inline : (WORD-DEFINED)' (WORD-DEFINED) ; header (WORD-FORGOTTEN) inline : (WORD-FORGOTTEN)' (WORD-FORGOTTEN) ; -header (EMIT-HOOK) inline : (EMIT-HOOK)' (EMIT-HOOK) ; header QUIT : QUIT R-CLEAR (RESET) CR 0 jump (DONE) diff --git a/v4/system/boot.c b/v4/system/boot.c index f69558b3..106093bd 100644 --- a/v4/system/boot.c +++ b/v4/system/boot.c @@ -4,6 +4,7 @@ * It is not part of the engine (v4/src): it needs the capsule directory, * which only a whole system has. */ +#include "v4/post.h" #include "v4/blocks.h" #include "v4/boot.h" #include "v4/message.h" @@ -13,18 +14,18 @@ #include "starkernel/capsule_blocks.h" /* The capsules, in the order they are loaded. */ -/* POST is part of the boot: v4:post79.4th is loaded after the vocabulary it - * tests and must end with a clean tally. -DV4_POST_AT_BOOT=0 leaves it - * out, for work on a vocabulary that does not pass yet. */ +static const char *const boot_capsules[] = { + "v4:forth79.4th", +}; + +/* POST is part of the boot, and is the kernel's (v4/include/v4/post.h; + * docs/v4.0.0/NUCLEUS.md 6.3): when the capsules are in, the kernel feeds + * its cases to the node and judges them, and the boot passes only if none + * failed. -DV4_POST_AT_BOOT=0 leaves it out, for work on a vocabulary + * that does not pass yet. */ #ifndef V4_POST_AT_BOOT #define V4_POST_AT_BOOT 1 #endif -static const char *const boot_capsules[] = { - "v4:forth79.4th", -#if V4_POST_AT_BOOT - "v4:post79.4th", -#endif -}; #define LINE_MAX 1025u /* a line is at most 1024 characters, a block */ #define STEP_LIMIT 4000000000ULL /* instruction words one line may take */ @@ -77,37 +78,6 @@ static uint32_t word_count(const v4_node *n, const v4_image *im) /* ---- handing the node a line ---------------------------------------------- */ -/* POST's verdict. The POST capsule ends by printing one line, - * PARITY:V4_POST tests=N pass=N fail=N - * and the boot passes only if it has seen that line with fail=0. That no - * line was refused is not enough: a POST that was broken half way would - * refuse nothing. */ -static char post_line[96]; -static unsigned post_len; -static int post_seen, post_clean; - -static int text_at(const char *line, unsigned len, unsigned at, const char *want) -{ - unsigned i; - for (i = 0; want[i]; i++) - if (at + i >= len || line[at + i] != want[i]) return 0; - return 1; -} - -static void post_watch(char c) -{ - static const char clean[] = " fail=0"; - if (c != '\n') { - if (post_len < sizeof post_line) post_line[post_len++] = c; - return; - } - if (text_at(post_line, post_len, 0, "PARITY:V4_POST ")) { - post_seen = 1; - post_clean = post_len >= sizeof clean - 1 && text_at(post_line, post_len, post_len - (unsigned)(sizeof clean - 1), clean); - } - post_len = 0; -} - /* The boot is the node's neighbour on two of its ports. On port 0 it is * the kernel: the node writes the number of a request there (ENGINE.md * 3.3) -- for a block (blocks.h), or for one of the host's words. On port @@ -120,7 +90,10 @@ static void post_watch(char c) /* What the kernel keeps of the node's block window (blocks.h). */ static v4_blocks boot_blocks; -int v4_boot_line(const v4_boot *b, const char *text, unsigned len) +/* Hand the node a line and run it to its end. What it prints goes to the + * console; or, if `keep` is given, into `keep`, at most `cap` characters, + * and none of it is shown: *printed is then how many it printed in all. */ +static int run_line(const v4_boot *b, const char *text, unsigned len, char *keep, unsigned cap, unsigned *printed) { static v4_message out, in; /* one line at a time: the boot is not re-entered */ v4_node *n = b->n; @@ -155,8 +128,8 @@ int v4_boot_line(const v4_boot *b, const char *text, unsigned len) if (v4_message_type(&in) == V4_MSG_OUTPUT) { for (i = 0; i < chars; i++) { char c = v4_message_char(&in, i); - post_watch(c); - b->out(&c, 1); + if (!keep) b->out(&c, 1); + else { if (*printed < cap) keep[*printed] = c; (*printed)++; } } } else if (v4_message_type(&in) == V4_MSG_DONE) { return (int)in.word[V4_MSG_HEADER]; @@ -185,6 +158,27 @@ int v4_boot_line(const v4_boot *b, const char *text, unsigned len) } } +int v4_boot_line(const v4_boot *b, const char *text, unsigned len) +{ + return run_line(b, text, len, 0, 0u, 0); +} + +#if V4_POST_AT_BOOT +/* POST's host (post.h): a line is handed to the node as any line is, and + * what the node prints is kept for the runner and not shown. */ +static int post_line(void *self, const char *text, unsigned text_len, char *out, unsigned cap, unsigned *len) +{ + int how; + *len = 0; + how = run_line((const v4_boot *)self, text, text_len, out, cap, len); + return (how == V4_TEXT_QUIT || how == V4_TEXT_COMPLETED || how == V4_TEXT_ERROR) ? how : -1; +} +static void post_say(void *self, const char *text, unsigned len) +{ + ((const v4_boot *)self)->out(text, len); +} +#endif + /* ---- one capsule --------------------------------------------------------- */ static void say_where(const v4_boot *b, const char *name, uint32_t block, uint32_t line) @@ -345,7 +339,6 @@ int v4_boot_run(const v4_boot *b) { unsigned i; - post_len = 0; post_seen = 0; post_clean = 0; /* a node is born with nothing in it, and is sent the nucleus */ if (!v4_image_born(b->n, b->es, b->h, b->im)) { say(b, "V4: the nucleus is not for this build of the engine\nPARITY:FAIL\nPOST: FAILED\n"); @@ -375,16 +368,24 @@ int v4_boot_run(const v4_boot *b) for (i = 0; i < sizeof boot_capsules / sizeof boot_capsules[0]; i++) if (!load_capsule(b, boot_capsules[i])) { say(b, "PARITY:FAIL\nPOST: FAILED\n"); return 0; } #if V4_POST_AT_BOOT - if (!post_seen || !post_clean) { - say(b, post_seen ? "V4: POST reported failures\n" : "V4: POST did not report\n"); - say(b, "PARITY:FAIL\nPOST: FAILED\n"); - return 0; + { + v4_post_host host; + v4_post_tally tally; + host.self = (void *)b; host.n = b->n; host.line = post_line; host.say = post_say; + if (!v4_post_run(&host, v4_post_cases, v4_post_case_count, &tally)) { + say(b, "V4: POST reported failures\nPARITY:FAIL\nPOST: FAILED\n"); + return 0; + } } #endif - /* The kernel's words and the capsules are the system: COLD comes back - * to here, and FORGET will not go below it. */ + /* The kernel's words, the capsules and what POST's cases defined are + * the system, as in v3: COLD comes back to here, and FORGET will not go + * below it. */ v4_image_seal(b->n, b->im); + say(b, "PARITY:V4_SYSTEM word_count="); say_dec(b, word_count(b->n, b->im)); + say(b, " dict_hash="); say_hex(b, v4_boot_dict_hash(b->n, b->im)); + say(b, "\n"); #if V4_POST_AT_BOOT say(b, "PARITY:OK\nPOST: PASSED\n"); diff --git a/v4/system/post_cases.c b/v4/system/post_cases.c index 8fd6a58d..431f440a 100644 --- a/v4/system/post_cases.c +++ b/v4/system/post_cases.c @@ -877,7 +877,7 @@ const v4_post_case v4_post_cases[] = { { "-TRAILING.empty", l318, 1u, V4_POST_STACK, 0, 0u, "\012", 1u }, { "CMOVE.basic", l319, 2u, V4_POST_STACK, 0, 0u, "65 66 \012", 7u }, { "CMOVE.empty", l320, 1u, V4_POST_STACK, 0, 0u, "", 0u }, - { ">IN.initial", l321, 1u, V4_POST_STACK, 0, 0u, "9 \012", 3u }, + { ">IN.initial", l321, 1u, V4_POST_STACK, 0, 0u, "6 \012", 3u }, { ">IN.advances", l322, 1u, V4_POST_STACK, 0, 0u, "0 \012", 3u }, { "..positive", l323, 1u, V4_POST_STACK, 0, 0u, "42 \012", 4u }, { "..negative", l324, 1u, V4_POST_STACK, 0, 0u, "-42 \012", 5u }, diff --git a/v4/tests/host_map.h b/v4/tests/host_map.h index 16b0ed5e..664a2fe6 100644 --- a/v4/tests/host_map.h +++ b/v4/tests/host_map.h @@ -65,8 +65,6 @@ #define SRC (BVARS + 8) #define SRC_HOOK (BVARS + 9) #define ACL_HOOK (BUF0_W - 6) /* the xt of the access control recheck word, or 0 */ -#define EMIT_HOOK (BUF0_W - 7) /* the xt of a word EMIT gives its character to, or 0: the console */ -#define CATCH (BUF0_W - 8) /* non-zero: a line's error is recorded here, -1, and the line ends " ok" */ #define LINE_STATUS (BUF0_W - 9) /* how the last line ended: 0 QUIT, 1 completed, 2 an error */ #define PORT (BUF0_W - 32) /* the node's ports (node.h): V4_PORTS of them, then "any port" and "which port". Port 0 is where its requests go. */ #define CONSOLE (BUF0_W - 16) /* the node what this one prints is sent to; 0: whoever sent the text being served */ @@ -175,8 +173,6 @@ static int host_load(v4_text *tx, v4_node *n, const char *const *files, unsigned v4_text_constant(tx, "BLK", BLK); v4_text_constant(tx, "(SRC)", SRC); v4_text_constant(tx, "(SRC-HOOK)", SRC_HOOK); - v4_text_constant(tx, "(EMIT-HOOK)", EMIT_HOOK); - v4_text_constant(tx, "(CATCH)", CATCH); v4_text_constant(tx, "(LINE-STATUS)", LINE_STATUS); v4_text_constant(tx, "(PORT)", PORT); v4_text_constant(tx, "(ME)", ME); diff --git a/v4/tests/test_host_quit.c b/v4/tests/test_host_quit.c index 37ba0c42..f391683c 100644 --- a/v4/tests/test_host_quit.c +++ b/v4/tests/test_host_quit.c @@ -1277,6 +1277,11 @@ int main(void) post_lost = 0; } + /* ---- nothing of POST is on the node (NUCLEUS.md 6.3) ---- */ + boot(); + CHECK(is(say("(CATCH)\n"), "UNKNOWN WORD: '(CATCH)'\n ERROR\nok> ") && is(say("(EMIT-HOOK)\n"), "UNKNOWN WORD: '(EMIT-HOOK)'\n ERROR\nok> ") + && is(say("T{\n"), "UNKNOWN WORD: 'T{'\n ERROR\nok> "), "the nucleus has neither of the variables the POST capsule needed, nor its words"); + /* ---- storage that refuses a write (MESH.md 8.2) ---- */ boot(); CHECK(is(say(REFUSING_FIRST " BLOCK DROP UPDATE SAVE-BUFFERS 65 EMIT\n"), "Storage refused\n ERROR\nok> "), "a write storage will not take says so, and the prompt returns"); @@ -1450,7 +1455,7 @@ int main(void) boot_bare(); CHECK(load_source("tools.fth"), "tools.fth compiles, every line of it"); CHECK(is(say(": SQ DUP * ; SEE SQ\n"), ": SQ\n dup call * \n ; \n ok\nok> "), "a definition: an in-line word, a call by name, the return"); - CHECK(is(say("SEE DUP\n"), ": DUP\n dup ; \n ok\nok> ") && is(say("SEE EMIT\n"), out) && strncmp(out, ": EMIT\n @p ", 12) == 0 && strstr(out, " b! @b \n if ") && strstr(out, " pop a! ; \n"), + CHECK(is(say("SEE DUP\n"), ": DUP\n dup ; \n ok\nok> ") && is(say("SEE EMIT\n"), out) && strncmp(out, ": EMIT\n @p 255 and ", 20) == 0 && strstr(out, " pop a! ; \n"), "the capsule's own words; a literal's value follows its @p"); CHECK(is(say("VARIABLE V 7 V ! SEE V\n"), ": V\n data: 7 \n ok\nok> ") && is(say("5 CONSTANT K SEE K\n"), ": K\n data: 5 \n ok\nok> "), "a variable and a constant show what they hold"); CHECK(is(say(": IM 1 ; IMMEDIATE SEE IM\n"), ": IM\n @p 1 ; \nIMMEDIATE\n ok\nok> "), "an immediate word says so"); diff --git a/v4/tests/test_host_unit.c b/v4/tests/test_host_unit.c index c2bcfd6d..fbe8ee96 100644 --- a/v4/tests/test_host_unit.c +++ b/v4/tests/test_host_unit.c @@ -31,6 +31,7 @@ #include "v4/manage.h" #include "v4/blocks.h" #include "v4/message.h" +#include "v4/post.h" #include "v4/text.h" #include "block_subsystem.h" #include @@ -154,7 +155,6 @@ static int host_open(void *self, const char *name, unsigned len) (void)self; if (len == 17 && memcmp(name, "v4:nucleus-64.f18", 17) == 0) { hera_reads.is_f18 = 1; hera_reads.cells_at = 0; return 1; } if (len == 14 && memcmp(name, "v4:forth79.4th", 14) == 0) return read_file(&hera_reads, "forth79.4th"); - if (len == 13 && memcmp(name, "v4:post79.4th", 13) == 0) return read_file(&hera_reads, "post79.4th"); return 0; } static int host_cell(void *self, v4_cell *w) @@ -277,6 +277,30 @@ static const char *tell(v4_cell node, const char *text) } static int told(v4_cell node, const char *text) { return tell(node, text)[0] == 0 && ended == 1 && ended_how == V4_TEXT_COMPLETED; } +/* POST's host, for the node numbered 10 (v4/include/v4/post.h): a line is + * told to it from the console, and what it prints is handed to the runner. */ +static int post_line(void *self, const char *text, unsigned text_len, char *out, unsigned cap, unsigned *len) +{ + static char line[V4_MSG_MAX_CHARS + 1]; + const char *r; + (void)self; + *len = 0; + if (text_len > V4_MSG_MAX_CHARS) return -1; + memcpy(line, text, text_len); line[text_len] = 0; + r = tell(10, line); + if (ended != 1 || ended_from != 10) return -1; + *len = printed_len; + memcpy(out, r, printed_len < cap ? printed_len : cap); + return (int)ended_how; +} +static char post_said[2048]; +static unsigned post_said_len; +static void post_say(void *self, const char *text, unsigned len) +{ + (void)self; + if (post_said_len + len < sizeof post_said) { memcpy(post_said + post_said_len, text, len); post_said_len += len; post_said[post_said_len] = 0; } +} + /* Every line of a capsule of FORTH blocks, told to a node from the console: * how many lines did not complete. */ static unsigned load(v4_cell node, const char *file) @@ -376,7 +400,16 @@ int main(void) } CHECK(strcmp(tell(10, "NODE-ME ."), "0 ") == 0 && refused == 0, "it asks where it is, and is answered"); CHECK(load(10, "forth79.4th") == 0, "it takes in FORTH-79"); - CHECK(load(10, "post79.4th") == 0 && post_passed[10] == 1 && post_other == 0, "and passes POST"); + { + v4_post_host host; + v4_post_tally tally; + host.self = 0; host.n = node_numbered(10); host.line = post_line; host.say = post_say; + CHECK(v4_post_run(&host, v4_post_cases, v4_post_case_count, &tally) && tally.tests == 538 && tally.pass == 538 && tally.fail == 0 + && strstr(post_said, "PARITY:V4_POST tests=538 pass=538 fail=0\n") != NULL && strstr(post_said, "POST FAIL") == NULL, + "and passes POST, which the kernel runs on her: %u of %u, %u failed; \"%s\"", tally.pass, tally.tests, tally.fail, post_said); + } + CHECK(strstr(tell(10, "T{"), "UNKNOWN WORD") != NULL, "nothing of POST's harness is on her: \"%s\"", printed); + CHECK(strcmp(tell(10, "RS1"), "42 42 \n") == 0, "what POST's cases defined is: \"%s\"", printed); CHECK(load(10, "hera.4th") == 0, "and its own capsule, which makes it Hera"); CHECK(told(10, "(SEAL)"), "that is the system it comes back to"); @@ -387,9 +420,10 @@ int main(void) CHECK(ended == 1 && ended_how == V4_TEXT_COMPLETED && ended_from == 10, "Hera births four nodes and joins them: \"%s\"", r); } CHECK(born_count == 4 && refused == 0, "four nodes were asked for: %u", born_count); - CHECK(post_passed[10] == 1 && post_passed[11] == 0 && post_passed[12] == 0 && post_passed[13] == 0 && post_passed[14] == 0 && post_other == 0, - "a node she births is not POSTed: POST is the kernel's, once, on Hera: %u; %u %u %u %u, %u failed", + CHECK(post_passed[10] == 0 && post_passed[11] == 0 && post_passed[12] == 0 && post_passed[13] == 0 && post_passed[14] == 0 && post_other == 0, + "a node she births is not POSTed, and no node prints a POST tally: POST is the kernel's, once, on Hera: %u %u %u %u %u, %u failed", post_passed[10], post_passed[11], post_passed[12], post_passed[13], post_passed[14], post_other); + CHECK(strstr(tell(10, "COLD"), "Cold Start") != NULL && strcmp(tell(10, "RS1"), "42 42 \n") == 0, "COLD on Hera comes back to a system that has what POST's cases defined: \"%s\"", printed); CHECK(parity_count == 4 && parity_number[0] == 11 && parity_number[1] == 12 && parity_number[2] == 13 && parity_number[3] == 14, "the parity of each was recorded: %u", parity_count); CHECK(parity_hash[0] == parity_hash[1] && parity_hash[1] == parity_hash[2] && parity_hash[2] == parity_hash[3], "and their dictionary hashes are the same: %016llx %016llx %016llx %016llx", diff --git a/v4/tools/mkpost.py b/v4/tools/mkpost.py index ffd200fb..bfa60777 100755 --- a/v4/tools/mkpost.py +++ b/v4/tools/mkpost.py @@ -240,10 +240,14 @@ ANSI = re.compile(r"\x1b\[[0-9;]*m") def run_v3(v3, cases): """Runs the cases in one session. Returns a list, one entry per case: None if v3 did not get through it, else (error, stack, output).""" - script = [": T| ; IMMEDIATE", ": TCLR BEGIN DEPTH WHILE DROP REPEAT ;"] + # The lines are run as the kernel sends them to the node: without the + # "T| " each began with when they were lines of a capsule. A case that + # looks at where it is in its line (>IN) depends on it. + script = [": TCLR BEGIN DEPTH WHILE DROP REPEAT ;"] for n, case in enumerate(cases): script.append('TCLR DECIMAL FORTH DEFINITIONS ." [[B%d]]"' % n) - script.extend(case["lines"]) + assert all(line.startswith("T| ") for line in case["lines"]), case + script.extend(line[3:] for line in case["lines"]) script.append('." [[E%d]]" BASE @ DECIMAL .S BASE ! ." [[S%d]]"' % (n, n)) script.append("BYE") done = subprocess.run([v3, "--log-none"], input=("\n".join(script) + "\n").encode("latin-1"), diff --git a/v4/tools/post79_rules.py b/v4/tools/post79_rules.py index a0308877..fae2ce9a 100644 --- a/v4/tools/post79_rules.py +++ b/v4/tools/post79_rules.py @@ -112,7 +112,9 @@ STANDARD = { "TYPE.basic_string": dict(text="72 PAD C! 105 PAD 1+ C! PAD 2 TYPE CR", out="Hi\n", why=D1 + "; and " + RS), "TYPE.numbers": dict(text="49 PAD C! 50 PAD 1+ C! PAD 2 TYPE CR", out="12\n", why=D1 + "; and " + RS), - ">IN.initial": dict(out="9 \n", why="FORTH-79: >IN is the offset into the input, 9 here; v3 prints an address"), + # 6: the line is ">IN @ . CR" and >IN is read when "@" has been taken with the blank after it. It was 9 + # while the cases were a capsule, whose lines each began "T| " (until MESH.md step 6b). + ">IN.initial": dict(out="6 \n", why="FORTH-79: >IN is the offset into the input, 6 here; v3 prints an address"), "WORD.empty_input": None, "WORD.space_delim": None, "WORD.newline_delim": None, "WORD.tab_delim": None, "WORD.comma_delim": None, "WORD.skip_leading": None, "WORD.single_char": None, "WORD.long_word": None,