Loops, and the scripting language is a language
while and for. Both only mean anything in a script, because a loop goes back to the line that opened it and a prompt has no line to go back to - and both say so rather than doing something surprising. THE SCRIPT READER KEEPS THE POSITION OF EVERY LINE before reading it, which is what makes any of this possible: by the time a line has been read the reader is past it, and a line is not a fixed size to subtract. Three words per line, and the block is read again on the way back so the pointer into it means what it meant - the same thing nesting one script inside another already did, for a different reason. THE TWO LOOPS END DIFFERENTLY, and that is the design rather than an accident. A while is taken away at its end and its own line asks the question again, so nothing has to be remembered. A for is not: how many words it has used is kept in the block, and its line reads itself again and counts one more off the front. That is a byte in a block instead of a copy of the word list in every one of them. Blocks grew from a byte to a record of sixteen - state, kind, words used, and where the line that opened it was - and sixteen because A and B are a shift register, so four rotations turn a block number into its offset. The history and the variables are addressed the same way for the same reason. Nested loops, an if inside a loop, a loop inside a branch nobody takes, and a for with no words: the last two run no times rather than once, which is the case worth having a test for. Three things found by running it: textSame asks whether two WHOLE strings are the same, so "in red green blue" is not "in". The word has to be split off before it is compared. A for typed at a prompt complained about while, because both arrive at the same place. One message that names neither is better than one that names the wrong one. And docs.sh caught a naming convention nobody had written down: it recognises a packed name by its label ending in "Name", so ForName2 was silently not counted. It failed the right way round - saying the run was shorter than the count claims rather than passing - but the convention now lives where the names are and not only in the checker. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E2JrLzFvuFX9fgi1LDRjrW
This commit is contained in:
co-authored by
Claude Opus 5
parent
16f8232a35
commit
2abc8281df
@@ -243,6 +243,21 @@ scriptLine:
|
||||
STD.0.1
|
||||
|
||||
scriptLineAgain:
|
||||
; ---- Where this line begins ----
|
||||
;
|
||||
; Kept before it is read, because a loop has to be able to go back to the line that opened
|
||||
; it and by the time that line has been read the reader is past it. Three words, and the
|
||||
; block itself is read again on the way back, which is what scriptReread is for.
|
||||
SETD.0 ScriptIndex
|
||||
SETD.1 ScriptLineIndex
|
||||
CALL sbfsCopyWord
|
||||
SETD.0 ScriptAt
|
||||
SETD.1 ScriptLineAt
|
||||
CALL sbfsCopyWord
|
||||
SETD.0 ScriptBlocks
|
||||
SETD.1 ScriptLineBlocks
|
||||
CALL sbfsCopyWord
|
||||
|
||||
SETD.1 ScriptLength
|
||||
RSTA
|
||||
STA.1
|
||||
@@ -539,6 +554,19 @@ ScriptIndex:
|
||||
0x00 0x00
|
||||
ScriptAt:
|
||||
0x00 0x00
|
||||
|
||||
; ---- And where the line being read began ----
|
||||
;
|
||||
; A loop goes back to the line that opened it, and by the time that line has been read the
|
||||
; reader is past it. So the position is kept before every line rather than worked out
|
||||
; afterwards, which cannot be done: a line is not a fixed size and there is nothing to
|
||||
; subtract.
|
||||
ScriptLineIndex:
|
||||
0x00 0x00
|
||||
ScriptLineAt:
|
||||
0x00 0x00
|
||||
ScriptLineBlocks:
|
||||
0x00 0x00
|
||||
; Saved with the rest, so that a quiet script calling a loud one gets its quiet back when
|
||||
; the loud one finishes. A new script INHERITS it rather than resetting, because a build
|
||||
; that asked for quiet meant its helpers too; only the first script started from the prompt
|
||||
|
||||
Reference in New Issue
Block a user