The shell runs what it reads, not what a name ends in
A typed word had ".sbx" pasted on the end of it before anything went looking, which is why "notes.txt" sent the shell after a notes.txt.sbx that was never going to exist, and why a script could only be started with "do". The extension was what made a file reachable by name. Now the word as typed is asked for first and the word with the extension on it only after that misses. What comes back is dispatched on what is inside it: SBEX loads and starts, "#!" is read as lines. The loader already refuses anything that is not SBEX and the script reader already refuses anything without the shebang, so the two kinds of runnable file turn each other away and neither has to know the other exists. The suffix can only ever be a second guess, so a file that is really there always beats one that would have to be invented and every program already on a disk still starts by the short name people type for it. It costs a second walk of each directory when a word is not found in it. Tab completion offers a file under the name it actually has, and the suffix stripper is gone: a first word can now be any file at all, and offering only the ones ending .sbx would hide the scripts. The video capture windows moved out a hundred thousand cycles, because starting Lander now walks four names where it walked two. 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
4e61158b11
commit
fd962f0084
@@ -11,15 +11,27 @@ finished
|
||||
> dir
|
||||
Say.sbx 156
|
||||
dir.sbx 156
|
||||
Greet 156
|
||||
notes.txt 21
|
||||
notes.sbx 21
|
||||
4 files
|
||||
hello.sh 38
|
||||
Apps <dir>
|
||||
6 files, 1 directory
|
||||
> Greet a program with no extension
|
||||
it says: a program with no extension
|
||||
finished
|
||||
> hello.sh
|
||||
> echo a script, started by its name
|
||||
a script, started by its name
|
||||
> away.sh
|
||||
> echo a script from the system place
|
||||
a script from the system place
|
||||
> notes
|
||||
not a program
|
||||
that is not a program or a script: notes
|
||||
> notes.sbx
|
||||
not a program
|
||||
that is not a program or a script: notes.sbx
|
||||
> notes.txt
|
||||
I do not know: notes.txt
|
||||
that is not a program or a script: notes.txt
|
||||
> nosuchprogram
|
||||
I do not know: nosuchprogram
|
||||
> abcdefghijklmnopqr
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
CosmOS
|
||||
> Cr[2;3HCrash [2;9Hzz
|
||||
> Cr[2;3HCrash.sbx [2;13Hzz
|
||||
Crash opcode | service | bank | device | blind
|
||||
finished
|
||||
> Sa[5;3HSay[5;6Hzz
|
||||
I do not know: Sayzz
|
||||
> Sa[5;3HSay.sbx[5;10Hzz
|
||||
I do not know: Say.sbxzz
|
||||
> cd Ap[7;3Hcd Apps/[7;11H
|
||||
/Apps> echo where am I
|
||||
where am I
|
||||
|
||||
@@ -2,6 +2,9 @@ Say hello there
|
||||
Say.sbx spelled out in full
|
||||
run once more
|
||||
dir
|
||||
Greet a program with no extension
|
||||
hello.sh
|
||||
away.sh
|
||||
notes
|
||||
notes.sbx
|
||||
notes.txt
|
||||
|
||||
+16
-3
@@ -487,8 +487,8 @@ printf 'and these are the very different notes in B\n' > notesB.txt
|
||||
"$ROOT/Programs/CosmOS/Apps/Wander.asm" -o "$WORK/Wander.sbx" >/dev/null
|
||||
"$TOOL" put "$DISKS/cwd.img" "$WORK/Wander.sbx" /Apps/Wander.sbx >/dev/null
|
||||
|
||||
# A disk for invoking a program by typing its name. Four files, each there to say one
|
||||
# thing about how a typed word turns into a file name.
|
||||
# A disk for invoking a program by typing its name. Every file on it is there to say one
|
||||
# thing about how a typed word turns into a file that runs.
|
||||
#
|
||||
# dir.sbx is a working program under the name of a built-in command, which is the only way
|
||||
# to check that the built-ins really are tried first. If the search ever moved ahead of the
|
||||
@@ -496,15 +496,28 @@ printf 'and these are the very different notes in B\n' > notesB.txt
|
||||
#
|
||||
# notes.sbx is text under a program's name, so that a file that IS found and IS NOT a
|
||||
# program can be told apart from a word that names nothing. notes.txt is the same text
|
||||
# under its own name, which no typed word can reach: "notes.txt" looks for notes.txt.sbx.
|
||||
# under its own name - which the shell could not reach at all until it began trying the
|
||||
# word as typed, because "notes.txt" only ever looked for notes.txt.sbx.
|
||||
#
|
||||
# Greet is a program with NO extension, and hello.sh is a script. Neither could be started
|
||||
# by typing its name before the shell decided what to run by reading it, and between them
|
||||
# they are the whole of that claim: SBEX loads, #! is read as lines, and the name says
|
||||
# nothing about which happened. /Apps/away.sh is the same for a script found somewhere
|
||||
# other than where you are standing.
|
||||
"$TOOL" format "$DISKS/invoke.img" 64 2 >/dev/null
|
||||
"$ROOT/Assembler" -I "$ROOT/Programs/CosmOS/Source" \
|
||||
"$ROOT/Programs/CosmOS/Apps/Say.asm" -o "$WORK/Say.sbx" >/dev/null
|
||||
"$TOOL" put "$DISKS/invoke.img" "$WORK/Say.sbx" >/dev/null
|
||||
"$TOOL" put "$DISKS/invoke.img" "$WORK/Say.sbx" dir.sbx >/dev/null
|
||||
"$TOOL" put "$DISKS/invoke.img" "$WORK/Say.sbx" Greet >/dev/null
|
||||
printf 'this is not a program' > notes.txt
|
||||
"$TOOL" put "$DISKS/invoke.img" notes.txt >/dev/null
|
||||
"$TOOL" put "$DISKS/invoke.img" notes.txt notes.sbx >/dev/null
|
||||
printf '#!\necho a script, started by its name\n' > "$WORK/hello.sh"
|
||||
"$TOOL" put "$DISKS/invoke.img" "$WORK/hello.sh" hello.sh >/dev/null
|
||||
"$TOOL" mkdir "$DISKS/invoke.img" /Apps >/dev/null
|
||||
printf '#!\necho a script from the system place\n' > "$WORK/away.sh"
|
||||
"$TOOL" put "$DISKS/invoke.img" "$WORK/away.sh" /Apps/away.sh >/dev/null
|
||||
|
||||
# A disk for the assembler that runs on the machine. It holds a source file and the two
|
||||
# programs that check the front end - the reader on its own and the tokenizer on its own -
|
||||
|
||||
+9
-2
@@ -1690,8 +1690,15 @@ print(sum(1 for o in range(0, len(px), 3) if px[o:o + 3] == moon))
|
||||
# What is checked is that it is HIGHER LATER: two captures, the second further on, and the
|
||||
# lander nearer the top in the second. A thruster that only fired once for a held button
|
||||
# would let it fall between them instead, which is exactly what the console does.
|
||||
#
|
||||
# ONE AND 1.8 MILLION, and they were 800 thousand and 1.6 million. The shell tries a typed
|
||||
# word as the name of a file before it tries it with ".sbx" on the end, so starting Lander
|
||||
# now walks four names where it walked two, and at 800 thousand the program had not drawn
|
||||
# yet - which reads as row -1 and fails, correctly, for a reason that has nothing to do with
|
||||
# thrusters. The gap between the two captures is what the check is made of, and it is the
|
||||
# same gap.
|
||||
python3 -c "open('$BUILD/lander.pad','wb').write(b'\x00' * 40 + b'\x08' * 400)"
|
||||
for when in 800000 1600000; do
|
||||
for when in 1000000 1800000; do
|
||||
timeout 30 "$EMU" --fast --cycles $when --keyboard "$BUILD/lander.keys" \
|
||||
--pad "$BUILD/lander.pad" --screen "$BUILD/held$when.ppm" \
|
||||
--disk "$ROOT/Tests/build/disks/cosmos.img" --ram-disk 2048 \
|
||||
@@ -1705,7 +1712,7 @@ def top(path):
|
||||
ship = bytes.fromhex('d8c048')
|
||||
ys = [i // 320 for i in range(len(px) // 3) if px[i * 3:i * 3 + 3] == ship]
|
||||
return min(ys) if ys else -1
|
||||
print(top('$BUILD/held800000.ppm'), top('$BUILD/held1600000.ppm'))
|
||||
print(top('$BUILD/held1000000.ppm'), top('$BUILD/held1800000.ppm'))
|
||||
" 2>/dev/null || echo "-1 -1")
|
||||
EOT
|
||||
[ "$EARLY" -gt 0 ] && [ "$LATE" -gt 0 ] && [ "$LATE" -lt "$EARLY" ] \
|
||||
|
||||
Reference in New Issue
Block a user