diff --git a/Programs/CosmOS/Source/cosmos.asm b/Programs/CosmOS/Source/cosmos.asm index 13525f6..73ab0be 100644 --- a/Programs/CosmOS/Source/cosmos.asm +++ b/Programs/CosmOS/Source/cosmos.asm @@ -5568,8 +5568,6 @@ MonitorPrompt: UnknownText: " ? " -MonitorName: -"monitor" MonitorHelp: "x examine, d disassemble, a assemble, s set, b bank, g go, exit leaves" ExamineName: @@ -5604,6 +5602,17 @@ NoSuchOp: "no such instruction" NeedsValue: "that one needs a value after it" +; ---- The shell's own words, packed ---- +; +; Fifteen names with nothing between them, which is a TABLE and not an accident of layout. +; Each is a string ending in a zero, so the next one begins after that zero and walking them +; needs no pointers and no lengths - which is what makes completing a half typed command +; possible at all, since the dispatch below is a chain of comparisons and cannot be walked. +; +; NOTHING MAY BE PUT BETWEEN THEM. Tests/docs.sh checks that this run holds exactly the names +; the dispatch tests and that the count below agrees, so a command added without a name here +; is caught rather than silently left out of what Tab knows about. +ShellNames: DirName: "dir" DoName: @@ -5632,6 +5641,12 @@ HelpName: "help" ExitName: "exit" +MonitorName: +"monitor" + +; How many of them, since a run of strings does not say where it stops. +ShellNameCount: + 0d15 ; Where the machine is, written out for the prompt, and where in the buffer it begins. ; Built from the end backwards, so it starts somewhere in the middle. diff --git a/Tests/docs.sh b/Tests/docs.sh index 7ee3d2f..d968493 100755 --- a/Tests/docs.sh +++ b/Tests/docs.sh @@ -456,6 +456,50 @@ for name, text in (("the Programming Manual", pm), ("the Assembler Manual", am), problems.append("%s still says \"%s\", and it has not been true since" " directories arrived" % (name, claim)) +# ---- The shell's words are a table as well as a chain of comparisons ---- +# +# The dispatch is a run of "is the line this name" tests, which is fine to execute and +# impossible to WALK - so completing a half typed command needs the names as data too, and +# they are: fifteen strings packed end to end from ShellNames, each ending in the zero that +# says where the next begins. +# +# THE TWO CAN DISAGREE AND THE WAY THEY DO IS QUIET. A command added to the dispatch and not +# to the run simply never completes, which nobody would think to test by hand; something put +# BETWEEN the strings ends the walk early and takes the rest of the commands with it. So this +# reads both and compares them, and reads the count as well, because a run of strings does +# not say where it stops. +cosmosSource = open("Programs/CosmOS/Source/cosmos.asm").read() + +# The dispatch, up to the point where the monitor's single letters begin - those are one +# character each and there is nothing to complete about them. +dispatchEnd = cosmosSource.find("SETD.0 Mode") +dispatched = re.findall(r"SETD\.1 (\w+Name)\b", cosmosSource[:dispatchEnd]) + +# The run, which ends at the first thing that is not a label and a string. +runAt = cosmosSource.find("ShellNames:") +packed = [] +if runAt < 0: + problems.append("cosmos.asm has no ShellNames run for the shell's own words") +else: + lines = cosmosSource[runAt:].split("\n")[1:] + while len(lines) >= 2 and re.fullmatch(r"(\w+Name):", lines[0]) \ + and re.fullmatch(r'"[^"]*"', lines[1]): + packed.append(lines[0][:-1]) + lines = lines[2:] + +stated = re.search(r"ShellNameCount:\s*\n\s*0d(\d+)", cosmosSource) +if not stated: + problems.append("cosmos.asm no longer says how many shell names there are") +elif int(stated.group(1)) != len(packed): + problems.append("cosmos.asm says there are %s shell names and the run holds %d" + % (stated.group(1), len(packed))) +if runAt >= 0 and sorted(packed) != sorted(dispatched): + missing = sorted(set(dispatched) - set(packed)) + extra = sorted(set(packed) - set(dispatched)) + problems.append("the shell's dispatch and its packed names disagree:%s%s" + % ("".join(" %s is dispatched and not in the run;" % n for n in missing), + "".join(" %s is in the run and not dispatched;" % n for n in extra))) + # ---- CosmOS fits in the half of the machine it says it does ---- # # The memory map in the CosmOS README is a CONVENTION. Nothing in the assembler, the