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
+45
-23
@@ -28,8 +28,9 @@ for itself.
|
||||
- Loadable Applications: Validate SBEX files, copy their Program and Data segments into
|
||||
the addresses for which they were assembled, and start them at their declared entry
|
||||
point.
|
||||
- Invocation By Name: A word the shell has no command for is looked for on the disk as
|
||||
`<name>.sbx`, and loaded and started if it is there. Built-in commands are tried first.
|
||||
- Invocation By Name: A word the shell has no command for is looked for on the disk, and
|
||||
what is found is run according to what is inside it - a program is loaded and started, a
|
||||
script is read as lines. Built-in commands are tried first.
|
||||
- Resident Services: Applications can print strings and numbers, read lines, receive their
|
||||
command arguments, read and write files, and return to the shell through named software
|
||||
interrupts.
|
||||
@@ -211,6 +212,10 @@ A `$` with nothing name-like after it is just a `$`.
|
||||
the same way it does at the prompt, because the only thing a script changes is where the next
|
||||
line comes from - the shell splits it, matches it and runs it without knowing the difference.
|
||||
|
||||
**Typing a script's name runs it too**, the same way typing a program's name does; `do` is how
|
||||
a file is reached by its whole name, the way `load` is for a program. See Starting An
|
||||
Application By Name.
|
||||
|
||||
```
|
||||
#! script
|
||||
; Build the system and put it where the machine will find it.
|
||||
@@ -327,7 +332,7 @@ CosmOS currently provides these built-in commands:
|
||||
| `cd [path]` | Go to a directory, or to the root with nothing after it. |
|
||||
| `mkdir <path>` | Make a directory. |
|
||||
| `rmdir <path>` | Remove one, if it is empty. |
|
||||
| `<name> [words]` | Any word the shell does not recognise is looked for on the disk as `<name>.sbx`, and loaded and started if it is there. |
|
||||
| `<name> [words]` | Any word the shell does not recognise is looked for on the disk, and started if it is found: loaded if it is a program, read as lines if it is a script. |
|
||||
| `delete <file>` | Remove a file from the filesystem and release its blocks. |
|
||||
| `rename <file> <to>` | Give a file a different name without moving its contents. |
|
||||
| `set [name [value]]` | Give a name a value, or say what the names are. See Names For Things. |
|
||||
@@ -422,18 +427,23 @@ program; anything after it is a file.
|
||||
|
||||
| Where | What is offered |
|
||||
| -- | -- |
|
||||
| The first word | the fifteen commands, and programs - under the name you would type, with the extension taken off |
|
||||
| The first word | the fifteen commands, and every file, under the name it actually has |
|
||||
| After it | anything on the disk, under its real name |
|
||||
| Either, with a `/` in it | whatever is in the directory the word names |
|
||||
|
||||
A directory answers with a separator on the end instead of a space, which says what it is and
|
||||
lets the next part be typed straight away.
|
||||
|
||||
**Programs are looked for in the three places the shell would look to run one**: where you
|
||||
are, `/Apps` on the disk you are on, and `/Apps` on drive 0. Offering something the shell
|
||||
would not find would be finishing a word into a thing that then does not work. A program that
|
||||
is in two of those places is offered twice and so is never the only match, which costs it the
|
||||
space after it - the shell is comparing names, not deciding which file it would have run.
|
||||
**Files are looked for in the three places the shell would look to run one**: where you are,
|
||||
`/Apps` on the disk you are on, and `/Apps` on drive 0. Offering something the shell would not
|
||||
find would be finishing a word into a thing that then does not work. A file that is in two of
|
||||
those places is offered twice and so is never the only match, which costs it the space after
|
||||
it - the shell is comparing names, not deciding which file it would have run.
|
||||
|
||||
A first word used to be offered with `.sbx` taken off, and anything without that ending was
|
||||
not offered at all. That was right while the extension was what made a file reachable; now
|
||||
that the shell decides by reading, hiding the files without one would hide scripts - which is
|
||||
much of what a first word is.
|
||||
|
||||
Nothing typed and nothing matching both do nothing, quietly.
|
||||
|
||||
@@ -640,22 +650,34 @@ directory's unused fields hold, the version, the free count.
|
||||
### Starting An Application By Name:
|
||||
|
||||
A word the shell has no command for is not immediately an error. Before saying so, the
|
||||
shell adds `.sbx` to it unless it is already there, looks for a file of that name, and if
|
||||
one is there loads it and starts it exactly as `load` and `run` would. Whatever followed
|
||||
the word reaches the program through `osArgument`, the same way and by the same route as
|
||||
whatever follows `run`.
|
||||
shell looks for a file of that name and, if one is there, decides what to do with it by
|
||||
what is inside it. Whatever followed the word reaches the program through `osArgument`, the
|
||||
same way and by the same route as whatever follows `run`.
|
||||
|
||||
Three properties of this are deliberate:
|
||||
**The shell runs what it reads.** A file beginning `SBEX` is loaded and started exactly as
|
||||
`load` and `run` would; a file beginning `#!` is read as lines exactly as `do` would. The
|
||||
loader already refuses anything that is not `SBEX` and the script reader already refuses
|
||||
anything without the shebang, so between them the two kinds of runnable thing turn each
|
||||
other away and neither has to know the other exists. **The name says nothing about which
|
||||
happened**, which is what makes `.sbx` a convention rather than a rule.
|
||||
|
||||
Four properties of this are deliberate:
|
||||
|
||||
**Built-in commands are tried first and always win.** The search happens only after the
|
||||
whole dispatch chain has failed to match, so a file named `dir.sbx` cannot become `dir`.
|
||||
The commands that are worth trusting when the disk is the thing being doubted stay
|
||||
trustworthy.
|
||||
|
||||
**The extension is what makes a file reachable by name.** Typing `notes` looks for
|
||||
`notes.sbx`, and typing `notes.txt` looks for `notes.txt.sbx`. A text file therefore
|
||||
cannot be started by typing what it is called, whatever happens to be inside it. Only
|
||||
`load` reaches a file by its literal name.
|
||||
**The word as typed is tried first, and only then the word with `.sbx` on the end.** The
|
||||
first is what makes a file reachable under the name it actually has - a script, a program
|
||||
somebody dropped the extension from, or a launcher. The second is what keeps every program
|
||||
already on a disk startable by the short name people have always typed for it. The suffix
|
||||
can only ever be a second guess, so a file that is really there always wins over one that
|
||||
would have to be invented, and typing `notes.txt` no longer sends the shell after a
|
||||
`notes.txt.sbx` that was never going to exist.
|
||||
|
||||
It costs a second walk of each directory when a word is not found in it, which is the price
|
||||
of the exact name being asked for first.
|
||||
|
||||
A path works here too, so `/Apps/Say hello` starts `/Apps/Say.sbx` and gives it `hello`.
|
||||
|
||||
@@ -666,10 +688,10 @@ said where to look, so only that place is tried. Neither is stored anywhere, so
|
||||
nothing to configure and nothing to go stale - a search path somebody could set would need
|
||||
somewhere to live between one boot and the next, and there is no such place yet.
|
||||
|
||||
**A file that is found but is broken says so.** If `notes.sbx` exists and is not an SBEX
|
||||
program, typing `notes` reports `not a program` rather than `I do not know: notes`.
|
||||
Reporting an unknown command about a file that is sitting on the disk would send somebody
|
||||
looking in the wrong place.
|
||||
**A file that is found but is neither says so.** If `notes.txt` exists and begins with
|
||||
neither `SBEX` nor `#!`, typing `notes.txt` reports `that is not a program or a script`
|
||||
rather than `I do not know: notes.txt`. Reporting an unknown command about a file that is
|
||||
sitting on the disk would send somebody looking in the wrong place.
|
||||
|
||||
Names are matched exactly, including case, because every other name on the filesystem is.
|
||||
What limits the typed word is the buffer it is built in rather than the format: each name
|
||||
@@ -688,7 +710,7 @@ laid out in three directories:
|
||||
|
||||
| Where | What |
|
||||
| -- | -- |
|
||||
| `/Apps` | The programs. The second place the shell looks for a word it does not recognise, so anything here starts by name from anywhere on the disk. |
|
||||
| `/Apps` | What you run. The second place the shell looks for a word it does not recognise, so anything here starts by name from anywhere on the disk - programs, and scripts too. |
|
||||
| `/Source` | The things you name to the assembler: CosmOS itself, the assembler itself, and small programs to read. |
|
||||
| `/Lib` | The things those include. Everything here is named by an `#Include` somewhere and by nothing else, which is what makes it a library rather than a source. |
|
||||
|
||||
|
||||
Reference in New Issue
Block a user