Lines that are only run sometimes
if, else, end, and same. IF TAKES A COMMAND, which is one rule rather than two and is why comparing values needs no syntax of its own: "same" is an ordinary command that fails when its two words differ, so "if same $a $b" falls out of the rule instead of being an exception to it. Anything else that can fail is a question too - "if load Snake.sbx" is a perfectly good one. The shell already had the other half. LineFailed exists because a script stops at the first line that did not work, so every command was already saying whether it had, for a different reason entirely. A BLOCK HAS TWO KINDS OF NOT-RUNNING. One where an else would turn it on, and one where it would not - which is what an if pushes when something above it is already being skipped. That is what makes nesting need no looking down the stack: the top of it says everything. A branch nobody is taking is not even looked at. The skipping happens BEFORE the names are filled in, so a variable mentioned in a branch that is not running is not an error - a line nobody runs must not be able to fail. AND LINES MAY BE INDENTED, which they could not be before there was anything to indent inside. Nobody writes an if inside an if without indenting what is in them, and a leading space used to make the first word empty and match nothing. Found by writing the test script the way anybody would write one. CALL commandFailed became BRI commandFailed in nine places. It never returns - it marks the line and branches to the prompt - so calling it was a lie that cost a Stack frame each time, and fourteen other sites already branched. THE LINT RULE FOUND THIS, three days after I wrote the rule and on my own code: two false positives that were really the linter being right about a CALL that is not one. It does not fix the leak on its own, since a failure inside any called routine still abandons that frame, but it removes the cause of the commonest case and makes the code true. The mechanical edit then left a BRI prompt stranded behind one of them, and the linter caught that too. 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
4b109f704c
commit
16f8232a35
@@ -0,0 +1,54 @@
|
||||
CosmOS
|
||||
> set a hello
|
||||
> if same $a hello
|
||||
> echo taken
|
||||
taken
|
||||
> else
|
||||
> echo not taken
|
||||
> end
|
||||
> if load nosuch.sbx
|
||||
no such file
|
||||
> echo loaded
|
||||
> else
|
||||
> echo did not
|
||||
did not
|
||||
> end
|
||||
> else
|
||||
else with no if above it
|
||||
> end
|
||||
end with no if above it
|
||||
> if
|
||||
if wants a command to decide by
|
||||
> do blocks.script
|
||||
> set colour red
|
||||
> if same $colour red
|
||||
> echo it is red
|
||||
it is red
|
||||
> if same $colour blue
|
||||
> echo and blue
|
||||
> else
|
||||
> echo but not blue
|
||||
but not blue
|
||||
> end
|
||||
> else
|
||||
> echo $neverSetAnywhere
|
||||
> end
|
||||
> if same $colour blue
|
||||
> echo wrong
|
||||
> else
|
||||
> echo right
|
||||
right
|
||||
> end
|
||||
> if same $colour blue
|
||||
> if same $colour red
|
||||
> echo deep wrong
|
||||
> else
|
||||
> echo deep also wrong
|
||||
> end
|
||||
> end
|
||||
> echo done
|
||||
done
|
||||
> exit
|
||||
halted
|
||||
Execution halted.
|
||||
[exit 0]
|
||||
@@ -24,6 +24,7 @@ Press.sbx 872
|
||||
Mode.sbx 48
|
||||
Crash.sbx 632
|
||||
vars.script 50
|
||||
blocks.script 343
|
||||
tune.sbx 306
|
||||
notes.txt 21
|
||||
Apps <dir>
|
||||
@@ -36,7 +37,7 @@ outer.script 376
|
||||
inner.script 44
|
||||
loop.script 35
|
||||
crossed.txt 560
|
||||
23 files, 1 directory
|
||||
24 files, 1 directory
|
||||
> exit
|
||||
halted
|
||||
Execution halted.
|
||||
|
||||
@@ -14,6 +14,7 @@ Press.sbx 872
|
||||
Mode.sbx 48
|
||||
Crash.sbx 632
|
||||
vars.script 50
|
||||
blocks.script 343
|
||||
tune.sbx 306
|
||||
notes.txt 21
|
||||
Apps <dir>
|
||||
@@ -25,7 +26,7 @@ nonl.script 38
|
||||
outer.script 376
|
||||
inner.script 44
|
||||
loop.script 35
|
||||
22 files, 1 directory
|
||||
23 files, 1 directory
|
||||
> drive 1
|
||||
> dir
|
||||
other.txt 28
|
||||
|
||||
@@ -31,6 +31,7 @@ Press.sbx 872
|
||||
Mode.sbx 48
|
||||
Crash.sbx 632
|
||||
vars.script 50
|
||||
blocks.script 343
|
||||
tune.sbx 306
|
||||
notes.txt 21
|
||||
Apps <dir>
|
||||
@@ -42,7 +43,7 @@ nonl.script 38
|
||||
outer.script 376
|
||||
inner.script 44
|
||||
loop.script 35
|
||||
22 files, 1 directory
|
||||
23 files, 1 directory
|
||||
> exit
|
||||
halted
|
||||
Execution halted.
|
||||
|
||||
@@ -21,6 +21,7 @@ Press.sbx 872
|
||||
Mode.sbx 48
|
||||
Crash.sbx 632
|
||||
vars.script 50
|
||||
blocks.script 343
|
||||
tune.sbx 306
|
||||
notes.txt 21
|
||||
Apps <dir>
|
||||
@@ -32,7 +33,7 @@ nonl.script 38
|
||||
outer.script 376
|
||||
inner.script 44
|
||||
loop.script 35
|
||||
22 files, 1 directory
|
||||
23 files, 1 directory
|
||||
> exit
|
||||
halted
|
||||
Execution halted.
|
||||
|
||||
@@ -107,6 +107,7 @@ Press.sbx 872
|
||||
Mode.sbx 48
|
||||
Crash.sbx 632
|
||||
vars.script 50
|
||||
blocks.script 343
|
||||
tune.sbx 306
|
||||
notes.txt 21
|
||||
Apps <dir>
|
||||
@@ -118,7 +119,7 @@ nonl.script 38
|
||||
outer.script 376
|
||||
inner.script 44
|
||||
loop.script 35
|
||||
22 files, 1 directory
|
||||
23 files, 1 directory
|
||||
> exit
|
||||
halted
|
||||
Execution halted.
|
||||
|
||||
@@ -26,6 +26,7 @@ Press.sbx 872
|
||||
Mode.sbx 48
|
||||
Crash.sbx 632
|
||||
vars.script 50
|
||||
blocks.script 343
|
||||
tune.sbx 306
|
||||
notes.txt 21
|
||||
Apps <dir>
|
||||
@@ -37,7 +38,7 @@ nonl.script 38
|
||||
outer.script 376
|
||||
inner.script 44
|
||||
loop.script 35
|
||||
22 files, 1 directory
|
||||
23 files, 1 directory
|
||||
> exit
|
||||
halted
|
||||
Execution halted.
|
||||
|
||||
@@ -14,6 +14,7 @@ Press.sbx 872
|
||||
Mode.sbx 48
|
||||
Crash.sbx 632
|
||||
vars.script 50
|
||||
blocks.script 343
|
||||
tune.sbx 306
|
||||
notes.txt 21
|
||||
Apps <dir>
|
||||
@@ -25,7 +26,7 @@ nonl.script 38
|
||||
outer.script 376
|
||||
inner.script 44
|
||||
loop.script 35
|
||||
22 files, 1 directory
|
||||
23 files, 1 directory
|
||||
> load
|
||||
load what?
|
||||
> load nosuch.sbx
|
||||
|
||||
@@ -12,6 +12,7 @@ Press.sbx 872
|
||||
Mode.sbx 48
|
||||
Crash.sbx 632
|
||||
vars.script 50
|
||||
blocks.script 343
|
||||
tune.sbx 306
|
||||
notes.txt 21
|
||||
Apps <dir>
|
||||
@@ -23,7 +24,7 @@ nonl.script 38
|
||||
outer.script 376
|
||||
inner.script 44
|
||||
loop.script 35
|
||||
22 files, 1 directory
|
||||
23 files, 1 directory
|
||||
> load Say.sbx
|
||||
loaded, starting at 5000
|
||||
> run the disk took its time
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
set a hello
|
||||
if same $a hello
|
||||
echo taken
|
||||
else
|
||||
echo not taken
|
||||
end
|
||||
if load nosuch.sbx
|
||||
echo loaded
|
||||
else
|
||||
echo did not
|
||||
end
|
||||
else
|
||||
end
|
||||
if
|
||||
do blocks.script
|
||||
exit
|
||||
@@ -132,7 +132,12 @@ for i in 1 2 3 4 5 6 7 8; do "$TOOL" put "$DISKS/sbfs.img" "filler$i.txt" >/dev/
|
||||
# A script that names something nothing was ever set to. Stop on failure is what says the
|
||||
# expansion really did fail rather than merely complaining: the line after it must not run.
|
||||
printf '#! script\necho before\necho $nosuchname\necho after\n' > vars.script
|
||||
# A script with blocks in it, because that is where they are actually for. It nests, it
|
||||
# takes the second branch of an outer if, and the branch nobody takes mentions a name that
|
||||
# was never set - which must not be an error, because nothing there is being run.
|
||||
printf '#! script\nset colour red\nif same $colour red\n echo it is red\n if same $colour blue\n echo and blue\n else\n echo but not blue\n end\nelse\n echo $neverSetAnywhere\nend\nif same $colour blue\n echo wrong\nelse\n echo right\nend\nif same $colour blue\n if same $colour red\n echo deep wrong\n else\n echo deep also wrong\n end\nend\necho done\n' > blocks.script
|
||||
"$TOOL" put "$DISKS/cosmos.img" vars.script >/dev/null
|
||||
"$TOOL" put "$DISKS/cosmos.img" blocks.script >/dev/null
|
||||
# tune.sbx, which used to be a boot image and is now a program like any other. It brings a
|
||||
# vector of its own - the screen's, so that it has a beat to play to - which makes it the
|
||||
# second thing here that the version two format exists for.
|
||||
|
||||
@@ -425,6 +425,19 @@ cosmosVars | CosmOS/Source/cosmos.asm | run | cosmosVar
|
||||
# Break is what makes it visible, because it prints the registers. The two dumps have to
|
||||
# agree, and the failures between them are what would move it.
|
||||
cosmosStack | CosmOS/Source/cosmos.asm | run | cosmosStack.in | - | disks/cosmos.img
|
||||
# Lines that are only run sometimes. "if" takes a COMMAND and what follows runs only if that
|
||||
# command worked - the Bourne shell's answer, and the reason "test" exists there: one rule in
|
||||
# if, and comparing two things is just another command that can fail. Here that command is
|
||||
# "same", and the shell already had the other half in LineFailed.
|
||||
#
|
||||
# AN if INSIDE A BRANCH NOBODY IS TAKING IS NOT A QUESTION. Its else must not run either, so
|
||||
# it is pushed as a block that neither branch of can be taken - which is why a block has two
|
||||
# kinds of not-running rather than one, and why nesting needs no looking down the stack.
|
||||
#
|
||||
# THE BRANCH NOBODY TAKES IS NOT EVEN LOOKED AT. The script names a variable that was never
|
||||
# set, inside the branch that is not taken, and that must not be an error - so the skipping
|
||||
# happens before the names are filled in, and a line nobody is running cannot fail.
|
||||
cosmosBlocks | CosmOS/Source/cosmos.asm | run | cosmosBlocks.in | - | disks/cosmos.img
|
||||
# The same editing offered to a PROGRAM, through osReadLine. Edit reads its lines that way,
|
||||
# so a word typed with two letters the wrong way round is put right without starting the line
|
||||
# again - which is the whole of what A4 buys.
|
||||
|
||||
Reference in New Issue
Block a user