From d9ebc76cf5dde22f4b70afff5732b8f24c66d16c Mon Sep 17 00:00:00 2001 From: Anachronaut Date: Sun, 6 Sep 2026 15:06:26 -0400 Subject: [PATCH] A script is given words, and keeps them "do build.sh cosmos.asm" looked for a file called "build.sh cosmos.asm", because scriptOpen copied the whole rest of the line into the name. So a script could be told nothing, and a launcher - a script whose entire job is to hand on what it was told - could not exist. Now the name is cut off the front and what follows is kept whole. $1 to $9 are the words of it, walked out on demand, and $args is all of them. Nothing is stored per parameter, so there is no limit on how many a script may be handed and no second number to keep in step. Both ways of starting a script pass them on: "do" and typing the name. A word that was not given is an error that stops the script, like every other name this shell does not know. Expanding it to nothing would let a command run with an argument missing and then report success, which is what stop-on-failure exists to prevent. $args is always set inside a script, empty if it was given nothing, so "if same $args" can be asked. ---- And the count that describes the block was already wrong ---- Found while adding a field to it. The state one script keeps for another is saved by a single copy of a fixed number of bytes, and that number was 71 against a block of 77: six bytes of line position had been added in the middle of it years after the count was written. So the tail of every saved script was never saved, and #quiet in a helper stayed behind in the script that called it - the opposite of what this file's own comment promises and the README documents. The unsaved line position turned out not to matter, because a loop keeps its own copy in the block record. Nothing said so. Three numbers describe this block and all three now say so in a comment, and cosmosScriptNest ends on a helper that goes quiet and a caller that must not stay that way. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01E2JrLzFvuFX9fgi1LDRjrW --- .gitignore | 1 + Programs/CosmOS/README.md | 48 +++++++- Programs/CosmOS/Source/cosmos.asm | 178 +++++++++++++++++++++++++++- Programs/CosmOS/Source/script.asm | 58 +++++++-- SplitBit Test Manual.md | 2 +- Tests/expected/cosmos.out | 2 +- Tests/expected/cosmosCrossDisk.out | 7 +- Tests/expected/cosmosDeep.out | 2 +- Tests/expected/cosmosDrives.out | 7 +- Tests/expected/cosmosFault.out | 7 +- Tests/expected/cosmosFlip.out | 7 +- Tests/expected/cosmosGrid.out | 7 +- Tests/expected/cosmosInvoke.out | 2 +- Tests/expected/cosmosMonitor.out | 7 +- Tests/expected/cosmosMonitorRun.out | 7 +- Tests/expected/cosmosRun.out | 7 +- Tests/expected/cosmosScriptArgs.out | 43 +++++++ Tests/expected/cosmosScriptNest.out | 7 ++ Tests/expected/cosmosSlowDisk.out | 7 +- Tests/expected/cosmosSprite.out | 7 +- Tests/expected/cosmosTyped.out | 2 +- Tests/input/cosmosScriptArgs.in | 7 ++ Tests/input/cosmosScriptNest.in | 1 + Tests/makedisks.sh | 27 +++++ Tests/manifest | 16 +++ 25 files changed, 441 insertions(+), 25 deletions(-) create mode 100644 Tests/expected/cosmosScriptArgs.out create mode 100644 Tests/input/cosmosScriptArgs.in diff --git a/.gitignore b/.gitignore index 129c0a0..b20bce4 100644 --- a/.gitignore +++ b/.gitignore @@ -46,3 +46,4 @@ Source/Emulator/rom.c # The personal disk 'make run-voyager' puts in drive 1. Made on demand, never rebuilt, and # not cleaned - it is the one place in here where something made ON the machine can live. /Disks/ +*.sym diff --git a/Programs/CosmOS/README.md b/Programs/CosmOS/README.md index 70a1b29..7ec8cd6 100644 --- a/Programs/CosmOS/README.md +++ b/Programs/CosmOS/README.md @@ -216,6 +216,52 @@ line comes from - the shell splits it, matches it and runs it without knowing th a file is reached by its whole name, the way `load` is for a program. See Starting An Application By Name. +### What A Script Is Given: + +Whatever followed the name reaches the script, whichever way it was started - `do build.sh +cosmos.asm` and `build.sh cosmos.asm` hand it the same thing. + +| Name | What it stands for | +| -- | -- | +| `$1` to `$9` | The words it was given, counted from one. | +| `$args` | All of them, exactly as they were typed. | + +``` +#! script +; build.sh +echo building $1 +cd /Source +Asm $1 +``` + +**Nothing is stored per parameter.** The line is kept whole and the word wanted is walked out +of it, so there is no limit on how many words a script may be handed and nothing to keep in +step. `$args` is that line; `$1` is a word copied out of it. + +**A word that was not given is an error**, exactly like any other name the shell does not +know: `$2` in a script given one word says `nothing is set called 2` and stops the script. +Expanding it to nothing would let a command run with an argument missing and report success, +which is the failure the whole stop-on-error rule exists to prevent. A script that genuinely +wants to work with or without something can ask `if same $args` - and `$args` is always set +inside a script, empty if it was given nothing, so that question can always be asked. + +**At the prompt they mean nothing**, and say so. There is no script there to have been given +anything, so `$1` is a name nobody set. + +**A script's own words win over anything `set`.** They are looked at before the eight named +slots, so a parameter cannot be shadowed by something left lying about at the prompt. + +**Each script has its own**, saved and restored with the rest of where it had got to. A script +that hands different words to a helper still has its own when the helper returns. That is also +what makes a **launcher** possible: a script whose whole body is one line handing on what it +was told, without knowing what any of it means. + +``` +#! script +; /Apps/Lander - the launcher +Packages/app.Lander/Lander $args +``` + ``` #! script ; Build the system and put it where the machine will find it. @@ -325,7 +371,7 @@ CosmOS currently provides these built-in commands: | `dir` | List the files on the mounted disk and their sizes. | | `load ` | Read and validate an SBEX application, then place its code and data where its header requests. | | `run [words]` | Start the loaded application and make the rest of the line available to it as an argument. | -| `do