diff --git a/Programs/CosmOS/README.md b/Programs/CosmOS/README.md index 1b0373c..15a917e 100644 --- a/Programs/CosmOS/README.md +++ b/Programs/CosmOS/README.md @@ -116,6 +116,56 @@ an installed library and a copy of the source. The disk is rebuilt from scratch when its applications change, so its contents describe the current source tree rather than accumulating files left by older builds. +## Scripts: + +`do ` runs the lines in a file as though somebody had typed them. Every command works +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. + +``` +#! script +; Build the system and put it where the machine will find it. +cd /Source/CosmOS +Asm cosmos.asm +``` + +**The first two bytes must be `#!`**, or the shell refuses the file and says so. That is what +tells a script from anything else, and it is deliberately not the name and not a flag in the +directory entry: the rule this filesystem keeps is that an entry holds only what the content +cannot say about itself, and a script can say what it is. The loader already refuses anything +that does not begin `SBEX`, so the two kinds of runnable file turn each other away without +either of them having been told about the other. + +What follows the `#!` is ignored. It is where the name of an interpreter goes if there is ever +a second one; today there is one and it is this shell. + +**`#` is a directive and `;` is a comment, exactly as in SplitBit assembly.** One rule across +the machine rather than two dialects: `#` means this line is about the file, `;` means ignore +this line. Comments and blank lines never reach the shell at all - they are dropped by the +reader, so they are not echoed and the dispatch never sees a line it would have to know to +ignore. This is not Unix's convention and is not trying to be; there `#!` genuinely is a +comment that only the kernel looks at, while here the shell requires it. + +**Each line is echoed as it runs**, after the prompt, so that a script reads exactly like +somebody typing it and a script that stops says where. + +**A script stops at the first line that does not work.** A build whose first step failed and +whose second step ran anyway produces something wrong and reports success, which is the whole +reason the shell now remembers whether a line worked. What counts as not working is a command +that failed, a name the shell does not know, or a program that exited with a status. Nothing +is printed but `stopped: that line did not work` - whatever failed has already said what was +wrong in words. + +**A script running out is not the same as typing running out.** The console ending means +there is nobody there and the shell stops; a script ending means go back to whoever asked for +it, so the next line comes from the console again. + +The interactive assembler reads its lines the same way, so a script can contain a block of +assembly and end it with a `.` just as you would by hand. + +**A script cannot yet run another script.** That is the next thing, and it wants a stack of +positions rather than the single one the reader keeps today. + ## Shell Commands: CosmOS currently provides these built-in commands: @@ -125,6 +175,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