X-Git-Url: https://jxself.org/git/?a=blobdiff_plain;f=md%2Flanguage.md;h=fa5b46940dfad634bc5fe342c77b5a295ce44818;hb=90a91e98a93b9707b88400032c9ba942328bef8a;hp=2714db96138a00a8808de432aa5e1d8f930eec6f;hpb=1f96e35373b905c64c5bbf76bc5696702e036404;p=mudman.git diff --git a/md/language.md b/md/language.md index 2714db9..fa5b469 100644 --- a/md/language.md +++ b/md/language.md @@ -1,3 +1,9 @@ +% The Muddle Programming Language +% Greg Pfister + S. W. Galley + et al. +% 1979 + MIT Technical Report 293 Laboratory for Computer Science\ @@ -13,21 +19,21 @@ This document is free of known copyright restrictions. Abstract ======== -The Muddle programming language began existence in late 1970 (under -the name Muddle) as a successor to Lisp (Moon, 1974), a candidate -vehicle for the Dynamic Modeling System, and a possible base for -implementation of Planner (Hewitt, 1969). The original design goals -included an interactive integrated environment for programming, -debugging, loading, and editing: ease in learning and use; facilities -for structured, modular, shared programs; extensibility of syntax, -data types and operators: data-type checking for debugging and -optional data-type declarations for compiled efficiency; associative -storage, coroutining, and graphics. Along the way to reaching those -goals, it developed flexible input/output (including the ARPA -Network), and flexible interrupt and signal handling. It now serves as -a base for software prototyping, research, development, education, and -implementation of the majority of programs at MIT-DMS: a library of -sharable modules, a coherent user interface, special research +The Muddle programming language began existence in late 1970 as a +successor to Lisp (Moon, 1974), a candidate vehicle for the Dynamic +Modeling System, and a possible base for implementation of Planner +(Hewitt, 1969). The original design goals included an interactive +integrated environment for programming, debugging, loading, and +editing: ease in learning and use; facilities for structured, +modular, shared programs; extensibility of syntax, data types and +operators: data-type checking for debugging and optional data-type +declarations for compiled efficiency; associative storage, +coroutining, and graphics. Along the way to reaching those goals, it +developed flexible input/output (including the ARPA Network), and +flexible interrupt and signal handling. It now serves as a base for +software prototyping, research, development, education, and +implementation of the majority of programs at MIT-DMS: a library of +sharable modules, a coherent user interface, special research projects, autonomous daemons, etc. This document was originally intended to be a simple low-level @@ -54,7 +60,7 @@ Acknowledgements I was not a member of the original group which labored for two years in the design and initial implementation of Muddle; that group was -composed principally of Gerald Sussman, Carl Hewit, Chris Reeve, Dave +composed principally of Gerald Sussman, Carl Hewitt, Chris Reeve, Dave Cressey, and later Bruce Daniels. I would therefore like to take this opportunity to thank my Muddle mentors, chiefly Chris Reeve and Bruce Daniels, for remaining civil through several months of verbal @@ -119,16 +125,16 @@ on. There are no "practice problems"; you are assumed to be learning Muddle for some purpose, and your work in achieving that purpose will -be more useful and motivated than artificial problems. In several +be more useful and motivating than artificial problems. In several cases, the examples contain illustrations of important points which -are not covered in the text. Ignore examples as your peril. +are not covered in the text. Ignore examples at your peril. This document does not assume knowledge of any specific programming -language on the \[sic\] your part. However, "computational literacy" -is assumed: you should have written at least one program before. Also -very little familiarity is assumed with the interactive time-sharing -operating systems under which Muddle runs -- ITS, Tenex, and Tops-20 --- namely just file and user naming conventions. +language on your part. However, "computational literacy" is assumed: +you should have written at least one program before. Also very little +familiarity is assumed with the interactive time-sharing operating +systems under which Muddle runs -- ITS, Tenex, and Tops-20 -- namely +just file and user naming conventions. ### Notation @@ -150,7 +156,7 @@ a computer terminal appears herein in a fixed width font, as in `ROOT`. A metasyntactic variable -- something to be replaced in actual use by something else -- appears as *radix:fix*, in an italic font; often the variable will have both a meaning and a data type (as here), -but sometimes one of those will be ommitted, for obvious reasons. +but sometimes one of those will be omitted, for obvious reasons. An ellipsis (...) indicates that something uninteresting has been omitted. The character `^` means that the following character is to be @@ -169,8 +175,8 @@ especially upon reaching chapter 5 (Simple Functions). ------------------------- First, catch your rabbit. Somehow get the interpreter running -- the -program in the file `SYS:TS.Muddle` in the ITS version or -`SYS:Muddle.SAV` in the Tenex version or `SYS:Muddle.EXE` in the +program in the file `SYS:TS MDL` in the ITS version or +`SYS:MDL.SAV` in the Tenex version or `SYS:MDL.EXE` in the Tops-20 version. The interpreter will first type out some news relating to Muddle, if any, then type @@ -203,7 +209,7 @@ interpreted as an expression(s) in Muddle. When this interpretation is done, the result will be printed and Muddle will wait for more typing. `ESC` will be represented by the glyph `$` in this document. -Typing the rubout character (`DEL` in the ITS and Top-20 versions, +Typing the rubout character (`DEL` in the ITS and Tops-20 versions, `CTRL`+`A` in the Tenex version) causes the last character in the buffer -- the one most recently typed -- to be thrown away (deleted). If you now immediately type another rubout, once again the last @@ -225,9 +231,8 @@ except that, if your terminal is a "display" terminal (for example, IMLAC, ARDS, Datapoint), it firsts clears the screen. Typing `^G` (`CTRL`+`G`) causes Muddle to stop whatever it is doing -and act as if an error had occurred ([section -1.4](#14-errors-simple-considerations-1)). `^G` is generally most -useful for temporary interruptions to check the progress of a +and act as if an error had occurred (section 1.4). `^G` is generally +most useful for temporary interruptions to check the progress of a computation. `^G` is "reversible" -- that is, it does not destroy any of the "state" of the computation it interrupts. To "undo" a `^G`, type the characters @@ -237,11 +242,11 @@ type the characters (This is discussed more fully far below, in section 16.4.) Typing `^S` (`CTRL`+`S`) causes Muddle to **throw away** what it is -currently doing and return a normal "listening" state. (In the Tenex -and Tops-20 versions, `^O` also should have the same effect.) `^S` is -generally most useful for aborting infinite loops and similar terrible -things. `^S` **destroys** whatever is going on, and so it is **not** -reversible. +currently doing and return to a normal "listening" state. (In the +Tenex and Tops-20 versions, `^O` also should have the same effect.) +`^S` is generally most useful for aborting infinite loops and similar +terrible things. `^S` **destroys** whatever is going on, and so it is +**not** reversible. Most expressions in Muddle include "brackets" (generically meant) that must be correctly paired and nested. If you end your typing with the @@ -1174,7 +1179,7 @@ re-bound....) One way to "name" a `FUNCTION` is )>$ - #FUNCTION ((X) <* .X .X> + #FUNCTION ((X) <* .X .X>) So that @@ -1186,7 +1191,7 @@ So that Another way, which is somewhat cleaner in its typing: >>$ - #FUNCTION ((X) <* .X .X> + #FUNCTION ((X) <* .X .X>) `FUNCTION` is an `FSUBR` which simply makes a `FUNCTION` out of its arguments and returns the created `FUNCTION`. @@ -2003,7 +2008,7 @@ cases, since Direct Representation usually produces exactly the same effect (in the absence of errors), and the intention is more apparent. \[Note: if `.L` is a `LIST`, `` makes a copy of `.L` whereas `(!.L)` doesn't; see section 7.7.\] `STRING`, on the other hand, -produces effect very different from literal `STRING`s. +produces effects very different from literal `STRING`s. Examples: @@ -4126,30 +4131,30 @@ used on the `CHANNEL`, and whether or not the *device* is a terminal. The following table tells which `SUBR`s can be used with which modes, where `OK` indicates an allowed use: - ------------------------------------------------------------------------------------------------------------------------------------------------- - "READ" "PRINT" "READB" "PRINTB", "PRINTO" mode / SUBRs - -------------------- --------------------- --------------------- -------------------------------------------- ----------------------------------- - OK OK `READ` `READCHR` `NEXTCHR` - `READSTRING` `FILECOPY` - `FILE-LENGTH LOAD` + ------------------------------------------------------------------------- + "READ" "PRINT" "READB" "PRINTB", "PRINTO" mode / SUBRs + ------ ------- ------- ------------------ ------------ + OK OK `READ` `READCHR` `NEXTCHR` + `READSTRING` `FILECOPY` + `FILE-LENGTH LOAD` - OK OK\* `PRINT` `PRIN1` `PRINC` `IMAGE` - `CRLF` `TERPRI` `FILECOPY` - `PRINTSTRING` `BUFOUT` `NETS` - `RENAME` + OK OK\* `PRINT` `PRIN1` `PRINC` `IMAGE` + `CRLF` `TERPRI` `FILECOPY` + `PRINTSTRING` `BUFOUT` `NETS` + `RENAME` - OK `READB` `GC-READ` + OK `READB` `GC-READ` - OK `PRINTB` `GC-DUMP` + OK `PRINTB` `GC-DUMP` - OK OK OK `ACCESS` + OK OK OK `ACCESS` - OK OK OK OK `RESET` + OK OK OK OK `RESET` - OK OK `ECHOPAIR` + OK OK `ECHOPAIR` - OK `TTYECHO` `TYI` - ------------------------------------------------------------------------------------------------------------------------------------------------- + OK `TTYECHO` `TYI` + ------------------------------------------------------------------------- `*` PRINTing (or `PRIN1`ing) an `RSUBR` (chapter 19) on a `"PRINTB"` or `"PRINTO"` `CHANNEL` has special effects. @@ -4272,52 +4277,52 @@ each element, and an interpretation. The format used is the following: *element-number: type interpretation* - ---------------------------------------------------------------------------------------------------- - element-number type interpretation - -------------------------- ------------------ ------------------------------------------------------ - -1 `LIST` transcript channel(s) (see below) + ------------------------------------------------------------------------------------- + element-number type interpretation + ---------------- ------------- ------------------------------------------------------ + -1 `LIST` transcript channel(s) (see below) - \* 0 varies device-dependent information + \* 0 varies device-dependent information - \* 1 `FIX` channel number (ITS) or JFN (Tenex and Tops-20), `0` - for internal or closed + \* 1 `FIX` channel number (ITS) or JFN (Tenex and Tops-20), `0` + for internal or closed - \* 2 `STRING` mode + \* 2 `STRING` mode - \* 3 `STRING` first file name argument + \* 3 `STRING` first file name argument - \* 4 `STRING` second file name argument + \* 4 `STRING` second file name argument - \* 5 `STRING` device name argument + \* 5 `STRING` device name argument - \* 6 `STRING` directory name argument + \* 6 `STRING` directory name argument - \* 7 `STRING` real first file name + \* 7 `STRING` real first file name - \* 8 `STRING` real second file name + \* 8 `STRING` real second file name - \* 9 `STRING` real device name + \* 9 `STRING` real device name - \* 10 `STRING` real directory name + \* 10 `STRING` real directory name - \* 11 `FIX` various status bits + \* 11 `FIX` various status bits - \* 12 `FIX` PDP-10 instruction used to do one I/O operation + \* 12 `FIX` PDP-10 instruction used to do one I/O operation - 13 `FIX` number of characters per line of output + 13 `FIX` number of characters per line of output - 14 `FIX` current character position on a line + 14 `FIX` current character position on a line - 15 `FIX` number of lines per page + 15 `FIX` number of lines per page - 16 `FIX` current line number on a page + 16 `FIX` current line number on a page - 17 `FIX` access pointer for file-oriented devices + 17 `FIX` access pointer for file-oriented devices - 18 `FIX` radix for `FIX` conversion + 18 `FIX` radix for `FIX` conversion - 19 `FIX` sink for an internal `CHANNEL` - ---------------------------------------------------------------------------------------------------- + 19 `FIX` sink for an internal `CHANNEL` + ------------------------------------------------------------------------------------- N.B.: The elements of a `CHANNEL` below number 1 are usually invisible but are obtainable via ` fix>`, for some appropriate @@ -4700,7 +4705,7 @@ Muddle behaves like the ITS version of the text editor Teco with respect to typing in carriage-return, in that it automatically adds a line-feed. In order to type in a lone carriage-return, a carriage-return followed by a rubout must be typed. Also `PRINT`, -`PRINT1` and `PRINC` do not automatically add a line-feed when a +`PRIN1` and `PRINC` do not automatically add a line-feed when a carriage-return is output. This enables overstriking on a terminal that lacks backspacing capability. It also means that what goes on a terminal and what goes in a file are more likely to look the same. @@ -7125,7 +7130,7 @@ is written, so that the code is not duplicated on disk. A purified produces objects of `TYPE` `LOCR` instead of `LOCD`. 19.5. TYPE-C and TYPE-W -======================= +----------------------- In order to handle user `NEWTYPE`s reasonably, the internal `TYPE` codes for them have to be able to be different from one Muddle run to @@ -7902,7 +7907,7 @@ At any given time there is a defined **interrupt level**. This is a `FIX` which determines which interrupts can really "interrupt" -- that is, cause the current processing to be suspended while their wants are satisfied. Normal, non-interrupt programs operate at an interrupt -level of 0 (zero.) An interrupt is processed at an interrupt level +level of 0 (zero). An interrupt is processed at an interrupt level equal to the interrupt's priority. ### 21.7.1. Interrupt Processing @@ -7952,13 +7957,13 @@ If `INT-LEVEL` lowers the priority of the interrupt level, it does not priority than the target priority have been processed. Setting the `INT-LEVEL` extremely high (for example, -` FIX>>`) effectively disables all interrupts +` FIX>>`) effectively disables all interrupts (but occurrences of enabled interrupts will still be queued). If `LISTEN` or `ERROR` is called when the `INT-LEVEL` is not zero, then the typeout will be - LISTENING-AT-LEVEL I PROCESS p INT-LEVEL i + LISTENING-AT-LEVEL l PROCESS p INT-LEVEL i ### 21.7.3. DISMISS @@ -7989,7 +7994,7 @@ Muddle is communicating with a person or another processor. Each interrupt, and the mode of the `CHANNEL` tells what kinds of `"CHAR"` interrupts occur to be handled through that `IHEADER`. -1. If the `CHANNEL` is for `INPUT`, "CHAR" occurs every time an +1. If the `CHANNEL` is for `INPUT`, `"CHAR"` occurs every time an "interesting" character (see below) is received from the `CHANNEL`'s real terminal, or any character is received from the `CHANNEL`'s pseudo-terminal, or a character or word is received @@ -8012,7 +8017,7 @@ which it was typed. In the ITS version, the "interesting" characters are those "enabled for interrupts" on a real terminal, namely `^@` through `^G`, `^K` through `^_`, and `DEL` (that is, ASCII codes 0-7, 13-37, and 177 -octal.) +octal). In the Tenex and Tops-20 versions, the operating system can be told which characters typed on a terminal should cause this interrupt to @@ -8060,7 +8065,7 @@ an input `CHANNEL` open to a pseudo-terminal ("STY" device and friends). An interrupt occurs when a character is available for input. These interrupts are set up in exactly the same way as real-terminal interrupts, except that a handler gets applied to only **one** -argument, the `CHANNEL`. Pseudo-terminal are not available in the +argument, the `CHANNEL`. Pseudo-terminals are not available in the Tenex and Tops-20 versions. For any other flavor of ITS channel interrupt, a handler gets applied @@ -8126,7 +8131,7 @@ unfortunately). a deferrable garbage collection that is needed because of exhausted movable garbage-collected storage. Enabling this interrupt is the only way a program can know that a garbage collection is about to occur. A -handler takes two arguments: A `FIX` telling the number of machine +handler takes two arguments: a `FIX` telling the number of machine words needed and an `ATOM` telling what initiated the garbage collection (see above). If it wishes, a handler can try to prevent a garbage collection by calling `BLOAT` with the `FIX` argument. If the @@ -8138,7 +8143,7 @@ try to cause a garbage collection. ### 21.8.6. "CLOCK" `"CLOCK"`, when enabled, occurs every half second (the ITS -"slow-clock" tick.) It is not available in the Tenex or Tops-20 +"slow-clock" tick). It is not available in the Tenex or Tops-20 versions. It wants handlers which take no arguments. Example: > 1> @@ -8161,9 +8166,9 @@ character. ### 21.8.8. "UNBLOCKED" `"UNBLOCKED"` occurs whenever a `$` (`ESC`) is typed on a terminal if -a program was hanging and waiting for input, or when a TYI call (which -see) is satisfied. A handler takes one argument: the `CHANNEL` via -which the `$` or character is input. +a program was hanging and waiting for input, or when a `TYI` call +(which see) is satisfied. A handler takes one argument: the `CHANNEL` +via which the `$` or character is input. ### 21.8.9. "READ" and "WRITE" @@ -8245,7 +8250,7 @@ process. It is not available in the Tenex and Tops-20 versions. A handler takes one argument: A `FIX` between `0` and `7` inclusive, telling which inferior process is interrupting. -### 21.8.14. "RUNT and "REALT" +### 21.8.14. "RUNT" and "REALT" These are not available in the Tenex and Tops-20 versions. @@ -8269,7 +8274,7 @@ argument, or `#FALSE ()` if `REALTIMER` has not been called. `"MPV"` ("memory protection violation") occurs if Muddle tries to refer to a storage address not in its address space. `"PURE"` occurs if Muddle tries to alter read-only storage. `"ILOPR"` occurs if Muddle -executes and illegal instruction ("operator"). `"PARITY"` occurs if +executes an illegal instruction ("operator"). `"PARITY"` occurs if the CPU detects a parity error in Muddle's address space. All of these require a handler that takes one argument: the address (`TYPE` `WORD`) following the instruction that was being executed at the time. @@ -8287,7 +8292,7 @@ system process instead of to Muddle. In the ITS version, if and when a interrupt goes to the superior operating system process. - If an `IHEADER` is associated but disabled, the error `DANGEROUS-INTERRUPT-NOT-HANDLED` occurs (`FILE-SYSTEM-ERROR` for - \`"IOC"). + `"IOC"`). - If an `IHEADER` is associated and enabled, but the `INT-LEVEL` is too high, the error `ATTEMPT-TO-DEFER-UNDEFERABLE-INTERRUPT` occurs. @@ -8394,9 +8399,9 @@ when space becomes full varies, as discussed below. Most storage used explicitly by Muddle programs is obtained from a pool of free storage managed by a "garbage collector". Storage is -obtained from this pool by the `SUBR`s which construct objects. When a -`SUBR` finds that the pool of available storage is exhausted, it -automatically calls the garbage collector. +obtained from this pool by the `SUBR`s which construct objects. When +such a `SUBR` finds that the pool of available storage is exhausted, +it automatically calls the garbage collector. The garbage collector has two algorithms available to it: the "copying" algorithm, which is used by default, and the "mark-sweep" @@ -8425,7 +8430,7 @@ Only when the total system resources are exhausted will you finally lose. Thus, if you just "forget about" an object, that is, lose all possible -means of referencing it, its storage is automatically reclaimed. +means of referencing it, its storage area is automatically reclaimed. "Object" in this context includes that stack-structured storage space used in `PROCESS`es for functional application. @@ -8550,8 +8555,9 @@ becomes full, Muddle goes through the following procedure: 5. Finally, the "mark-sweep" algorithm sweeps through the storage space, adding unmarked objects to the internal free lists for later re-use. The "copying" algorithm maps the inferior process's - address space into Muddle's own, replacing old garbagey with the - new compact storage, and the inferior process is destroyed. + address space into Muddle's own, replacing old garbagey storage + with the new compact storage, and the inferior process is + destroyed. 22.5 GC ------- @@ -8560,24 +8566,44 @@ becomes full, Muddle goes through the following procedure: causes the garbage collector to run and returns the total number of words of storage reclaimed. All of its arguments are optional: if they -are not supplied, a call to GC simply causes a "copying" garbage +are not supplied, a call to `GC` simply causes a "copying" garbage collection. If *min* is explicitly supplied as an argument, a garbage-collection parameter is changed permanently before the garbage collector runs. *min* is the smallest number of words of "free" (unclaimed, available for use) movable garbage-collected storage the garbage collector will -be satisfied with having after it is done. Initially it is 8192 words. -If the total amount of reclaimed storage is less than *min*, the -garbage collector will ask the operating system for enough storage (in -1024 word blocks) to make it up. N.B.: the system may be incivil -enough not to grant the request; in that case, the garbage collector -will be content with what it has, **unless** that is not enough to -satisfy a **pending** request for storage. Then it will inform you -that it is losing. A large *min* will result in fewer total garbage -collections, but they will take longer since the total quantity of -storage to be dealt with will generally be larger. Smaller *min*s -result in shorter, more frequent garbage collections. +be satisfied with having after it is done each time. Initially it is +8192 words. If the total amount of reclaimed storage is less than +*min*, the garbage collector will ask the operating system for enough +storage (in 1024-word blocks) to make it up. N.B.: the system may be +incivil enough not to grant the request; in that case, the garbage +collector will be content with what it has, **unless** that is not +enough to satisfy a **pending** request for storage. Then it will +inform you that it is losing. A large *min* will result in fewer total +garbage collections, but they will take longer since the total +quantity of storage to be dealt with will generally be larger. Smaller +*min*s result in shorter, more frequent garbage collections. + +*exh?* tells whether or not this garbage collection should be +"exhaustive". It is optional, a `FALSE` by default. The difference +between normal and exhaustive "copying" garbage collections is whether +certain kinds of storage that require complicated treatment (for +example, associations) are reclaimed. An exhaustive garbage collection +occurs every eighth time that the "copying" algorithm is used, or when +`GC` is called with this argument true, or when a normal garbage +collection cannot satisfy the storage request. + +*ms-freq* gives the number of times the "mark-sweep" algorithm should +be used hereafter for every time the normal "copying" algorithm is +used. Giving `0` for *ms-freq* means never to use the "mark-sweep" +algorithm, and giving ` FIX>` means (effectively) always +to use it. The "mark-sweep" algorithm uses considerably less processor +time than the "copying" algorithm, but it never shrinks the +free-storage pool, and in fact the pool can become fragmented. The +"mark-sweep" algorithm could be useful in a program system (such as +the compiler) where the size of the pool rarely changes, but objects +are created and thrown away continuously. 22.6. BLOAT ----------- @@ -8618,8 +8644,8 @@ by default), and indicate the following: `READ`ing large `STRING`s, and calling routines within the interpreter and compiled programs) -Arguments on the second line are also `FIX` and optional, but they set -garbage-collection parameters permanently, as follows: +Arguments on the second line above are also `FIX` and optional, but +they set garbage-collection parameters permanently, as follows: - *min*: as for `GC` - *plcl*: number of slots for `LVAL`s added when the space for @@ -8688,7 +8714,7 @@ about certain areas of storage. In detail: 22.8. GC-MON ------------ - + ("garbage-collector monitor") determines whether or not the interpreter will hereafter print information on the terminal when a @@ -8714,7 +8740,7 @@ of `GIN` and `GOUT`. Two `SUBR`s, described next, use only part of the garbage-collector algorithm, in order to find all pointers to an object. `GC-DUMP` and `GC-READ`, as their names imply, also use part in order to translate -between Muddle objects and binary representation thereof. +between Muddle objects and binary representations thereof. ### 22.9.1. SUBSTITUTE @@ -8729,7 +8755,7 @@ the few legitimate uses for it is to substitute the "right" `ATOM` for the "wrong" one, after `OBLIST`s have been in the wrong state. This is more or less the way `ATOM`s are impurified. It is also useful for unlinking `RSUBR`s. `SUBSTITUTE` returns *old* as a favor: unless you -hang onto *old* at that point, it will be garbage-collected. +hang onto *old* at that point, it will be garbage. 22.9.2 PURIFY ------------- @@ -8810,10 +8836,10 @@ control passes to the superior process. ("value return") seldom returns. It passes control back up the process tree to the superior of Muddle, passing its argument as a message to that superior. If it does return, the value is `#FALSE ()`. If the -argument is a `STRING`, it is passed to the superior as a command to +argument is a `STRING`, it is passed to the superior as commands to be executed, via `.VALUE` in the ITS version and `RSCAN` in the Tops-20 version. If the argument is a `FIX`, it is passed to the -superior as the "effective address" of a `.BREAK 16`, instruction in +superior as the "effective address" of a `.BREAK 16,` instruction in the ITS version and ignored in other versions. 23.4. Inter-process Communication