Start a program by typing its name
A word the shell has no command for is now looked for on the disk as "<name>.sbx", and if it is there it is loaded and started exactly as load and run would do it. Whatever followed the word reaches the program through osArgument by the same route as whatever follows run, so "Say hello there" and "Type notes.txt" work without either program knowing how it was started. load and run are unchanged and both stay. load is how the monitor puts an arbitrary file in front of itself, which typing a name deliberately cannot do: the extension is added rather than assumed, so "notes.txt" looks for notes.txt.sbx and a text file is unreachable by name whatever is inside it. Three things this had to get right: The built-ins are tried first and always win. The search hangs off the end of the dispatch chain, so a file called dir.sbx cannot become dir, and the commands worth trusting when the disk is what you are doubting stay trustworthy. The invoke disk carries a working dir.sbx so that this is checked rather than asserted. A file that is found but is broken says so. "not a program" and "I do not know" are different answers, and giving the second about a file sitting on the disk would send somebody looking in the wrong place. loadProgram therefore hands back a status as well as a message, since only "no file of that name" can fairly be reported as anything other than a fault. doLoad became that subroutine rather than being copied. It ends in RET instead of a jump to the prompt, and each way of failing sets its number and its text together so a new one cannot leave half of the answer behind. cosmosBreak moves because Break prints the pointers it was handed and those are the shell's leftovers, which a CALL now puts back. 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
dbe58db660
commit
2b0aeeefd4
@@ -2,6 +2,7 @@ CosmOS
|
||||
> dir list what is on the disk
|
||||
load <file> read a program off the disk
|
||||
run [words] start what was loaded, and tell it those words
|
||||
<name> [words] load and start that program off the disk
|
||||
delete <file> take it off the disk
|
||||
rename <file> <to> call it something else
|
||||
monitor look at memory, change it, and jump into it
|
||||
|
||||
@@ -3,11 +3,11 @@ CosmOS
|
||||
> two stops, and what the registers were at each
|
||||
break at 200E
|
||||
A 11 B 22 Q 00 status 00
|
||||
DP0 1030 DP1 0663 DP2 039C DP3 2000 SP FFFF
|
||||
DP0 1030 DP1 06C2 DP2 0000 DP3 2000 SP FFFF
|
||||
press a key
|
||||
break at 2023
|
||||
A 44 B 55 Q 00 status 00
|
||||
DP0 1000 DP1 0663 DP2 039C DP3 2000 SP FFF5
|
||||
DP0 1000 DP1 06C2 DP2 0000 DP3 2000 SP FFF5
|
||||
press a key
|
||||
carried on to the end
|
||||
finished
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
CosmOS
|
||||
> it says: hello there
|
||||
finished
|
||||
> it says: spelled out in full
|
||||
finished
|
||||
> it says: once more
|
||||
finished
|
||||
> Say.sbx 155
|
||||
dir.sbx 155
|
||||
notes.txt 21
|
||||
notes.sbx 21
|
||||
4 files
|
||||
> not a program
|
||||
> not a program
|
||||
> I do not know: notes.txt
|
||||
> I do not know: nosuchprogram
|
||||
> I do not know: abcdefghijklmnopqr
|
||||
> I do not know: abcdefghijklmnopqrs
|
||||
> dir list what is on the disk
|
||||
load <file> read a program off the disk
|
||||
run [words] start what was loaded, and tell it those words
|
||||
<name> [words] load and start that program off the disk
|
||||
delete <file> take it off the disk
|
||||
rename <file> <to> call it something else
|
||||
monitor look at memory, change it, and jump into it
|
||||
help this
|
||||
exit stop, or leave the monitor if you are in it
|
||||
> halted
|
||||
Execution halted.
|
||||
[exit 0]
|
||||
@@ -0,0 +1,12 @@
|
||||
Say hello there
|
||||
Say.sbx spelled out in full
|
||||
run once more
|
||||
dir
|
||||
notes
|
||||
notes.sbx
|
||||
notes.txt
|
||||
nosuchprogram
|
||||
abcdefghijklmnopqr
|
||||
abcdefghijklmnopqrs
|
||||
help
|
||||
exit
|
||||
@@ -177,6 +177,25 @@ awk 'BEGIN { for (i = 0; i < 30; i++) printf "line %02d: ABCDEFGHIJKLMNOPQRSTUVW
|
||||
"$ROOT/Programs/CosmOS/Apps/More.asm" -o "$WORK/More.sbx" >/dev/null
|
||||
"$TOOL" put "$DISKS/type.img" "$WORK/More.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.
|
||||
#
|
||||
# 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
|
||||
# dispatch chain, this disk would start answering "dir" with a program.
|
||||
#
|
||||
# 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.
|
||||
"$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
|
||||
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
|
||||
|
||||
# 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 -
|
||||
# because a fault in either of those would otherwise turn up much later as a mysterious
|
||||
|
||||
@@ -324,6 +324,19 @@ cosmosType | CosmOS/Source/cosmos.asm | run | cosmosTyp
|
||||
# with Space, and one line with Return. The input is intentionally packed so that the one
|
||||
# byte the pager consumes leaves the next shell command immediately behind it.
|
||||
cosmosMore | CosmOS/Source/cosmos.asm | run | cosmosMore.in | - | disks/type.img
|
||||
# Typing a program's name starts it. The disk is built so that each line of the input asks
|
||||
# a different question of the one rule: "Say hello there" is a bare name with an argument,
|
||||
# "Say.sbx" is the same file spelled out in full, and "run once more" says the program that
|
||||
# was invoked really did land in the loaded slot and can be started again from it.
|
||||
#
|
||||
# Then the four ways a word does not become a running program. "dir" is a real program on
|
||||
# this disk and must still list the disk, because the built-ins are tried first. "notes"
|
||||
# finds notes.sbx and says it is not a program, which is the answer that has to differ from
|
||||
# "I do not know" - the file is there. "notes.txt" looks for notes.txt.sbx and finds
|
||||
# nothing, which is how a text file stays unreachable by name. And the last two are the
|
||||
# length boundary: eighteen characters is the longest bare name that leaves room for the
|
||||
# extension, and nineteen cannot be a file name at all, so both are unknown words.
|
||||
cosmosInvoke | CosmOS/Source/cosmos.asm | run | cosmosInvoke.in | - | disks/invoke.img
|
||||
# The assembler's front end, checked in two pieces before anything is built on it.
|
||||
#
|
||||
# cosmosSource reads a source file and prints it back. The file crosses a block boundary,
|
||||
|
||||
Reference in New Issue
Block a user