fix(v4.0.0): step 6e review round 1 -- a take that does not take does nothing; output and answers wait at a middle node; no queue on the kernel's port; a printing wait is not interrupted
- The result of every take is looked at: a wire cut between the look and the take leaves nothing acted on (the text before run again, a refusal counted, a wait ended by an old answer, a way forgotten). - A node with no room to pass on what another printed, or its word of how text ended, leaves it on the wire it came by and moves it when there is room; what is behind it for the same port waits too. Sleep for room (9) is woken by room on any of the node's wires (engine; MESH.md 7d.3). - The lone node's host keeps no queue for the kernel's port: a message to it is error 18. The step limit is counted while the node waits for room. - A text waiting for room to print is not interrupted by console text; AWAIT is, as before. (BREAK?) is gone. - A GONE is believed only by the centre's port; unawaited answers let go are counted; nothing past a message's last character goes on a wire; AWAIT sets (AWAIT-FROM) only once the stack has been tried. - test_host_depth.c: ten paths, each run works or ends in one named stack error; it fails with (ROOM) or (ROOM-SERVE) taken out. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
b1d09af043
commit
6a7d0aa27f
+72
-47
@@ -246,12 +246,28 @@ header CMOVE
|
||||
MINE: drop 1 (A-SELF) a! ! ;
|
||||
NOT: drop ;
|
||||
|
||||
\ ( port -- bit ) the bit for a port, by its number, in a word of a bit to a port
|
||||
: (WBIT)
|
||||
push 1 pop if Z -1 + FOR 2* NEXT ;
|
||||
Z: drop ;
|
||||
|
||||
\ ( -- ) A MESSAGE FOR ANOTHER NODE is passed on (MESH.md section 7): the
|
||||
\ one the mark of the wire in (WIRE) is at, whose seven words are in (IN),
|
||||
\ is moved, whole, to the wire that leads toward that node. It is refused
|
||||
\ instead if it has been passed on as often as a message may be; if there
|
||||
\ is no way, or no one on the port; if that wire has no room for it; or if
|
||||
\ that wire is the one room is kept on and it would take that room.
|
||||
\ instead if it has been passed on as often as a message may be; or if
|
||||
\ there is no way, or no one on the port.
|
||||
\ WITH NO ROOM on that wire -- or none but the room kept on it, (KEEP) --
|
||||
\ text, a NACK and a GONE are refused, at once. But what a node printed
|
||||
\ (type 2) and its word of how text ended (type 3) are NOT let go for want
|
||||
\ of room: the message is left where it is, on the wire it came by, and
|
||||
\ gone past; what is behind it is served; and it is moved on a later pass,
|
||||
\ when there is room. Printing waits; it is not lost (MESH.md 7d.1,
|
||||
\ ruling 3). (H-PORT) and (H-NEED) are the port of the first message left
|
||||
\ so on this pass and the cells it needs there: a node that then sleeps,
|
||||
\ sleeps for that room, (SLEEP), and is woken by room on any wire.
|
||||
\ (H-MASK) has a bit for each port something was left for: what is behind
|
||||
\ it for the same port is left too, though it be shorter and would fit, so
|
||||
\ that what a node printed goes on in the order it came.
|
||||
\ HOW OFTEN. A message's fourth word is how many more nodes may pass it
|
||||
\ on; a node sends it with 16, and a move takes one off. The node that
|
||||
\ finds 1 there refuses it. A device sends it with 0, which is taken for
|
||||
@@ -262,13 +278,31 @@ header CMOVE
|
||||
14 + -if OK jump SPENT
|
||||
POS: if OK -1 + if SPENT -16 + -if SPENT
|
||||
OK: drop
|
||||
(IN) a! @ (WAY) dup (P-WAY) a! !
|
||||
(KEEP) a! @ xor if KEPT
|
||||
GO: drop (P-WAY) a! @ (WIRE-A) b! !b 3 (DO) if MOVED
|
||||
(IN) a! @ (WAY) (P-WAY) a! !
|
||||
(IN)+6 a! @ 3 + 2/ 2/ 7 + \ the cells it takes,
|
||||
(P-WAY) a! @ (KEEP) a! @ xor if KEPT drop jump NEED
|
||||
KEPT: drop 8 + \ and the room kept, if it is that wire
|
||||
NEED: (P-NEED) a! !
|
||||
(P-WAY) a! @ -if WAY \ no way: refused
|
||||
SPENT: drop jump (REFUSE)
|
||||
WAY: (WBIT) (H-MASK) a! @ and if CLEAR \ something is left for that port already?
|
||||
FULL: drop (IN)+2 a! @ -2 + if HOLD -1 + if HOLD jump SPENT \ no room: only output and answers wait
|
||||
CLEAR: drop
|
||||
(P-NEED) a! @ (P-WAY) a! @ (ROOM?) (S-WIRE) a! @ (WIRE!)
|
||||
if GO -1 + if FULL jump SPENT \ no one on that port: refused
|
||||
GO: drop (P-WAY) a! @ (WIRE-A) b! !b 3 (DO) if MOVED jump SPENT
|
||||
MOVED: drop ;
|
||||
KEPT: drop (IN)+6 a! @ 3 + 2/ 2/ 15 + (P-WAY) a! @ (ROOM?)
|
||||
(S-WIRE) a! @ (WIRE!) if GO jump SPENT
|
||||
HOLD: drop
|
||||
(P-WAY) a! @ (WBIT) dup inv (H-MASK) a! @ and + !
|
||||
(H-PORT) a! @ -if HELD drop (P-WAY) a! @ (H-PORT) a! ! (P-NEED) a! @ (H-NEED) a! ! 7 (DO) drop ;
|
||||
HELD: drop 7 (DO) drop ;
|
||||
|
||||
\ ( -- ) SLEEP until a message comes -- or, if (SERVE) left a message
|
||||
\ on a wire for want of room, until there is that room or a message comes
|
||||
\ or any wire of this node's gains room (operation 9, MESH.md 7d.3).
|
||||
: (SLEEP)
|
||||
(H-PORT) a! @ -if ROOM drop 8 (DO) drop ;
|
||||
ROOM: (WIRE!) (H-NEED) a! @ (WIRE-A) b! !b 9 (DO) drop ;
|
||||
|
||||
\ ( -- ) ONE PASS OVER EVERY WIRE THAT HAS A MESSAGE. What is for another
|
||||
\ node is passed on, or refused; what is for this node is left where it
|
||||
@@ -278,7 +312,7 @@ header CMOVE
|
||||
\ looks for what is this node's own, (MINE).
|
||||
: (SERVE)
|
||||
(WIRE-HAVE) b! @b dup (S-HAVE) a! ! (S-MASK) a! !
|
||||
0 (S-WIRE) a! !
|
||||
0 (S-WIRE) a! ! -1 (H-PORT) a! ! 0 (H-MASK) a! !
|
||||
W: (S-MASK) a! @ if END
|
||||
dup 2/ ! 1 and if NEXTW
|
||||
drop (S-WIRE) a! @ (WIRE!) 6 (DO) drop
|
||||
@@ -316,44 +350,29 @@ header CMOVE
|
||||
\ ( -- ) go past the message (MINE) found: it stays on its wire
|
||||
: (SKIP) (S-WIRE) a! @ (WIRE!) 7 (DO) drop ;
|
||||
|
||||
\ ( -- ) take the message (MINE) found, which has one word of text: its
|
||||
\ seven words stay in (IN), and its word goes to (ONE)
|
||||
: (TAKE1) (S-WIRE) a! @ (WIRE!) (IN) (WIRE-A) b! !b (ONE) (WIRE-B) b! !b 2 (DO) drop ;
|
||||
|
||||
\ ( -- n ) the number of this node's console: the one it was told of, or
|
||||
\ with none told of, whoever sent the text it is doing
|
||||
: (A-CONSOLE)
|
||||
(CONSOLE) a! @ if C0 ;
|
||||
C0: drop (MSG)+1 a! @ ;
|
||||
|
||||
\ ( -- ) A LINE FROM THE CONSOLE BREAKS A WAIT FOR ROOM (MESH.md 7d.4).
|
||||
\ If text for this node from its console is on a wire, the text being
|
||||
\ done ends in error 21, Interrupted; the text from the console stays
|
||||
\ where it is, to be done when this one has been finished with. Only
|
||||
\ text that is still being done is broken: not once it has ended in an
|
||||
\ error -- NODE-ERROR holds the code from then until the next text begins
|
||||
\ -- or been finished with, (QUIET), when what waits for room is only what
|
||||
\ it printed and the word of how it ended.
|
||||
: (BREAK?)
|
||||
(QUIET) a! @ if TEXT drop ;
|
||||
TEXT: drop NODE-ERROR b! @b if CLEAN drop ;
|
||||
CLEAN: drop (MINE0)
|
||||
L: (MINE) if NO
|
||||
drop (IN)+2 a! @ -1 + if T
|
||||
KEEP: drop (SKIP) jump L
|
||||
T: drop (A-CONSOLE) (IN)+1 a! @ xor if BRK jump KEEP
|
||||
BRK: drop NODE-ERROR b! 21 !b ;
|
||||
NO: drop ;
|
||||
\ ( -- how ) take the message (MINE) found, which has one word of text:
|
||||
\ its seven words stay in (IN), and its word goes to (ONE). 0: it is
|
||||
\ taken. Anything else: it is not -- the wire was cut after the message
|
||||
\ was looked at -- and (ONE) is not its word: nothing is to be done for it.
|
||||
: (TAKE1) (S-WIRE) a! @ (WIRE!) (IN) (WIRE-A) b! !b (ONE) (WIRE-B) b! !b 2 jump (DO)
|
||||
|
||||
\ ( -- how ) WAIT UNTIL THE WIRE of the port (W-PORT) has (W-NEED) cells
|
||||
\ free. 0: it has. 2: no one is on that port. The node sleeps until
|
||||
\ there is room or a message comes; woken by a message it passes on what
|
||||
\ is for other nodes, (SERVE), and sleeps again. It is the one thing a
|
||||
\ node waits to put: what a text prints (MESH.md 7d.1, ruling 3).
|
||||
\ there is room, or a message comes, or another wire of its own gains
|
||||
\ room; woken with no room yet, it passes on what is for other nodes,
|
||||
\ (SERVE), and sleeps again. It is the one thing a node waits to put:
|
||||
\ what a text prints (MESH.md 7d.1, ruling 3).
|
||||
\ NOTHING BREAKS THIS WAIT but the room coming or the wire being cut
|
||||
\ (ruled 2026-10-08): text for this node that comes meanwhile, from its
|
||||
\ console or anyone, stays on its wire and is done when this text has been
|
||||
\ finished with. A text whose printing can never go, because a stuck node
|
||||
\ is on the way, waits until that node is killed (MESH.md 7d.6).
|
||||
: (WAIT-ROOM)
|
||||
L: (W-PORT) a! @ (WIRE!) (W-NEED) a! @ (WIRE-A) b! !b 9 (DO)
|
||||
if DONE -1 + if WOKEN drop 2 ;
|
||||
WOKEN: drop (ROOM-SERVE) (SERVE) (BREAK?) jump L
|
||||
WOKEN: drop (WIRE-HAVE) b! @b if QUIET \ no wire has a message: there is nothing to pass on,
|
||||
drop (ROOM-SERVE) (SERVE) jump L \ and no more of the stacks is asked for than a wait needs
|
||||
QUIET: drop jump L
|
||||
DONE: ;
|
||||
|
||||
\ ( -- ) send what has been printed, to where (PRINT-TO) says, by the port
|
||||
@@ -363,10 +382,15 @@ header CMOVE
|
||||
\ wire is the one the answer goes by. The characters are made ready in
|
||||
\ (OUT-TEXT), not where they are: until the message is on the wire the
|
||||
\ buffer is as it was, and a fault on the way leaves it to be sent again.
|
||||
\ The three cells after the last character are made zero first, so that
|
||||
\ nothing printed earlier goes on the wire in the last word (they are in
|
||||
\ the buffer, or the four free cells after it).
|
||||
\ The three cells and two return entries this needs are tried first.
|
||||
\ WITH NO ONE ON THE PORT what was printed cannot be sent. While the text
|
||||
\ is being done that is its error, 18; once it has been finished with
|
||||
\ there is no one to tell: it is let go and counted in (LOST).
|
||||
\ WITH NO ONE ON THE PORT -- when it waits for room, or when it comes to
|
||||
\ put -- what was printed cannot be sent. While the text is being done
|
||||
\ that is its error, 18. Once it has been finished with, what it printed
|
||||
\ is let go and counted in (LOST), and the text is said to have ended in
|
||||
\ an error: (LINE-STATUS), which is the word then sent of how it ended.
|
||||
: (FLUSH-OUT)
|
||||
(OUT^) a! @ (OUT) xor if NONE drop
|
||||
0 0 0 drop drop drop 0 push 0 push pop drop pop drop
|
||||
@@ -375,16 +399,17 @@ header CMOVE
|
||||
SAME: drop 8 +
|
||||
NEED: (W-NEED) a! ! (PRINT-PORT) a! @ (W-PORT) a! !
|
||||
(WAIT-ROOM) if ROOM
|
||||
drop (QUIET) a! @ if TELL
|
||||
LOSE: drop (OUT) (OUT^) a! ! (LOST) a! @ 1 + ! ;
|
||||
NOONE: drop (QUIET) a! @ if TELL
|
||||
drop (OUT) (OUT^) a! ! (LOST) a! @ 1 + ! 2 (LINE-STATUS) a! ! ;
|
||||
TELL: drop NODE-ERROR b! 18 !b ;
|
||||
ROOM: drop
|
||||
(PRINT-TO) a! @ 2 (HDR)
|
||||
(OUT^) a! @ a! 0 !+ 0 !+ 0 !
|
||||
(OUT^) a! @ (OUT) - dup (OUT-HDR)+6 a! !
|
||||
3 + 2/ 2/ -1 + push (OUT-TEXT) pop (OUT) a!
|
||||
FOR @+ @+ 8* + @+ 8* 8* + @+ 8* 8* 8* + over b! !b 1 + NEXT
|
||||
drop
|
||||
(OUT-TEXT) (PRINT-PORT) a! @ (PUT-ON) if SENT jump LOSE
|
||||
(OUT-TEXT) (PRINT-PORT) a! @ (PUT-ON) if SENT jump NOONE
|
||||
SENT: drop (OUT) (OUT^) a! ! ;
|
||||
NONE: drop ;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user