feat(v4): centre.4th and hera.4th; every node's kernel serves it (MESH.md 9a.3)

What a birthing node needs is centre.4th; KILL, PAUSE, RESUME, UNIT-KILL and
CENTRE are Hera's.  An outer node births, as a v3 VM may, and may not kill.
A capsule is read by the node that opened it.  test_host_unit: 93 checks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
rajames
2026-10-16 11:59:47 -04:00
co-authored by Claude Opus 5.5
parent 450dea9c24
commit c88af25e1e
3 changed files with 184 additions and 140 deletions
+117
View File
@@ -0,0 +1,117 @@
Block 8100
( centre.4th -- what a node that births others needs. )
( docs/v4.0.0/MESH.md 9a. Births follow v3: any node may )
( birth on its own ports, and is its children's parent. )
( The kernel's requests, by their numbers in manage.h: )
-6 KERNEL-WORD NODE-ME -7 KERNEL-WORD NODE-BORN
-8 KERNEL-WORD NODE-WIRE -9 KERNEL-WORD NODE-UNWIRE
-13 KERNEL-WORD NODE-PARITY -14 KERNEL-WORD CAPSULE-OPEN
-15 KERNEL-WORD CAPSULE-CELL -16 KERNEL-WORD CAPSULE-LINE
-17 KERNEL-WORD NODE-CHILD -18 KERNEL-WORD NODE-PLACE
( Text for another node is built in PAD. )
VARIABLE (T#)
: (T0) ( -- ) 0 (T#) ! ;
: (TC) ( c -- ) PAD (T#) @ + C! 1 (T#) +! ;
: (TS) ( baddr u -- )
DUP IF 0 DO DUP I + C@ (TC) LOOP DROP ELSE DROP DROP THEN ;
Block 8101
: (TN) ( n -- ) 0 <# #S #> (TS) 32 (TC) ;
: (T) ( -- baddr u ) PAD (T#) @ ;
( The node being born: its number, its place, the port of )
( this node that leads to it, its own port that leads here, )
( and its personality: a capsule's name, or none. )
VARIABLE (KID) VARIABLE (KID#) VARIABLE (KIDP)
VARIABLE (KIDC) VARIABLE (PERS) VARIABLE (PERS#)
: (FAIL) ( -- )
." BIRTH: node " (KID#) @ . ." did not do as it was told" CR
-1 NODE-ERROR ! ;
: (TOLD) ( how -- ) 1 - IF (FAIL) THEN ;
: (TELL) ( baddr u -- ) (KID#) @ SEND (KID#) @ AWAIT (TOLD) ;
Block 8102
( the system, a capsule of F18 code, cell by cell to its port )
: (NUCLEUS) ( -- )
S" v4:nucleus-64.f18" CAPSULE-OPEN 0= IF (FAIL) THEN
BEGIN CAPSULE-CELL WHILE (KIDP) @ PORT! REPEAT DROP ;
( a capsule of FORTH blocks, a line at a time )
: (LINES) ( baddr u -- ) CAPSULE-OPEN 0= IF (FAIL) THEN
BEGIN PAD CAPSULE-LINE DUP 0< 0= WHILE PAD SWAP (TELL) REPEAT
DROP ;
Block 8103
( The nodes this one has had born: for each its number and )
( the port of this node it is on. Sixteen at most. )
CREATE (KIDS) 32 ALLOT VARIABLE (KIDS#) 0 (KIDS#) !
: (KID@) ( i -- addr ) 2 * (KIDS) + ;
: (NOTE) ( number port -- )
(KIDS#) @ 16 < IF
(KIDS#) @ (KID@) SWAP OVER 1+ ! ! 1 (KIDS#) +!
ELSE DROP DROP THEN ;
: (WHICH) ( number -- i | -1 )
-1 SWAP (KIDS#) @ DUP IF 0 DO
DUP I (KID@) @ = IF SWAP DROP I SWAP THEN
LOOP ELSE DROP THEN DROP ;
: (UNLIST) ( i -- )
(KIDS#) @ 1- DUP (KIDS#) ! (KID@) DUP @ SWAP 1+ @
ROT (KID@) SWAP OVER 1+ ! ! ;
Block 8104
( Who it is, where its printing goes, which of its ports )
( leads to everything it is not told of, and who is there. )
: (WHO) ( -- )
(T0) (KID#) @ (TN) S" (ME) ! " (TS)
(CONSOLE) @ (TN) S" (CONSOLE) ! " (TS)
(KIDC) @ (TN) S" DEFAULT-ROUTE " (TS)
(ME) @ (TN) (KIDC) @ (TN) S" NEIGHBOUR" (TS)
(T) 0 (KIDP) @ SEND-ON (KID#) @ AWAIT (TOLD) ;
Block 8105
( number port childport baddr u -- place A NODE IS BORN, )
( its port childport joined to this one's port: empty, then )
( the system, FORTH-79, and its personality if u is not 0. )
: BIRTH-AS
(PERS#) ! (PERS) ! (KIDC) ! (KIDP) ! (KID#) !
(KID#) @ NODE-BORN DUP 0< IF (FAIL) THEN (KID) !
NODE-ME (KIDP) @ (KID) @ (KIDC) @ NODE-WIRE 0= IF (FAIL) THEN
(NUCLEUS)
(KID#) @ (KIDP) @ ROUTE (KID#) @ (KIDP) @ NEIGHBOUR (WHO)
S" v4:forth79.4th" (LINES)
(PERS#) @ IF (PERS) @ (PERS#) @ (LINES) THEN
S" (SEAL)" (TELL)
(KID) @ (KID#) @ NODE-PARITY
(KID#) @ (KIDP) @ (NOTE)
(KID) @ ;
Block 8106
( number port childport -- place a node with no capsule )
: BIRTH 0 0 BIRTH-AS ;
( Two outer nodes are joined: port 3 of X to port 4 of Y, )
( and each is told the other is there. )
VARIABLE (XP) VARIABLE (XN) VARIABLE (YP) VARIABLE (YN)
: (X) ( place number -- ) (XN) ! (XP) ! ;
: (Y) ( place number -- ) (YN) ! (YP) ! ;
: (SAY) ( them port me -- ) (KID#) !
(T0) OVER (TN) DUP (TN) S" ROUTE " (TS)
SWAP (TN) (TN) S" NEIGHBOUR" (TS) (T) (TELL) ;
: (JOIN) ( -- )
(XP) @ 3 (YP) @ 4 NODE-WIRE 0= IF (FAIL) THEN
(YN) @ 3 (XN) @ (SAY) (XN) @ 4 (YN) @ (SAY) ;
Block 8107
( n -- A UNIT: four outer nodes, n+1 to n+4, on ports 2 )
( to 5 of this one, each by its own port 2, and joined in a )
( square: 1-2, 2-4, 4-3, 3-1. )
VARIABLE (U)
VARIABLE (P1) VARIABLE (P2) VARIABLE (P3) VARIABLE (P4)
: (N) ( k -- number ) (U) @ + ;
: UNIT ( n -- ) (U) !
1 (N) 2 2 BIRTH (P1) ! 2 (N) 3 2 BIRTH (P2) !
3 (N) 4 2 BIRTH (P3) ! 4 (N) 5 2 BIRTH (P4) !
(P1) @ 1 (N) (X) (P2) @ 2 (N) (Y) (JOIN)
(P2) @ 2 (N) (X) (P4) @ 4 (N) (Y) (JOIN)
(P4) @ 4 (N) (X) (P3) @ 3 (N) (Y) (JOIN)
(P3) @ 3 (N) (X) (P1) @ 1 (N) (Y) (JOIN) ;
Block 8108
( n -- NODE n IS GONE: every node this one birthed is told, )
( as from this one, and n leaves the list if it was there. )
( The system calls this when it believes a GONE, through )
( GONE-HOOK in quit.f18; Hera calls it from KILL. )
: GONE-DOWN ( n -- )
DUP (WHICH) DUP 0< IF DROP ELSE (UNLIST) THEN
(KIDS#) @ DUP IF 0 DO DUP I (KID@) @ GONE LOOP
ELSE DROP THEN DROP ;
' GONE-DOWN (GONE-HOOK) !
+28 -109
View File
@@ -1,111 +1,30 @@
Block 8000
( hera.4th -- Hera: the node that has the others born and )
( manages them. docs/v4.0.0/MESH.md sections 9 and 10. )
( She asks whoever holds the fabric for a node, wires it, )
( and sends it its capsules through the port that joins )
( them. The unit rule is here and nowhere else: four outer )
( nodes round a centre, an outer node wired only inside its )
( unit. )
( Text for another node is built in PAD. )
VARIABLE (T#)
: (T0) ( -- ) 0 (T#) ! ;
: (TC) ( c -- ) PAD (T#) @ + C! 1 (T#) +! ;
: (TS) ( baddr u -- )
DUP IF 0 DO DUP I + C@ (TC) LOOP DROP ELSE DROP DROP THEN ;
: (TN) ( n -- ) 0 <# #S #> (TS) 32 (TC) ;
: (T) ( -- baddr u ) PAD (T#) @ ;
Block 8001
( The node being born: its place in the fabric, the number )
( it is to have, and the port of this node that leads to it. )
VARIABLE (KID) VARIABLE (KID#) VARIABLE (KIDP)
: (FAIL) ( -- )
." BIRTH: node " (KID#) @ . ." did not do as it was told" CR
-1 NODE-ERROR ! ;
: (TOLD) ( how -- ) 1 - IF (FAIL) THEN ;
: (TELL) ( baddr u -- ) (KID#) @ SEND (KID#) @ AWAIT (TOLD) ;
( the nucleus, a capsule of F18 code, cell by cell to its port )
: (NUCLEUS) ( -- )
S" v4:nucleus-64.f18" CAPSULE-OPEN 0= IF (FAIL) THEN
BEGIN CAPSULE-CELL WHILE (KIDP) @ PORT! REPEAT DROP ;
( a capsule of FORTH blocks, a line at a time )
: (LINES) ( baddr u -- ) CAPSULE-OPEN 0= IF (FAIL) THEN
BEGIN PAD CAPSULE-LINE DUP 0< 0= WHILE PAD SWAP (TELL) REPEAT
DROP ;
Block 8002
( The nodes this one has had born: for each its number and )
( its place in the fabric. Sixteen at most. )
CREATE (KIDS) 32 ALLOT VARIABLE (KIDS#) 0 (KIDS#) !
: (KID@) ( i -- addr ) 2 * (KIDS) + ;
: (NOTE) ( number place -- )
(KIDS#) @ 16 < IF
(KIDS#) @ (KID@) SWAP OVER 1+ ! ! 1 (KIDS#) +!
ELSE DROP DROP THEN ;
( which of them has that number: its place in the list, or -1 )
: (WHICH) ( number -- i | -1 )
-1 SWAP (KIDS#) @ DUP IF 0 DO
DUP I (KID@) @ = IF SWAP DROP I SWAP THEN
LOOP ELSE DROP THEN DROP ;
Block 8003
( who it is, where its printing goes, and that everything )
( not told of goes by its port 2, where this node is )
: (WHO) ( -- )
(T0) (KID#) @ (TN) S" (ME) ! " (TS)
(CONSOLE) @ (TN) S" (CONSOLE) ! 2 DEFAULT-ROUTE " (TS)
(ME) @ (TN) S" 2 NEIGHBOUR" (TS)
(T) 0 (KIDP) @ SEND-ON (KID#) @ AWAIT (TOLD) ;
( number port -- place A NODE IS BORN on that port of )
( this one: empty, then the nucleus, then FORTH-79. )
: BIRTH ( number port -- place )
(KIDP) ! (KID#) !
(KID#) @ NODE-BORN DUP 0< IF (FAIL) THEN (KID) !
NODE-ME (KIDP) @ (KID) @ 2 NODE-WIRE 0= IF (FAIL) THEN
(NUCLEUS)
(KID#) @ (KIDP) @ ROUTE (KID#) @ (KIDP) @ NEIGHBOUR (WHO)
S" v4:forth79.4th" (LINES)
Block 8004
S" (SEAL)" (TELL)
(KID) @ (KID#) @ NODE-PARITY
(KID#) @ (KID) @ (NOTE)
(KID) @ ;
( Two outer nodes are joined: port 3 of X to port 4 of Y, )
( and each is told the other is there. )
VARIABLE (XP) VARIABLE (XN) VARIABLE (YP) VARIABLE (YN)
: (X) ( place number -- ) (XN) ! (XP) ! ;
: (Y) ( place number -- ) (YN) ! (YP) ! ;
: (SAY) ( them port me -- ) (KID#) !
(T0) OVER (TN) DUP (TN) S" ROUTE " (TS)
SWAP (TN) (TN) S" NEIGHBOUR" (TS) (T) (TELL) ;
: (JOIN) ( -- )
(XP) @ 3 (YP) @ 4 NODE-WIRE 0= IF (FAIL) THEN
(YN) @ 3 (XN) @ (SAY) (XN) @ 4 (YN) @ (SAY) ;
Block 8005
( n -- A UNIT: four outer nodes, n+1 to n+4, on ports 2 )
( to 5 of this one, and joined in a square: 1-2, 2-4, 4-3, )
( 3-1. The corners across from each other are not wired: )
( what one sends the other goes by this node. )
VARIABLE (U)
VARIABLE (P1) VARIABLE (P2) VARIABLE (P3) VARIABLE (P4)
: (N) ( k -- number ) (U) @ + ;
: UNIT ( n -- ) (U) !
1 (N) 2 BIRTH (P1) ! 2 (N) 3 BIRTH (P2) !
3 (N) 4 BIRTH (P3) ! 4 (N) 5 BIRTH (P4) !
(P1) @ 1 (N) (X) (P2) @ 2 (N) (Y) (JOIN)
(P2) @ 2 (N) (X) (P4) @ 4 (N) (Y) (JOIN)
(P4) @ 4 (N) (X) (P3) @ 3 (N) (Y) (JOIN)
(P3) @ 3 (N) (X) (P1) @ 1 (N) (Y) (JOIN) ;
Block 8006
( n -- KILL: node n is removed, whatever it was doing. )
( This node forgets the way to it, and every other node it )
( has had born is told that n is gone: each forgets its way )
( to n, and one that is waiting for n's answer stops. )
( docs/v4.0.0/MESH.md 7b.5. As v3's KILL, by number. )
: (UNLIST) ( i -- )
(KIDS#) @ 1- DUP (KIDS#) ! (KID@) DUP @ SWAP 1+ @
ROT (KID@) SWAP OVER 1+ ! ! ;
( hera.4th -- what is Hera's alone, beside centre.4th, which )
( she loads first. docs/v4.0.0/MESH.md 9a. She decides )
( which nodes there are and which are awake: KILL, PAUSE and )
( RESUME, by number, through the kernel's registry, are hers )
( and no other node's, as v3's KILL is Hera's alone. )
-10 KERNEL-WORD NODE-SLEEP -11 KERNEL-WORD NODE-WAKE
-12 KERNEL-WORD NODE-KILL
( n -- n flag a node there is, and not Hera herself )
: (THERE?) DUP (ME) @ = 0= OVER NODE-PLACE 0< 0= AND ;
: (NO-NODE) ( n -- ) DROP ." no such node" CR -1 NODE-ERROR ! ;
( n -- KILL: node n is removed, whatever it was doing; this )
( node forgets the way to it, and GONE goes down the graph. )
: KILL ( n -- )
DUP (WHICH) DUP 0< IF
DROP DROP ." KILL: no such node" CR -1 NODE-ERROR ! THEN
OVER NODE-KILL (UNLIST)
DUP NO-ROUTE
(KIDS#) @ DUP IF 0 DO DUP I (KID@) @ GONE LOOP ELSE DROP THEN
DROP ;
(THERE?) 0= IF ." KILL: " (NO-NODE) THEN
DUP NODE-KILL DUP NO-ROUTE GONE-DOWN ;
Block 8001
: PAUSE ( n -- )
(THERE?) 0= IF ." PAUSE: " (NO-NODE) THEN NODE-SLEEP ;
: RESUME ( n -- )
(THERE?) 0= IF ." RESUME: " (NO-NODE) THEN NODE-WAKE ;
( n -- a unit is removed: each of n's children, then n )
: UNIT-KILL ( n -- )
BEGIN DUP 0 NODE-CHILD ?DUP WHILE KILL REPEAT KILL ;
( n -- A SECOND CENTRE, node n, from its port 6 to Hera's )
( port 6, given centre.4th; it births its unit, n+1 to n+4. )
: CENTRE ( n -- )
DUP 6 6 S" v4:centre.4th" BIRTH-AS DROP
5 1 DO DUP I + 6 ROUTE LOOP DROP
(T0) (KID#) @ (TN) S" UNIT" (TS) (T) (TELL) ;