Mostly work on generating better documentation.

This commit is contained in:
Simon Brooke 2023-04-01 14:28:50 +01:00
parent 4c2380ca26
commit 41cecdc522
34 changed files with 1531 additions and 794 deletions

3
.gitignore vendored
View file

@ -1,6 +1,7 @@
/target /target
/classes /classes
/checkouts /checkouts
resources/scratch/
profiles.clj profiles.clj
pom.xml pom.xml
pom.xml.asc pom.xml.asc
@ -18,3 +19,5 @@ pom.xml.asc
resources/scratch.lsp resources/scratch.lsp
Sysout*.lsp Sysout*.lsp
*.pdf *.pdf
src/beowulf/scratch.clj

144
README.md
View file

@ -43,63 +43,93 @@ To end a session, type `STOP` at the command prompt.
The following functions and symbols are implemented: The following functions and symbols are implemented:
| Symbol | Type | Signature | Documentation | | Function | Type | Signature | Implementation | Documentation |
|--------|------|-----------|---------------| |--------------|----------------|------------------|----------------|----------------------|
| NIL | Lisp variable | | ? | | NIL | Lisp variable | | | ? |
| T | Lisp variable | | ? | | T | Lisp variable | | | ? |
| F | Lisp variable | | ? | | F | Lisp variable | | | ? |
| ADD1 | Host function | (ADD1 X) | ? | | ADD1 | Host function | (ADD1 X) | | ? |
| AND | Host function | (AND & ARGS) | `T` if and only if none of my `args` evaluate to either `F` or `NIL`, else `F`. In `beowulf.host` principally because I don't yet feel confident to define varargs functions in Lisp. | | AND | Host function | (AND & ARGS) | PREDICATE | `T` if and only if none of my `args` evaluate to either `F` or `NIL`, else `F`. In `beowulf.host` principally because I don't yet feel confident to define varargs functions in Lisp. |
| APPEND | Lisp function | (APPEND X Y) | ? | | APPEND | Lisp function | (APPEND X Y) | LAMBDA-fn | see manual pages <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=19'>11</a>, <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=69'>61</a> |
| APPLY | Host function | (APPLY FUNCTION ARGS ENVIRONMENT DEPTH) | Apply this `function` to these `arguments` in this `environment` and return the result. For bootstrapping, at least, a version of APPLY written in Clojure. All args are assumed to be symbols or `beowulf.cons-cell/ConsCell` objects. See page 13 of the Lisp 1.5 Programmers Manual. | | APPLY | Host function | (APPLY FUNCTION ARGS ENVIRONMENT DEPTH) | | Apply this `function` to these `arguments` in this `environment` and return the result. For bootstrapping, at least, a version of APPLY written in Clojure. All args are assumed to be symbols or `beowulf.cons-cell/ConsCell` objects. See page 13 of the Lisp 1.5 Programmers Manual. |
| ATOM | Host function | (ATOM X) | Returns `T` if and only if the argument `x` is bound to an atom; else `F`. It is not clear to me from the documentation whether `(ATOM 7)` should return `T` or `F`. I'm going to assume `T`. | | ATOM | Host function | (ATOM X) | PREDICATE | Returns `T` if and only if the argument `x` is bound to an atom; else `F`. It is not clear to me from the documentation whether `(ATOM 7)` should return `T` or `F`. I'm going to assume `T`. |
| CAR | Host function | (CAR X) | Return the item indicated by the first pointer of a pair. NIL is treated specially: the CAR of NIL is NIL. | | CAR | Host function | (CAR X) | | Return the item indicated by the first pointer of a pair. NIL is treated specially: the CAR of NIL is NIL. |
| CDR | Host function | (CDR X) | Return the item indicated by the second pointer of a pair. NIL is treated specially: the CDR of NIL is NIL. | | CAAAAR | Lisp function | (CAAAAR X) | LAMBDA-fn | ? |
| CONS | Host function | (CONS CAR CDR) | Construct a new instance of cons cell with this `car` and `cdr`. | | CAAADR | Lisp function | (CAAADR X) | LAMBDA-fn | ? |
| COPY | Lisp function | (COPY X) | ? | | CAAAR | Lisp function | (CAAAR X) | LAMBDA-fn | ? |
| DEFINE | Host function | (DEFINE ARGS) | Bootstrap-only version of `DEFINE` which, post boostrap, can be overwritten in LISP. The single argument to `DEFINE` should be an assoc list which should be nconc'ed onto the front of the oblist. Broadly, (SETQ OBLIST (NCONC ARG1 OBLIST)) | | CAADAR | Lisp function | (CAADAR X) | LAMBDA-fn | ? |
| DIFFERENCE | Host function | (DIFFERENCE X Y) | ? | | CAADDR | Lisp function | (CAADDR X) | LAMBDA-fn | ? |
| DIVIDE | Lisp function | (DIVIDE X Y) | ? | | CAADR | Lisp function | (CAADR X) | LAMBDA-fn | ? |
| ERROR | Host function | (ERROR & ARGS) | Throw an error | | CAAR | Lisp function | (CAAR X) | LAMBDA-fn | ? |
| EQ | Host function | (EQ X Y) | Returns `T` if and only if both `x` and `y` are bound to the same atom, else `NIL`. | | CADAAR | Lisp function | (CADAAR X) | LAMBDA-fn | ? |
| EQUAL | Host function | (EQUAL X Y) | This is a predicate that is true if its two arguments are identical S-expressions, and false if they are different. (The elementary predicate `EQ` is defined only for atomic arguments.) The definition of `EQUAL` is an example of a conditional expression inside a conditional expression. NOTE: returns `F` on failure, not `NIL` | | CADADR | Lisp function | (CADADR X) | LAMBDA-fn | ? |
| EVAL | Host function | (EVAL EXPR); (EVAL EXPR ENV DEPTH) | Evaluate this `expr` and return the result. If `environment` is not passed, it defaults to the current value of the global object list. The `depth` argument is part of the tracing system and should not be set by user code. All args are assumed to be numbers, symbols or `beowulf.cons-cell/ConsCell` objects. | | CADAR | Lisp function | (CADAR X) | LAMBDA-fn | ? |
| FACTORIAL | Lisp function | (FACTORIAL N) | ? | | CADDAR | Lisp function | (CADDAR X) | LAMBDA-fn | ? |
| FIXP | Host function | (FIXP X) | ? | | CADDDR | Lisp function | (CADDDR X) | LAMBDA-fn | ? |
| GENSYM | Host function | (GENSYM ) | Generate a unique symbol. | | CADDR | Lisp function | (CADDR X) | LAMBDA-fn | ? |
| GET | Lisp function | (GET X Y) | ? | | CADR | Lisp function | (CADR X) | LAMBDA-fn | ? |
| GREATERP | Host function | (GREATERP X Y) | ? | | CDAAAR | Lisp function | (CDAAAR X) | LAMBDA-fn | ? |
| INTEROP | Host function | (INTEROP FN-SYMBOL ARGS) | Clojure (or other host environment) interoperation API. `fn-symbol` is expected to be either 1. a symbol bound in the host environment to a function; or 2. a sequence (list) of symbols forming a qualified path name bound to a function. Lower case characters cannot normally be represented in Lisp 1.5, so both the upper case and lower case variants of `fn-symbol` will be tried. If the function you're looking for has a mixed case name, that is not currently accessible. `args` is expected to be a Lisp 1.5 list of arguments to be passed to that function. Return value must be something acceptable to Lisp 1.5, so either a symbol, a number, or a Lisp 1.5 list. If `fn-symbol` is not found (even when cast to lower case), or is not a function, or the value returned cannot be represented in Lisp 1.5, an exception is thrown with `:cause` bound to `:interop` and `:detail` set to a value representing the actual problem. | | CDAADR | Lisp function | (CDAADR X) | LAMBDA-fn | ? |
| INTERSECTION | Lisp function | (INTERSECTION X Y) | ? | | CDAAR | Lisp function | (CDAAR X) | LAMBDA-fn | ? |
| LENGTH | Lisp function | (LENGTH L) | ? | | CDADAR | Lisp function | (CDADAR X) | LAMBDA-fn | ? |
| LESSP | Host function | (LESSP X Y) | ? | | CDADDR | Lisp function | (CDADDR X) | LAMBDA-fn | ? |
| MEMBER | Lisp function | (MEMBER A X) | ? | | CDADR | Lisp function | (CDADR X) | LAMBDA-fn | ? |
| MINUSP | Lisp function | (MINUSP X) | ? | | CDAR | Lisp function | (CDAR X) | LAMBDA-fn | ? |
| NOT | Lisp function | (NOT X) | ? | | CDDAAR | Lisp function | (CDDAAR X) | LAMBDA-fn | ? |
| NULL | Lisp function | (NULL X) | ? | | CDDADR | Lisp function | (CDDADR X) | LAMBDA-fn | ? |
| NUMBERP | Host function | (NUMBERP X) | ? | | CDDAR | Lisp function | (CDDAR X) | LAMBDA-fn | ? |
| OBLIST | Host function | (OBLIST ) | Return a list of the symbols currently bound on the object list. **NOTE THAT** in the Lisp 1.5 manual, footnote at the bottom of page 69, it implies that an argument can be passed but I'm not sure of the semantics of this. | | CDDDAR | Lisp function | (CDDDAR X) | LAMBDA-fn | ? |
| ONEP | Lisp function | (ONEP X) | ? | | CDDDDR | Lisp function | (CDDDDR X) | LAMBDA-fn | ? |
| PAIR | Lisp function | (PAIR X Y) | ? | | CDDDR | Lisp function | (CDDDR X) | LAMBDA-fn | ? |
| PLUS | Host function | (PLUS & ARGS) | ? | | CDDR | Lisp function | (CDDR X) | LAMBDA-fn | ? |
| PRETTY | Lisp variable | | ? | | CDR | Host function | (CDR X) | | Return the item indicated by the second pointer of a pair. NIL is treated specially: the CDR of NIL is NIL. |
| PRINT | Lisp variable | | ? | | CONS | Host function | (CONS CAR CDR) | | Construct a new instance of cons cell with this `car` and `cdr`. |
| PROP | Lisp function | (PROP X Y U) | ? | | COPY | Lisp function | (COPY X) | LAMBDA-fn | see manual pages <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=70'>62</a> |
| QUOTIENT | Host function | (QUOTIENT X Y) | I'm not certain from the documentation whether Lisp 1.5 `QUOTIENT` returned the integer part of the quotient, or a realnum representing the whole quotient. I am for now implementing the latter. | | DEFINE | Host function | (DEFINE ARGS) | PSEUDO-FUNCTION | Bootstrap-only version of `DEFINE` which, post boostrap, can be overwritten in LISP. The single argument to `DEFINE` should be an assoc list which should be nconc'ed onto the front of the oblist. Broadly, (SETQ OBLIST (NCONC ARG1 OBLIST)) |
| READ | Host function | (READ ); (READ INPUT) | An implementation of a Lisp reader sufficient for bootstrapping; not necessarily the final Lisp reader. `input` should be either a string representation of a LISP expression, or else an input stream. A single form will be read. | | DIFFERENCE | Host function | (DIFFERENCE X Y) | | ? |
| REMAINDER | Host function | (REMAINDER X Y) | ? | | DIVIDE | Lisp function | (DIVIDE X Y) | LAMBDA-fn | see manual pages <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=34'>26</a>, <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=72'>64</a> |
| REPEAT | Lisp function | (REPEAT N X) | ? | | ERROR | Host function | (ERROR & ARGS) | PSEUDO-FUNCTION | Throw an error |
| RPLACA | Host function | (RPLACA CELL VALUE) | Replace the CAR pointer of this `cell` with this `value`. Dangerous, should really not exist, but does in Lisp 1.5 (and was important for some performance hacks in early Lisps) | | EQ | Host function | (EQ X Y) | PREDICATE | Returns `T` if and only if both `x` and `y` are bound to the same atom, else `NIL`. |
| RPLACD | Host function | (RPLACD CELL VALUE) | Replace the CDR pointer of this `cell` with this `value`. Dangerous, should really not exist, but does in Lisp 1.5 (and was important for some performance hacks in early Lisps) | | EQUAL | Host function | (EQUAL X Y) | PREDICATE | This is a predicate that is true if its two arguments are identical S-expressions, and false if they are different. (The elementary predicate `EQ` is defined only for atomic arguments.) The definition of `EQUAL` is an example of a conditional expression inside a conditional expression. NOTE: returns `F` on failure, not `NIL` |
| SET | Host function | (SET SYMBOL VAL) | Implementation of SET in Clojure. Add to the `oblist` a binding of the value of `var` to the value of `val`. NOTE WELL: this is not SETQ! | | EVAL | Host function | (EVAL EXPR); (EVAL EXPR ENV DEPTH) | | Evaluate this `expr` and return the result. If `environment` is not passed, it defaults to the current value of the global object list. The `depth` argument is part of the tracing system and should not be set by user code. All args are assumed to be numbers, symbols or `beowulf.cons-cell/ConsCell` objects. |
| SUB1 | Lisp function | (SUB1 N) | ? | | FACTORIAL | Lisp function | (FACTORIAL N) | LAMBDA-fn | ? |
| SYSIN | Host function | (SYSIN ); (SYSIN FILENAME) | Read the contents of the file at this `filename` into the object list. If the file is not a valid Beowulf sysout file, this will probably corrupt the system, you have been warned. File paths will be considered relative to the filepath set when starting Lisp. It is intended that sysout files can be read both from resources within the jar file, and from the file system. If a named file exists in both the file system and the resources, the file system will be preferred. **NOTE THAT** if the provided `filename` does not end with `.lsp` (which, if you're writing it from the Lisp REPL, it won't), the extension `.lsp` will be appended. | | FIXP | Host function | (FIXP X) | PREDICATE | ? |
| SYSOUT | Host function | (SYSOUT ); (SYSOUT FILEPATH) | Dump the current content of the object list to file. If no `filepath` is specified, a file name will be constructed of the symbol `Sysout` and the current date. File paths will be considered relative to the filepath set when starting Lisp. | | GENSYM | Host function | (GENSYM ) | | Generate a unique symbol. |
| TERPRI | Lisp variable | | ? | | GET | Lisp function | (GET X Y) | LAMBDA-fn | see manual pages <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=49'>41</a>, <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=67'>59</a> |
| TIMES | Host function | (TIMES & ARGS) | ? | | GREATERP | Host function | (GREATERP X Y) | PREDICATE | ? |
| TRACE | Host function | (TRACE S) | Add this symbol `s` to the set of symbols currently being traced. If `s` is not a symbol, does nothing. | | INTEROP | Host function | (INTEROP FN-SYMBOL ARGS) | (INTEROP) | Clojure (or other host environment) interoperation API. `fn-symbol` is expected to be either 1. a symbol bound in the host environment to a function; or 2. a sequence (list) of symbols forming a qualified path name bound to a function. Lower case characters cannot normally be represented in Lisp 1.5, so both the upper case and lower case variants of `fn-symbol` will be tried. If the function you're looking for has a mixed case name, that is not currently accessible. `args` is expected to be a Lisp 1.5 list of arguments to be passed to that function. Return value must be something acceptable to Lisp 1.5, so either a symbol, a number, or a Lisp 1.5 list. If `fn-symbol` is not found (even when cast to lower case), or is not a function, or the value returned cannot be represented in Lisp 1.5, an exception is thrown with `:cause` bound to `:interop` and `:detail` set to a value representing the actual problem. |
| UNTRACE | Host function | (UNTRACE S) | ? | | INTERSECTION | Lisp function | (INTERSECTION X Y) | LAMBDA-fn | ? |
| ZEROP | Lisp function | (ZEROP N) | ? | | LENGTH | Lisp function | (LENGTH L) | LAMBDA-fn | see manual pages <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=70'>62</a> |
| LESSP | Host function | (LESSP X Y) | PREDICATE | ? |
| MEMBER | Lisp function | (MEMBER A X) | LAMBDA-fn | see manual pages <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=19'>11</a>, <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=70'>62</a> |
| MINUSP | Lisp function | (MINUSP X) | LAMBDA-fn | see manual pages <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=34'>26</a>, <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=72'>64</a> |
| NOT | Lisp function | (NOT X) | LAMBDA-fn | see manual pages <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=29'>21</a>, <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=31'>23</a>, <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=66'>58</a> |
| NULL | Lisp function | (NULL X) | LAMBDA-fn | see manual pages <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=19'>11</a>, <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=65'>57</a> |
| NUMBERP | Host function | (NUMBERP X) | PREDICATE | ? |
| OBLIST | Host function | (OBLIST ) | | Return a list of the symbols currently bound on the object list. **NOTE THAT** in the Lisp 1.5 manual, footnote at the bottom of page 69, it implies that an argument can be passed but I'm not sure of the semantics of this. |
| ONEP | Lisp function | (ONEP X) | LAMBDA-fn | see manual pages <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=34'>26</a>, <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=72'>64</a> |
| PAIR | Lisp function | (PAIR X Y) | LAMBDA-fn | see manual pages <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=68'>60</a> |
| PLUS | Host function | (PLUS & ARGS) | | ? |
| PRETTY | Lisp variable | | (PRETTY) | ? |
| PRINT | Lisp variable | | PSEUDO-FUNCTION | ? |
| PROP | Lisp function | (PROP X Y U) | LAMBDA-fn | see manual pages <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=67'>59</a> |
| QUOTIENT | Host function | (QUOTIENT X Y) | | I'm not certain from the documentation whether Lisp 1.5 `QUOTIENT` returned the integer part of the quotient, or a realnum representing the whole quotient. I am for now implementing the latter. |
| RANGE | Lisp variable | ? | (RANGE (LAMBDA (N M) (COND ((LESSP M N) (QUOTE NIL)) ((QUOTE T) (CONS N (RANGE (ADD1 N) M)))))) | ? |
| READ | Host function | (READ ); (READ INPUT) | PSEUDO-FUNCTION | An implementation of a Lisp reader sufficient for bootstrapping; not necessarily the final Lisp reader. `input` should be either a string representation of a LISP expression, or else an input stream. A single form will be read. |
| REMAINDER | Host function | (REMAINDER X Y) | | ? |
| REPEAT | Lisp function | (REPEAT N X) | LAMBDA-fn | ? |
| RPLACA | Host function | (RPLACA CELL VALUE) | PSEUDO-FUNCTION | Replace the CAR pointer of this `cell` with this `value`. Dangerous, should really not exist, but does in Lisp 1.5 (and was important for some performance hacks in early Lisps) |
| RPLACD | Host function | (RPLACD CELL VALUE) | PSEUDO-FUNCTION | Replace the CDR pointer of this `cell` with this `value`. Dangerous, should really not exist, but does in Lisp 1.5 (and was important for some performance hacks in early Lisps) |
| SET | Host function | (SET SYMBOL VAL) | PSEUDO-FUNCTION | Implementation of SET in Clojure. Add to the `oblist` a binding of the value of `var` to the value of `val`. NOTE WELL: this is not SETQ! |
| SUB1 | Lisp function | (SUB1 N) | LAMBDA-fn | see manual pages <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=34'>26</a>, <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=72'>64</a> |
| SYSIN | Host function | (SYSIN ); (SYSIN FILENAME) | (SYSIN) | Read the contents of the file at this `filename` into the object list. If the file is not a valid Beowulf sysout file, this will probably corrupt the system, you have been warned. File paths will be considered relative to the filepath set when starting Lisp. It is intended that sysout files can be read both from resources within the jar file, and from the file system. If a named file exists in both the file system and the resources, the file system will be preferred. **NOTE THAT** if the provided `filename` does not end with `.lsp` (which, if you're writing it from the Lisp REPL, it won't), the extension `.lsp` will be appended. |
| SYSOUT | Host function | (SYSOUT ); (SYSOUT FILEPATH) | (SYSOUT) | Dump the current content of the object list to file. If no `filepath` is specified, a file name will be constructed of the symbol `Sysout` and the current date. File paths will be considered relative to the filepath set when starting Lisp. |
| TERPRI | Lisp variable | | PSEUDO-FUNCTION | ? |
| TIMES | Host function | (TIMES & ARGS) | | ? |
| TRACE | Host function | (TRACE S) | PSEUDO-FUNCTION | Add this symbol `s` to the set of symbols currently being traced. If `s` is not a symbol, does nothing. |
| UNTRACE | Host function | (UNTRACE S) | PSEUDO-FUNCTION | ? |
| ZEROP | Lisp function | (ZEROP N) | LAMBDA-fn | see manual pages <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=34'>26</a>, <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=72'>64</a> |
Functions described as 'Lisp function' above are defined in the default Functions described as 'Lisp function' above are defined in the default
sysout file, `resources/lisp1.5.lsp`, which will be loaded by default unless sysout file, `resources/lisp1.5.lsp`, which will be loaded by default unless

View file

@ -331,20 +331,28 @@ It Is important to become familiar with the results of elementary functions on
S-expressions written in list notation. These can always be determined by translating S-expressions written in list notation. These can always be determined by translating
into dot notation. into dot notation.
#### Examples - lisp notation 2 #### Examples - list notation 2
car[(^ B c)]=A
cdr[(~ I3 c)]=(B C) ```
cons[^; (B c)]=(A B C) car[(A B C)] = A
car[((^ B) c)]*(A B) cdr[(A B C)] = (B C)
c~~[(A)]=NIL cons[A; (B C)] = (A B C)
car[cdr[(~ B C)]]=B car[((A B) C)] = (A B)
It is convenient to abbreviate multiple car's and,=s. This is done by forming cdr[(A)] = NIL
function names that begin with c, end with r, qnd have several a's and dl s between car[cdr[(A B C)]] = B
```
It is convenient to abbreviate multiple `car`s and `cdr`s. This is done by forming
function names that begin with `c`, end with `r`, and have several `a`s and `d`s between
them. them.
Examples
cadr[(~ B ~)]scar[cdrl(A B C)I=B ### Examples - composed accessor functions
caddr[(A B C )I=c
cadadr[(A (B C) D)]=c ```
cadr[(A B C)] = car[cdr[(A B C)]] = B
caddr[(A B C )] = C
cadadr[(A (B C) D)] = C
```
The last a or d in the name actually signifies the first operation in order to be The last a or d in the name actually signifies the first operation in order to be
performed, since it is nearest to the argument. performed, since it is nearest to the argument.
@ -4842,576 +4850,156 @@ SW6 on to return to overlord after accumulator printout resulting from
error *I? 5*. SW6 off for error printout. error *I? 5*. SW6 off for error printout.
``` ```
``` ## Index
INDEX TO FUNCTION DESCRIPTIONS
```
Function | Function | Call type | Implementation | Pages |
|--------------|------------|------------------|------------------------------|
``` | ADD1 | SUBR | | [26](#page26), [64](#page64) |
ADD 1 | ADVANCE | SUBR | PSEUDO-FUNCTION | [88](#page88) |
ADVANCE | AND | FSUBR | PREDICATE | [21](#page21), [58](#page58) |
AND | APPEND | SUBR | | [11](#page11), [61](#page61) |
APPEND | APPLY | SUBR | | [70](#page70) |
APPLY | ARRAY | SUBR | PSEUDO-FUNCTION | [27](#page27), [64](#page64) |
ARRAY | ATOM | SUBR | PREDICATE | [3](#page3), [57](#page57) |
ATOM | ATTRIB | SUBR | PSEUDO-FUNCTION | [59](#page59) |
ATTRIB | BLANK | APVAL | | [69](#page69), [85](#page85) |
BLANK | CAR | SUBR | | [2](#page2), [56](#page56) |
CAR | CDR | SUBR | | [3](#page3), [56](#page56) |
CDR | CHARCOUNT | APVAL | | [69](#page69), [87](#page87) |
CHARCOUNT | CLEARBUFF | SUBR | PSEUDO-FUNCTION | [86](#page86) |
CLEARBUFF | COMMA | APVAL | | [69](#page69), [85](#page85) |
COMMA | COMMON | SUBR | PSEUDO-FUNCTION | [64](#page64), [78](#page78) |
COMMON | COMPILE | SUBR | PSEUDO-FUNCTION | [64](#page64), [76](#page76) |
COMPILE | CONC | FEXPR | | [61](#page61) |
CONC | COND | FSUBR | | [18](#page18) |
COND | CONS | SUBR | | [2](#page2), [56](#page56) |
CONS | COPY | SUBR | | [62](#page62) |
COPY | COUNT | SUBR | PSEUDO-FUNCTION | [34](#page34), [66](#page66) |
COUNT | CP1 | SUBR | | [66](#page66) |
CP1 | CSET | EXPR | PSEUDO-FUNCTION | [17](#page17), [59](#page59) |
CSET | CSETQ | FEXPR | PSEUDO-FUNCTION | [59](#page59) |
CSETQ | CURCHAR | APVAL | | [69](#page69), [87](#page87) |
CURCHAR | DASH | SUBR | PREDICATE APVAL | [85](#page85), [87](#page87) |
DASH | DEFINE | EXPR | PSEUDO-FUNCTION | [15](#page15), [18](#page18), [58](#page58) |
DEFINE | DEFLIST | EXPR | PSEUDO-FUNCTION | [41](#page41), [58](#page58) |
DEFLIST | DIFFERENCE | SUBR | | [26](#page26), [64](#page64) |
DIFFERENCE | DIGIT | SUBR | PREDICATE | [87](#page87) |
DIGIT | DIVIDE | SUBR | | [26](#page26), [64](#page64) |
DIVIDE | DOLLAR | APVAL | | [69](#page69), [85](#page85) |
DOLLAR | DUMP | SUBR | PSEUDO-FUNCTION | [67](#page67) |
DUMP | EFFACE | SUBR | PSEUDO-FUNCTION | [63](#page63) |
EFFACE | ENDREAD | SUBR | PSEUDO-FUNCTION | [8 8](#page8 8) |
ENDREAD | EOF | APVAL | | [69](#page69), [88](#page88) |
EOF | EOR | APVAL | | [69](#page69), [88](#page88) |
EOR | EQ | SUBR | PREDICATE | [3](#page3), [23](#page23), [57](#page57) |
EQ | EQSIGN | APVAL | | [69](#page69), [85](#page85) |
EQSIGN | EQUAL | SUBR | PREDICATE | [11](#page11), [26](#page26), [57](#page57) |
EQUAL | ERROR | SUBR | PSEUDO-FUNCTION | [32](#page32), [66](#page66) |
ERROR | ERROR1 | SUBR | PSEUDO-FUNCTION | [88](#page88) |
ERROR1 | ERRORSET | SUBR | PSEUDO-FUNCTION | [35](#page35), [66](#page66) |
ERRORSET | EVAL | SUBR | | [71](#page71) |
EVAL | EVLIS | SUBR | | [71](#page71) |
EVLIS | EXCISE | SUBR | PSEUDO-FUNCTION | [67](#page67), [77](#page77) |
EXCISE | EXPT | SUBR | | [26](#page26), [64](#page64) |
EXPT | F | APVAL | | [22](#page22), [69](#page69) |
F | FIXP | SUBR | PREDICATE | [26](#page26), [64](#page64) |
FIXP | FLAG | EXPR | PSEUDO-FUNCTION | [41](#page41), [60](#page60) |
FLAG | FLOATP | SUBR | PREDICATE | [26](#page26), [64](#page64) |
FLOATP | FUNCTION | FSUBR | | [21](#page21), [71](#page71) |
FUNCTION | GENSYM | SUBR | | [66](#page66) |
GENSYM | GET | SUBR | | [41](#page41), [59](#page59) |
GET | GO | FSUBR | PSEUDO-FUNCTION | [30](#page30), [72](#page72) |
GO | GREATERP | SUBR | PREDICATE | [26](#page26), [64](#page64) |
GREATERP | INTERN | SUBR | PSEUDO-FUNCTION | [67](#page67), [87](#page87) |
INTERN | LABEL | FSUBR | | [8](#page8), [18](#page18), [70](#page70) |
``` | LAP | SUBR | PSEUDO-FUNCTION | [65](#page65), [73](#page73) |
| LEFTSHIFT | SUBR | | [27](#page27), [64](#page64) |
``` | LENGTH | SUBR | | [62](#page62) |
SUBR | LESSP | SUBR | PREDICATE | [26](#page26), [64](#page64) |
SUBR | LIST | FSUBR | | [57](#page57) |
FSUBR | LITER | SUBR | PREDICATE | [87](#page87) |
SUBR | LOAD | SUBR | PSEUDO-FUNCTION | [67](#page67) |
SUBR | LOGAND | FSUBR | | [27](#page27), [64](#page64) |
SUBR | LOGOR | FSUBR | | [26](#page26), [64](#page64) |
SUBR | LOGXOR | FSUBR | | [27](#page27), [64](#page64) |
SUBR | LPAR | APVAL | | [69](#page69), [85](#page85) |
APVAL | MAP | SUBR | FUNCTIONAL | [63](#page63) |
SUBR | MAPCON | SUBR | FUNCTIONAL PSEUDO- FUNCTION | [63](#page63) |
SUBR | MAPLIST | SUBR | FUNCTIONAL | [20](#page20), [21](#page21), [63](#page63) |
APVAL | MAX | FSUBR | | [26](#page26), [64](#page64) |
SUBR | MEMBER | SUBR | PREDICATE | [11](#page11), [62](#page62) |
APVAL | MIN | FSUBR | | [26](#page26), [64](#page64) |
SUBR | MINUS | SUBR | | [26](#page26), [63](#page63) |
SUBR | MINUSP | SUBR | PREDICATE | [26](#page26), [64](#page64) |
FEXPR | MKNAM | SUBR | | [86](#page86) |
FSUBR | NCONC | SUBR | PSEUDO-FUNCTION | [62](#page62) |
SUBR | NIL | APVAL | | [22](#page22), [69](#page69) |
SUBR | NOT | SUBR | PREDICATE | [21](#page21), [23](#page23), [58](#page58) |
SUBR | NULL | SUBR | PREDICATE | [11](#page11), [57](#page57) |
SUBR | NUMBERP | SUBR | PREDICATE | [26](#page26), [64](#page64) |
EXPR | NUMOB | SUBR | PSEUDO-FUNCTION | [86](#page86) |
FEXPR | OBLIST | APVAL | | [69](#page69) |
APVAL | ONEP | SUBR | PREDICATE | [26](#page26), [64](#page64) |
SUBR | OPCHAR | SUBR | PREDICATE | [87](#page87) |
EXPR | OPDEFINE | EXPR | PSEUDO-FUNCTION | [65](#page65), [75](#page75) |
EXPR | OR | FSUBR | PREDICATE | [21](#page21), [58](#page58) |
SUBR | PACK | SUBR | PSEUDO-FUNCTION | [86](#page86) |
SUBR | PAIR | SUBR | | [60](#page60) |
SUBR | PAUSE | SUBR | PSEUDO-FUNCTION | [67](#page67) |
APVAL | PERIOD | APVAL | | [69](#page69), [85](#page85) |
SUBR | PLB | SUBR | PSEUDO- FUNCTION | [67](#page67) |
SUBR | PLUS | FSUBR | | [25](#page25), [63](#page63) |
SUBR | PLUSS | APVAL | | [69](#page69), [85](#page85) |
APVAL | PRIN1 | SUBR | PSEUDO-FUNCTION | [65](#page65), [84](#page84) |
APVAL | PRINT | SUBR | PSEUDO-FUNCTION | [65](#page65), [84](#page84) |
SUBR | PRINTPROP | EXPR | PSEUDO-FUNCTION LIBRARY | [68](#page68) |
APVAL | PROG | FSUBR | | [29](#page29), [71](#page71) |
SUBR | PROG2 | SUBR | | [42](#page42), [66](#page66) |
SUBR | PROP | SUBR | FUNCTIONAL | [59](#page59) |
SUBR | PUNCH | SUBR | PSEUDO-FUNCTION | [65](#page65), [84](#page84) |
SUBR | PUNCHDEF | EXPR | PSEUDO-FUNCTION LIBRARY | [68](#page68) |
SUBR | PUNCHLAP | EXPR | PSEUDO-FUNCTION LIBRARY | [68](#page68), [76](#page76) |
SUBR | QUOTE | FSUBR | | [10](#page10), [22](#page22), [71](#page71) |
SUBR | QUOTIENT | SUBR | | [26](#page26), [64](#page64) |
SUBR | READ | SUBR | PSEUDO-FUNCTION | [5](#page5), [84](#page84) |
APVAL | READLAP | SUBR | PSEUDO-FUNCTION | [65](#page65), [76](#page76) |
SUBR | RECIP | SUBR | | [26](#page26), [64](#page64) |
EXPR | RECLAIM | SUBR | PSEUDO-FUNCTION | [67](#page67) |
SUBR | REMAINDER | SUBR | | [26](#page26), [64](#page64) |
FSUBR | REMFLAG | SUBR | PSEUDO-FUNCTION | [41](#page41), [60](#page60) |
SUBR | REMOB | SUBR | PSEUDO-FUNCTION | [67](#page67) |
SUBR | REMPROP | SUBR | PSEUDO-FUNCTION | [41](#page41), [59](#page59) |
FSUBR | RETURN | SUBR | PSEUDO-FUNCTION | [30](#page30), [72](#page72) |
SUBR | REVERSE | SUBR | | [6 2](#page6 2) |
SUBR | RPAR | APVAL | | [69](#page69), [85](#page85) |
``` | RPLACA | SUBR | PSEUDO-FUNCTION | [41](#page41), [58](#page58) |
| RPLACD | SUBR | PSEUDO-FUNCTION | [41](#page41), [58](#page58) |
``` | SASSOC | SUBR | FUNCTIONAL | [60](#page60) |
PSEUDO-FUNCTION | SEARCH | SUBR | FUNCTIONAL | [63](#page63) |
PREDICATE | SELECT | FEXPR | | [66](#page66) |
``` | SET | SUBR | PSEUDO-FUNCTION | [30](#page30), [71](#page71) |
| SETQ | FSUBR | PSEUDO-FUNCTION | [30](#page30), [71](#page71) |
``` | SLASH | APVAL | | [69](#page69), [85](#page85) |
PSEUDO-FUNCTION | SPEAK | SUBR | PSEUDO-FUNCTION | [34](#page34), [66](#page66) |
PREDICATE | SPECIAL | SUBR | PSEUDO-FUNCTION | [64](#page64), [78](#page78) |
PSEUDO-FUNCTION | STAR | APVAL | | [69](#page69), [85](#page85) |
``` | STARTREAD | SUBR | PSEUDO-FUNCTION | [87](#page87) |
| SUB1 | SUBR | | [26](#page26), [64](#page64) |
``` | SUBLIS | SUBR | | [12](#page12), [61](#page61) |
PSEUDO-FUNCTION | SUBST | SUBR | | [11](#page11), [61](#page61) |
PSEUDO-FUNCTION | T | APVAL | | [22](#page22), [69](#page69) |
PSEUDO-FUNCTION | TEMPUS-FUGIT | SUBR | PSEUDO-FUNCTION | [67](#page67) |
``` | TERPRI | SUBR | PSEUDO-FUNCTION | [65](#page65), [84](#page84) |
| TIMES | FSUBR | | [26](#page26), [64](#page64) |
``` | TRACE | EXPR | PSEUDO-FUNCTION | [32](#page32), [66](#page66), [79](#page79) |
PSEUDO-FUNCTION | TRACESET | EXPR | PSEUDO-FUNCTION LIBRARY | [68](#page68) |
PSEUDO-FUNCTION | UNCOMMON | SUBR | PSEUDO-FUNCTION | [64](#page64), [78](#page78) |
PSEUDO-FUNCTION | UNCOUNT | SUBR | PSEUDO-FUNCTION | [34](#page34), [66](#page66) |
PREDICATE | UNPACK | SUBR | PSEUDO-FUNCTION | [87](#page87) |
PSEUDO-FUNCTION | UNSPECIAL | SUBR | | [64](#page64), [78](#page78) |
PSEUDO-FUNCTION | UNTRACE | EXPR | PSEUDO-FUNCTION | [32](#page32), [66](#page66) |
PREDICATE | UNTRACESET | EXPR | PSEUDO-FUNCTION | [68](#page68) |
``` | ZEROP | SUBR | PREDICATE | [26](#page26), [64](#page64) |
```
PSEUDO-FUNCTION
PSEUDO- FUNC TION
PSEUDO-FUNCTION
```
```
PREDICATE
PREDICATE
PSEUDO-FUNCTION
PSEUDO-FUNCTION
PSEUDO-FUNCTION
```
```
PSEUDO-FUNCTION
```
```
PREDICATE
PSEUDO-FUNCTION
PREDICATE
```
```
PSEUDO-FUNCTION
PREDICATE
PSEUDO-FUNCTION
```
```
Page -
26,64
88
21, 58
11,61
70
27,64
3, 57
59
69,85
2, 56
3,56
69,87
8 6
69,85
64, 78
64,76
6 1
18
2, 56
62
34,66
66
17, 59
59
69,87
APVAL 15, 85,87 18, 58
41, 58
26, 64
87
26, 64
69,85
67
63
8 8
69,88
69,88
3, 23, 57
69,85
11, 26, 57
32,66
88
35,66
71
71
67,77
26, 64
22,69
26, 64
41, 60
26,64
21,71
66
41,59
30,72
26, 64
67,87
```
```
INDEX TO FUNCTION DESCRIPTIONS
```
Function
LABEL
LAP
LEFTSHIFT
LENGTH
LESSP
LIST
LITER
LOAD
LOG AND
LOGOR
LOGXOR
LPAR
MAP
MAPCON
MAPLIST
MAX
MEMBER
MIN
MINUS
MINUSP
MKNAM
NCONC
NIL
NOT
NULL
NUMBERP
NUMOB
OBLIST
ONE P
OPCHAR
OPDEFINE
OR
PACK
PAIR
PAUSE
PERIOD
PLB
PLUS
PLUSS
PRIN 1
PRINT
PRINTPROP
PROG
PROG2
PROP
PUNCH
PUNCHDEF
PUNCHLAP
QUOTE
QUOTIENT
READ
READLAP
RECIP
RECLAIM
REMAINDER
REMFLAG
REMOB
```
FSUBR
SUBR
SUBR
SUBR
SUBR
FSUBR
SUBR
SUBR
FSUBR
FSUBR
FSUBR
APVAL
SUBR
SUBR
SUBR
FSUBR
SUBR
FSUBR
SUBR
SUBR
SUBR
SUBR
APVAL
SUBR
SUBR
SUBR
SUBR
APVAL
SUBR
SUBR
EXPR
FSUBR
SUBR
SUBR
SUBR
APVAL
SUBR
FSUBR
APVAL
SUBR
SUBR
EXPR
FSUBR
SUBR
SUBR
SUBR
EXPR
EXPR
FSUBR
SUBR
SUBR
SUBR
SUBR
SUBR
SUBR
SUBR
SUBR
```
```
Page -
8, 18,70
PSEUDO-FUNCTION 65,73
27, 64
62
PREDICATE 26,64
57
PREDICATE 87
PSEUDO-FUNCTION 67
27,64
26,64
27, 64
69,85
FUNCTIONAL 63
FUNCTIONAL PSEUDO- FUNCTION 6 3
FUNCTIONAL 20, 21, 63
26,64
PREDICATE 11,62
26, 64
26,63
PREDICATE 26,64
86
PSEUDO-FUNCTION 62
22,69
PREDICATE 21, 23,^58
PREDICATE 11,57
PREDICATE 26, 64
PSEUDO-FUNCTION 86
69
PREDICATE 26, 64
PREDICATE 8 7
PSEUDO-FUNCTION 65,75
PREDICATE 21, 58
PSEUDO-FUNCTION 86
60
PSEUDO-FUNCTION 67
69,85
PSEUDO- FUNCTION 67
25,63
69,85
PSEUDO-FUNCTION 65,84
PSEUDO-FUNCTION 65,84
PSEUDO-FUNCTION LIBRARY 68
29,71
42,66
FUNCTIONAL 59
PSEUDO-FUNCTION 65,84
PSEUDO-FUNCTION LIBRARY 6 8
PSEUDO-FUNCTION LIBRARY 68,76
10, 22, 71
26,64
PSEUDO-FUNCTION 65,84
PSEUDO-FUNCTION 65,76
26,64
PSEUDO-FUNCTION 67
26, 64
PSEUDO-FUNCTION 41, 60
PSEUDO-FUNCTION 67
```
```
INDEX TO FUNCTION DESCRIPTIONS
```
Function
```
REMPROP
RETURN
REVERSE
RPAR
RPLACA
RPLACD
SASSOC
SEARCH
SELECT
SET
SETQ
SLASH
SPEAK
SPECIAL
STAR
STARTREAD
SUB1
SUB LIS
SUBST
T
TEMPUS-FUGIT
TERPRI
TIMES
TRACE
TRACESET
UNCOMMON
UNCOUNT
UNPACK
UNSPECIAL
UNTRACE
UNTRACESET
ZEROP
*T*
```
```
SUBR
SUBR
SUBR
APVAL
SUBR
SUBR
SUBR
SUBR
FEXPR
SUBR
FSUBR
APVAL
SUBR
SUBR
APVAL
SUBR
SUBR
SUBR
SUBR
APVAL
SUBR
SUBR
FSUBR
EXPR
EXPR
SUBR
SUBR
SUBR
SUBR
EXPR
EXPR
SUBR
APVAL
```
```
PSEUDO-FUNCTION
PSEUDO-FUNCTION
```
```
PSEUDO-FUNCTION
PSEUDO-FUNCTION
FUNCTIONAL
FUNCTIONAL
PSEUDO-FUNCTION
PSEUDO-FUNCTION
PSEUDO-FUNCTION
PSEUDO-FUNCTION
PSEUDO-FUNCTION
```
```
PSEUDO-FUNCTION
PSEUDO-FUNCTION
PSEUDO-FUNCTION
PSEUDO-FUNCTION
PSETJDO-FUNCTION
PSEUDO-FUNCTION
PSEUDO-FUNCTION
PSEUDO-FUNCTION
PSEUDO- FUNC TION
PREDICATE
```
```
Page
41,59
30,72
6 2
69,85
41,58
41,58
60
63
66
30, 71
30, 71
69,85
34,66 64, 78
69,85
87
26, 64
12,61
11, 61
22,69
67
65,84
26,64
32,66, 79
LIBRARY 6 8
64, 78
34,66
87
64,78
32,66
68
26,64
22,69
```
``` ```
Symbol or Term Symbol or Term

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1,6 +1,6 @@
<!DOCTYPE html PUBLIC "" <!DOCTYPE html PUBLIC ""
""> "">
<html><head><meta charset="UTF-8" /><title>beowulf</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Beowulf</span> <span class="project-version">0.3.0-SNAPSHOT</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 current"><a href="intro.html"><div class="inner"><span>beowulf</span></div></a></li><li class="depth-1 "><a href="mexpr.html"><div class="inner"><span>M-Expressions</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>beowulf</span></div></div></li><li class="depth-2 branch"><a href="beowulf.bootstrap.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>bootstrap</span></div></a></li><li class="depth-2 branch"><a href="beowulf.cons-cell.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>cons-cell</span></div></a></li><li class="depth-2 branch"><a href="beowulf.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-2 branch"><a href="beowulf.gendoc.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>gendoc</span></div></a></li><li class="depth-2 branch"><a href="beowulf.host.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>host</span></div></a></li><li class="depth-2 branch"><a href="beowulf.io.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>io</span></div></a></li><li class="depth-2 branch"><a href="beowulf.oblist.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>oblist</span></div></a></li><li class="depth-2 branch"><a href="beowulf.read.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>read</span></div></a></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>reader</span></div></div></li><li class="depth-3 branch"><a href="beowulf.reader.char-reader.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>char-reader</span></div></a></li><li class="depth-3 branch"><a href="beowulf.reader.generate.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>generate</span></div></a></li><li class="depth-3 branch"><a href="beowulf.reader.macros.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>macros</span></div></a></li><li class="depth-3 branch"><a href="beowulf.reader.parser.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>parser</span></div></a></li><li class="depth-3"><a href="beowulf.reader.simplify.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>simplify</span></div></a></li></ul></div><div class="document" id="content"><div class="doc"><div class="markdown"><h1><a href="#beowulf" name="beowulf"></a>beowulf</h1> <html><head><meta charset="UTF-8" /><title>beowulf</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Beowulf</span> <span class="project-version">0.3.0-SNAPSHOT</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 current"><a href="intro.html"><div class="inner"><span>beowulf</span></div></a></li><li class="depth-1 "><a href="mexpr.html"><div class="inner"><span>M-Expressions</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>beowulf</span></div></div></li><li class="depth-2 branch"><a href="beowulf.bootstrap.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>bootstrap</span></div></a></li><li class="depth-2 branch"><a href="beowulf.cons-cell.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>cons-cell</span></div></a></li><li class="depth-2 branch"><a href="beowulf.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-2 branch"><a href="beowulf.gendoc.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>gendoc</span></div></a></li><li class="depth-2 branch"><a href="beowulf.host.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>host</span></div></a></li><li class="depth-2 branch"><a href="beowulf.io.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>io</span></div></a></li><li class="depth-2 branch"><a href="beowulf.manual.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>manual</span></div></a></li><li class="depth-2 branch"><a href="beowulf.oblist.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>oblist</span></div></a></li><li class="depth-2 branch"><a href="beowulf.read.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>read</span></div></a></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>reader</span></div></div></li><li class="depth-3 branch"><a href="beowulf.reader.char-reader.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>char-reader</span></div></a></li><li class="depth-3 branch"><a href="beowulf.reader.generate.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>generate</span></div></a></li><li class="depth-3 branch"><a href="beowulf.reader.macros.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>macros</span></div></a></li><li class="depth-3 branch"><a href="beowulf.reader.parser.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>parser</span></div></a></li><li class="depth-3"><a href="beowulf.reader.simplify.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>simplify</span></div></a></li><li class="depth-2"><a href="beowulf.scratch.html"><div class="inner"><span class="tree" style="top: -176px;"><span class="top" style="height: 185px;"></span><span class="bottom"></span></span><span>scratch</span></div></a></li></ul></div><div class="document" id="content"><div class="doc"><div class="markdown"><h1><a href="#beowulf" name="beowulf"></a>beowulf</h1>
<p>LISP 1.5 is to all Lisp dialects as Beowulf is to Emglish literature.</p> <p>LISP 1.5 is to all Lisp dialects as Beowulf is to Emglish literature.</p>
<h2><a href="#what-this-is" name="what-this-is"></a>What this is</h2> <h2><a href="#what-this-is" name="what-this-is"></a>What this is</h2>
<p>A work-in-progress towards an implementation of Lisp 1.5 in Clojure. The objective is to build a complete and accurate implementation of Lisp 1.5 as described in the manual, with, in so far as is possible, exactly the same bahaviour - except as documented below.</p> <p>A work-in-progress towards an implementation of Lisp 1.5 in Clojure. The objective is to build a complete and accurate implementation of Lisp 1.5 as described in the manual, with, in so far as is possible, exactly the same bahaviour - except as documented below.</p>
@ -30,330 +30,601 @@
<table> <table>
<thead> <thead>
<tr> <tr>
<th>Symbol </th> <th>Function </th>
<th>Type </th> <th>Type </th>
<th>Signature </th> <th>Signature </th>
<th>Implementation </th>
<th>Documentation </th> <th>Documentation </th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr> <tr>
<td>NIL </td> <td>NIL </td>
<td>? </td> <td>Lisp variable </td>
<td>null </td> <td> </td>
<td> </td>
<td>? </td> <td>? </td>
</tr> </tr>
<tr> <tr>
<td>T </td> <td>T </td>
<td>? </td> <td>Lisp variable </td>
<td>null </td> <td> </td>
<td> </td>
<td>? </td> <td>? </td>
</tr> </tr>
<tr> <tr>
<td>F </td> <td>F </td>
<td>? </td> <td>Lisp variable </td>
<td>null </td> <td> </td>
<td> </td>
<td>? </td> <td>? </td>
</tr> </tr>
<tr> <tr>
<td>ADD1 </td> <td>ADD1 </td>
<td>Host function </td> <td>Host function </td>
<td>([x]) </td> <td>(ADD1 X) </td>
<td> </td>
<td>? </td> <td>? </td>
</tr> </tr>
<tr> <tr>
<td>AND </td> <td>AND </td>
<td>Host function </td> <td>Host function </td>
<td>([&amp; args]) </td> <td>(AND &amp; ARGS) </td>
<td>PREDICATE </td>
<td><code>T</code> if and only if none of my <code>args</code> evaluate to either <code>F</code> or <code>NIL</code>, else <code>F</code>. In <code>beowulf.host</code> principally because I dont yet feel confident to define varargs functions in Lisp. </td> <td><code>T</code> if and only if none of my <code>args</code> evaluate to either <code>F</code> or <code>NIL</code>, else <code>F</code>. In <code>beowulf.host</code> principally because I dont yet feel confident to define varargs functions in Lisp. </td>
</tr> </tr>
<tr> <tr>
<td>APPEND </td> <td>APPEND </td>
<td>Host function </td> <td>Lisp function </td>
<td>([x y]) </td> <td>(APPEND X Y) </td>
<td>Append the the elements of <code>y</code> to the elements of <code>x</code>. All args are assumed to be <code>beowulf.cons-cell/ConsCell</code> objects. See page 11 of the Lisp 1.5 Programmers Manual. </td> <td>LAMBDA-fn </td>
<td>see manual pages <a href="https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=19">11</a>, <a href="https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=69">61</a> </td>
</tr> </tr>
<tr> <tr>
<td>APPLY </td> <td>APPLY </td>
<td>Host function </td> <td>Host function </td>
<td>([function args environment depth]) </td> <td>(APPLY FUNCTION ARGS ENVIRONMENT DEPTH) </td>
<td> </td>
<td>Apply this <code>function</code> to these <code>arguments</code> in this <code>environment</code> and return the result. For bootstrapping, at least, a version of APPLY written in Clojure. All args are assumed to be symbols or <code>beowulf.cons-cell/ConsCell</code> objects. See page 13 of the Lisp 1.5 Programmers Manual. </td> <td>Apply this <code>function</code> to these <code>arguments</code> in this <code>environment</code> and return the result. For bootstrapping, at least, a version of APPLY written in Clojure. All args are assumed to be symbols or <code>beowulf.cons-cell/ConsCell</code> objects. See page 13 of the Lisp 1.5 Programmers Manual. </td>
</tr> </tr>
<tr> <tr>
<td>ATOM </td> <td>ATOM </td>
<td>Host function </td> <td>Host function </td>
<td>([x]) </td> <td>(ATOM X) </td>
<td>PREDICATE </td>
<td>Returns <code>T</code> if and only if the argument <code>x</code> is bound to an atom; else <code>F</code>. It is not clear to me from the documentation whether <code>(ATOM 7)</code> should return <code>T</code> or <code>F</code>. Im going to assume <code>T</code>. </td> <td>Returns <code>T</code> if and only if the argument <code>x</code> is bound to an atom; else <code>F</code>. It is not clear to me from the documentation whether <code>(ATOM 7)</code> should return <code>T</code> or <code>F</code>. Im going to assume <code>T</code>. </td>
</tr> </tr>
<tr> <tr>
<td>CAR </td> <td>CAR </td>
<td>Host function </td>
<td>(CAR X) </td>
<td> </td>
<td>Return the item indicated by the first pointer of a pair. NIL is treated specially: the CAR of NIL is NIL. </td>
</tr>
<tr>
<td>CAAAAR </td>
<td>Lisp function </td>
<td>(CAAAAR X) </td>
<td>LAMBDA-fn </td>
<td>? </td> <td>? </td>
<td>null </td> </tr>
<tr>
<td>CAAADR </td>
<td>Lisp function </td>
<td>(CAAADR X) </td>
<td>LAMBDA-fn </td>
<td>? </td>
</tr>
<tr>
<td>CAAAR </td>
<td>Lisp function </td>
<td>(CAAAR X) </td>
<td>LAMBDA-fn </td>
<td>? </td>
</tr>
<tr>
<td>CAADAR </td>
<td>Lisp function </td>
<td>(CAADAR X) </td>
<td>LAMBDA-fn </td>
<td>? </td>
</tr>
<tr>
<td>CAADDR </td>
<td>Lisp function </td>
<td>(CAADDR X) </td>
<td>LAMBDA-fn </td>
<td>? </td>
</tr>
<tr>
<td>CAADR </td>
<td>Lisp function </td>
<td>(CAADR X) </td>
<td>LAMBDA-fn </td>
<td>? </td>
</tr>
<tr>
<td>CAAR </td>
<td>Lisp function </td>
<td>(CAAR X) </td>
<td>LAMBDA-fn </td>
<td>? </td>
</tr>
<tr>
<td>CADAAR </td>
<td>Lisp function </td>
<td>(CADAAR X) </td>
<td>LAMBDA-fn </td>
<td>? </td>
</tr>
<tr>
<td>CADADR </td>
<td>Lisp function </td>
<td>(CADADR X) </td>
<td>LAMBDA-fn </td>
<td>? </td>
</tr>
<tr>
<td>CADAR </td>
<td>Lisp function </td>
<td>(CADAR X) </td>
<td>LAMBDA-fn </td>
<td>? </td>
</tr>
<tr>
<td>CADDAR </td>
<td>Lisp function </td>
<td>(CADDAR X) </td>
<td>LAMBDA-fn </td>
<td>? </td>
</tr>
<tr>
<td>CADDDR </td>
<td>Lisp function </td>
<td>(CADDDR X) </td>
<td>LAMBDA-fn </td>
<td>? </td>
</tr>
<tr>
<td>CADDR </td>
<td>Lisp function </td>
<td>(CADDR X) </td>
<td>LAMBDA-fn </td>
<td>? </td>
</tr>
<tr>
<td>CADR </td>
<td>Lisp function </td>
<td>(CADR X) </td>
<td>LAMBDA-fn </td>
<td>? </td>
</tr>
<tr>
<td>CDAAAR </td>
<td>Lisp function </td>
<td>(CDAAAR X) </td>
<td>LAMBDA-fn </td>
<td>? </td>
</tr>
<tr>
<td>CDAADR </td>
<td>Lisp function </td>
<td>(CDAADR X) </td>
<td>LAMBDA-fn </td>
<td>? </td>
</tr>
<tr>
<td>CDAAR </td>
<td>Lisp function </td>
<td>(CDAAR X) </td>
<td>LAMBDA-fn </td>
<td>? </td>
</tr>
<tr>
<td>CDADAR </td>
<td>Lisp function </td>
<td>(CDADAR X) </td>
<td>LAMBDA-fn </td>
<td>? </td>
</tr>
<tr>
<td>CDADDR </td>
<td>Lisp function </td>
<td>(CDADDR X) </td>
<td>LAMBDA-fn </td>
<td>? </td>
</tr>
<tr>
<td>CDADR </td>
<td>Lisp function </td>
<td>(CDADR X) </td>
<td>LAMBDA-fn </td>
<td>? </td>
</tr>
<tr>
<td>CDAR </td>
<td>Lisp function </td>
<td>(CDAR X) </td>
<td>LAMBDA-fn </td>
<td>? </td>
</tr>
<tr>
<td>CDDAAR </td>
<td>Lisp function </td>
<td>(CDDAAR X) </td>
<td>LAMBDA-fn </td>
<td>? </td>
</tr>
<tr>
<td>CDDADR </td>
<td>Lisp function </td>
<td>(CDDADR X) </td>
<td>LAMBDA-fn </td>
<td>? </td>
</tr>
<tr>
<td>CDDAR </td>
<td>Lisp function </td>
<td>(CDDAR X) </td>
<td>LAMBDA-fn </td>
<td>? </td>
</tr>
<tr>
<td>CDDDAR </td>
<td>Lisp function </td>
<td>(CDDDAR X) </td>
<td>LAMBDA-fn </td>
<td>? </td>
</tr>
<tr>
<td>CDDDDR </td>
<td>Lisp function </td>
<td>(CDDDDR X) </td>
<td>LAMBDA-fn </td>
<td>? </td>
</tr>
<tr>
<td>CDDDR </td>
<td>Lisp function </td>
<td>(CDDDR X) </td>
<td>LAMBDA-fn </td>
<td>? </td>
</tr>
<tr>
<td>CDDR </td>
<td>Lisp function </td>
<td>(CDDR X) </td>
<td>LAMBDA-fn </td>
<td>? </td> <td>? </td>
</tr> </tr>
<tr> <tr>
<td>CDR </td> <td>CDR </td>
<td>? </td> <td>Host function </td>
<td>null </td> <td>(CDR X) </td>
<td>? </td> <td> </td>
<td>Return the item indicated by the second pointer of a pair. NIL is treated specially: the CDR of NIL is NIL. </td>
</tr> </tr>
<tr> <tr>
<td>CONS </td> <td>CONS </td>
<td>? </td> <td>Host function </td>
<td>null </td> <td>(CONS CAR CDR) </td>
<td>? </td> <td> </td>
<td>Construct a new instance of cons cell with this <code>car</code> and <code>cdr</code>. </td>
</tr> </tr>
<tr> <tr>
<td>COPY </td> <td>COPY </td>
<td>Lisp function </td> <td>Lisp function </td>
<td>(X) </td> <td>(COPY X) </td>
<td>? </td> <td>LAMBDA-fn </td>
<td>see manual pages <a href="https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=70">62</a> </td>
</tr> </tr>
<tr> <tr>
<td>DEFINE </td> <td>DEFINE </td>
<td>Host function </td> <td>Host function </td>
<td>([args]) </td> <td>(DEFINE ARGS) </td>
<td>PSEUDO-FUNCTION </td>
<td>Bootstrap-only version of <code>DEFINE</code> which, post boostrap, can be overwritten in LISP. The single argument to <code>DEFINE</code> should be an assoc list which should be nconced onto the front of the oblist. Broadly, (SETQ OBLIST (NCONC ARG1 OBLIST)) </td> <td>Bootstrap-only version of <code>DEFINE</code> which, post boostrap, can be overwritten in LISP. The single argument to <code>DEFINE</code> should be an assoc list which should be nconced onto the front of the oblist. Broadly, (SETQ OBLIST (NCONC ARG1 OBLIST)) </td>
</tr> </tr>
<tr> <tr>
<td>DIFFERENCE </td> <td>DIFFERENCE </td>
<td>Host function </td> <td>Host function </td>
<td>([x y]) </td> <td>(DIFFERENCE X Y) </td>
<td> </td>
<td>? </td> <td>? </td>
</tr> </tr>
<tr> <tr>
<td>DIVIDE </td> <td>DIVIDE </td>
<td>Lisp function </td> <td>Lisp function </td>
<td>(X Y) </td> <td>(DIVIDE X Y) </td>
<td>? </td> <td>LAMBDA-fn </td>
<td>see manual pages <a href="https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=34">26</a>, <a href="https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=72">64</a> </td>
</tr> </tr>
<tr> <tr>
<td>ERROR </td> <td>ERROR </td>
<td>Host function </td> <td>Host function </td>
<td>([&amp; args]) </td> <td>(ERROR &amp; ARGS) </td>
<td>PSEUDO-FUNCTION </td>
<td>Throw an error </td> <td>Throw an error </td>
</tr> </tr>
<tr> <tr>
<td>EQ </td> <td>EQ </td>
<td>Host function </td> <td>Host function </td>
<td>([x y]) </td> <td>(EQ X Y) </td>
<td>PREDICATE </td>
<td>Returns <code>T</code> if and only if both <code>x</code> and <code>y</code> are bound to the same atom, else <code>NIL</code>. </td> <td>Returns <code>T</code> if and only if both <code>x</code> and <code>y</code> are bound to the same atom, else <code>NIL</code>. </td>
</tr> </tr>
<tr> <tr>
<td>EQUAL </td> <td>EQUAL </td>
<td>Host function </td> <td>Host function </td>
<td>([x y]) </td> <td>(EQUAL X Y) </td>
<td>PREDICATE </td>
<td>This is a predicate that is true if its two arguments are identical S-expressions, and false if they are different. (The elementary predicate <code>EQ</code> is defined only for atomic arguments.) The definition of <code>EQUAL</code> is an example of a conditional expression inside a conditional expression. NOTE: returns <code>F</code> on failure, not <code>NIL</code> </td> <td>This is a predicate that is true if its two arguments are identical S-expressions, and false if they are different. (The elementary predicate <code>EQ</code> is defined only for atomic arguments.) The definition of <code>EQUAL</code> is an example of a conditional expression inside a conditional expression. NOTE: returns <code>F</code> on failure, not <code>NIL</code> </td>
</tr> </tr>
<tr> <tr>
<td>EVAL </td> <td>EVAL </td>
<td>Host function </td> <td>Host function </td>
<td>([expr] [expr env depth]) </td> <td>(EVAL EXPR); (EVAL EXPR ENV DEPTH) </td>
<td> </td>
<td>Evaluate this <code>expr</code> and return the result. If <code>environment</code> is not passed, it defaults to the current value of the global object list. The <code>depth</code> argument is part of the tracing system and should not be set by user code. All args are assumed to be numbers, symbols or <code>beowulf.cons-cell/ConsCell</code> objects. </td> <td>Evaluate this <code>expr</code> and return the result. If <code>environment</code> is not passed, it defaults to the current value of the global object list. The <code>depth</code> argument is part of the tracing system and should not be set by user code. All args are assumed to be numbers, symbols or <code>beowulf.cons-cell/ConsCell</code> objects. </td>
</tr> </tr>
<tr>
<td>FACTORIAL </td>
<td>Lisp function </td>
<td>(FACTORIAL N) </td>
<td>LAMBDA-fn </td>
<td>? </td>
</tr>
<tr> <tr>
<td>FIXP </td> <td>FIXP </td>
<td>Host function </td> <td>Host function </td>
<td>([x]) </td> <td>(FIXP X) </td>
<td>PREDICATE </td>
<td>? </td> <td>? </td>
</tr> </tr>
<tr> <tr>
<td>GENSYM </td> <td>GENSYM </td>
<td>Host function </td> <td>Host function </td>
<td>([]) </td> <td>(GENSYM ) </td>
<td> </td>
<td>Generate a unique symbol. </td> <td>Generate a unique symbol. </td>
</tr> </tr>
<tr> <tr>
<td>GET </td> <td>GET </td>
<td>Lisp function </td> <td>Lisp function </td>
<td>(X Y) </td> <td>(GET X Y) </td>
<td>? </td> <td>LAMBDA-fn </td>
<td>see manual pages <a href="https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=49">41</a>, <a href="https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=67">59</a> </td>
</tr> </tr>
<tr> <tr>
<td>GREATERP </td> <td>GREATERP </td>
<td>Host function </td> <td>Host function </td>
<td>([x y]) </td> <td>(GREATERP X Y) </td>
<td>PREDICATE </td>
<td>? </td> <td>? </td>
</tr> </tr>
<tr> <tr>
<td>INTEROP </td> <td>INTEROP </td>
<td>Host function </td> <td>Host function </td>
<td>([fn-symbol args]) </td> <td>(INTEROP FN-SYMBOL ARGS) </td>
<td>(INTEROP) </td>
<td>Clojure (or other host environment) interoperation API. <code>fn-symbol</code> is expected to be either 1. a symbol bound in the host environment to a function; or 2. a sequence (list) of symbols forming a qualified path name bound to a function. Lower case characters cannot normally be represented in Lisp 1.5, so both the upper case and lower case variants of <code>fn-symbol</code> will be tried. If the function youre looking for has a mixed case name, that is not currently accessible. <code>args</code> is expected to be a Lisp 1.5 list of arguments to be passed to that function. Return value must be something acceptable to Lisp 1.5, so either a symbol, a number, or a Lisp 1.5 list. If <code>fn-symbol</code> is not found (even when cast to lower case), or is not a function, or the value returned cannot be represented in Lisp 1.5, an exception is thrown with <code>:cause</code> bound to <code>:interop</code> and <code>:detail</code> set to a value representing the actual problem. </td> <td>Clojure (or other host environment) interoperation API. <code>fn-symbol</code> is expected to be either 1. a symbol bound in the host environment to a function; or 2. a sequence (list) of symbols forming a qualified path name bound to a function. Lower case characters cannot normally be represented in Lisp 1.5, so both the upper case and lower case variants of <code>fn-symbol</code> will be tried. If the function youre looking for has a mixed case name, that is not currently accessible. <code>args</code> is expected to be a Lisp 1.5 list of arguments to be passed to that function. Return value must be something acceptable to Lisp 1.5, so either a symbol, a number, or a Lisp 1.5 list. If <code>fn-symbol</code> is not found (even when cast to lower case), or is not a function, or the value returned cannot be represented in Lisp 1.5, an exception is thrown with <code>:cause</code> bound to <code>:interop</code> and <code>:detail</code> set to a value representing the actual problem. </td>
</tr> </tr>
<tr> <tr>
<td>INTERSECTION </td> <td>INTERSECTION </td>
<td>Lisp function </td> <td>Lisp function </td>
<td>(X Y) </td> <td>(INTERSECTION X Y) </td>
<td>LAMBDA-fn </td>
<td>? </td> <td>? </td>
</tr> </tr>
<tr> <tr>
<td>LENGTH </td> <td>LENGTH </td>
<td>Lisp function </td> <td>Lisp function </td>
<td>(L) </td> <td>(LENGTH L) </td>
<td>? </td> <td>LAMBDA-fn </td>
<td>see manual pages <a href="https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=70">62</a> </td>
</tr> </tr>
<tr> <tr>
<td>LESSP </td> <td>LESSP </td>
<td>Host function </td> <td>Host function </td>
<td>([x y]) </td> <td>(LESSP X Y) </td>
<td>PREDICATE </td>
<td>? </td> <td>? </td>
</tr> </tr>
<tr> <tr>
<td>MEMBER </td> <td>MEMBER </td>
<td>Lisp function </td> <td>Lisp function </td>
<td>(A X) </td> <td>(MEMBER A X) </td>
<td>? </td> <td>LAMBDA-fn </td>
<td>see manual pages <a href="https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=19">11</a>, <a href="https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=70">62</a> </td>
</tr> </tr>
<tr> <tr>
<td>MINUSP </td> <td>MINUSP </td>
<td>Lisp function </td> <td>Lisp function </td>
<td>(X) </td> <td>(MINUSP X) </td>
<td>? </td> <td>LAMBDA-fn </td>
<td>see manual pages <a href="https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=34">26</a>, <a href="https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=72">64</a> </td>
</tr>
<tr>
<td>NOT </td>
<td>Lisp function </td>
<td>(NOT X) </td>
<td>LAMBDA-fn </td>
<td>see manual pages <a href="https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=29">21</a>, <a href="https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=31">23</a>, <a href="https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=66">58</a> </td>
</tr> </tr>
<tr> <tr>
<td>NULL </td> <td>NULL </td>
<td>Lisp function </td> <td>Lisp function </td>
<td>(X) </td> <td>(NULL X) </td>
<td>? </td> <td>LAMBDA-fn </td>
<td>see manual pages <a href="https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=19">11</a>, <a href="https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=65">57</a> </td>
</tr> </tr>
<tr> <tr>
<td>NUMBERP </td> <td>NUMBERP </td>
<td>Host function </td> <td>Host function </td>
<td>([x]) </td> <td>(NUMBERP X) </td>
<td>PREDICATE </td>
<td>? </td> <td>? </td>
</tr> </tr>
<tr> <tr>
<td>OBLIST </td> <td>OBLIST </td>
<td>Host function </td> <td>Host function </td>
<td>([]) </td> <td>(OBLIST ) </td>
<td> </td>
<td>Return a list of the symbols currently bound on the object list. <strong>NOTE THAT</strong> in the Lisp 1.5 manual, footnote at the bottom of page 69, it implies that an argument can be passed but Im not sure of the semantics of this. </td> <td>Return a list of the symbols currently bound on the object list. <strong>NOTE THAT</strong> in the Lisp 1.5 manual, footnote at the bottom of page 69, it implies that an argument can be passed but Im not sure of the semantics of this. </td>
</tr> </tr>
<tr> <tr>
<td>ONEP </td> <td>ONEP </td>
<td>Lisp function </td> <td>Lisp function </td>
<td>(X) </td> <td>(ONEP X) </td>
<td>? </td> <td>LAMBDA-fn </td>
<td>see manual pages <a href="https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=34">26</a>, <a href="https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=72">64</a> </td>
</tr> </tr>
<tr> <tr>
<td>PAIR </td> <td>PAIR </td>
<td>Lisp function </td> <td>Lisp function </td>
<td>(X Y) </td> <td>(PAIR X Y) </td>
<td>? </td> <td>LAMBDA-fn </td>
<td>see manual pages <a href="https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=68">60</a> </td>
</tr> </tr>
<tr> <tr>
<td>PLUS </td> <td>PLUS </td>
<td>Host function </td> <td>Host function </td>
<td>([&amp; args]) </td> <td>(PLUS &amp; ARGS) </td>
<td> </td>
<td>? </td> <td>? </td>
</tr> </tr>
<tr> <tr>
<td>PRETTY </td> <td>PRETTY </td>
<td>? </td> <td>Lisp variable </td>
<td>null </td> <td> </td>
<td>(PRETTY) </td>
<td>? </td> <td>? </td>
</tr> </tr>
<tr> <tr>
<td>PRINT </td> <td>PRINT </td>
<td>? </td> <td>Lisp variable </td>
<td>null </td> <td> </td>
<td>PSEUDO-FUNCTION </td>
<td>? </td> <td>? </td>
</tr> </tr>
<tr> <tr>
<td>PROP </td> <td>PROP </td>
<td>Lisp function </td> <td>Lisp function </td>
<td>(X Y U) </td> <td>(PROP X Y U) </td>
<td>? </td> <td>LAMBDA-fn </td>
<td>see manual pages <a href="https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=67">59</a> </td>
</tr> </tr>
<tr> <tr>
<td>QUOTIENT </td> <td>QUOTIENT </td>
<td>Host function </td> <td>Host function </td>
<td>([x y]) </td> <td>(QUOTIENT X Y) </td>
<td> </td>
<td>Im not certain from the documentation whether Lisp 1.5 <code>QUOTIENT</code> returned the integer part of the quotient, or a realnum representing the whole quotient. I am for now implementing the latter. </td> <td>Im not certain from the documentation whether Lisp 1.5 <code>QUOTIENT</code> returned the integer part of the quotient, or a realnum representing the whole quotient. I am for now implementing the latter. </td>
</tr> </tr>
<tr>
<td>RANGE </td>
<td>Lisp variable </td>
<td>? </td>
<td>(RANGE (LAMBDA (N M) (COND ((LESSP M N) (QUOTE NIL)) ((QUOTE T) (CONS N (RANGE (ADD1 N) M)))))) </td>
<td>? </td>
</tr>
<tr> <tr>
<td>READ </td> <td>READ </td>
<td>Host function </td> <td>Host function </td>
<td>([] [input]) </td> <td>(READ ); (READ INPUT) </td>
<td>PSEUDO-FUNCTION </td>
<td>An implementation of a Lisp reader sufficient for bootstrapping; not necessarily the final Lisp reader. <code>input</code> should be either a string representation of a LISP expression, or else an input stream. A single form will be read. </td> <td>An implementation of a Lisp reader sufficient for bootstrapping; not necessarily the final Lisp reader. <code>input</code> should be either a string representation of a LISP expression, or else an input stream. A single form will be read. </td>
</tr> </tr>
<tr> <tr>
<td>REMAINDER </td> <td>REMAINDER </td>
<td>Host function </td> <td>Host function </td>
<td>([x y]) </td> <td>(REMAINDER X Y) </td>
<td> </td>
<td>? </td> <td>? </td>
</tr> </tr>
<tr> <tr>
<td>REPEAT </td> <td>REPEAT </td>
<td>Lisp function </td> <td>Lisp function </td>
<td>(N X) </td> <td>(REPEAT N X) </td>
<td>LAMBDA-fn </td>
<td>? </td> <td>? </td>
</tr> </tr>
<tr> <tr>
<td>RPLACA </td> <td>RPLACA </td>
<td>Host function </td> <td>Host function </td>
<td>([cell value]) </td> <td>(RPLACA CELL VALUE) </td>
<td>PSEUDO-FUNCTION </td>
<td>Replace the CAR pointer of this <code>cell</code> with this <code>value</code>. Dangerous, should really not exist, but does in Lisp 1.5 (and was important for some performance hacks in early Lisps) </td> <td>Replace the CAR pointer of this <code>cell</code> with this <code>value</code>. Dangerous, should really not exist, but does in Lisp 1.5 (and was important for some performance hacks in early Lisps) </td>
</tr> </tr>
<tr> <tr>
<td>RPLACD </td> <td>RPLACD </td>
<td>Host function </td> <td>Host function </td>
<td>([cell value]) </td> <td>(RPLACD CELL VALUE) </td>
<td>PSEUDO-FUNCTION </td>
<td>Replace the CDR pointer of this <code>cell</code> with this <code>value</code>. Dangerous, should really not exist, but does in Lisp 1.5 (and was important for some performance hacks in early Lisps) </td> <td>Replace the CDR pointer of this <code>cell</code> with this <code>value</code>. Dangerous, should really not exist, but does in Lisp 1.5 (and was important for some performance hacks in early Lisps) </td>
</tr> </tr>
<tr> <tr>
<td>SET </td> <td>SET </td>
<td>Host function </td> <td>Host function </td>
<td>([symbol val]) </td> <td>(SET SYMBOL VAL) </td>
<td>PSEUDO-FUNCTION </td>
<td>Implementation of SET in Clojure. Add to the <code>oblist</code> a binding of the value of <code>var</code> to the value of <code>val</code>. NOTE WELL: this is not SETQ! </td> <td>Implementation of SET in Clojure. Add to the <code>oblist</code> a binding of the value of <code>var</code> to the value of <code>val</code>. NOTE WELL: this is not SETQ! </td>
</tr> </tr>
<tr> <tr>
<td>SUB1 </td> <td>SUB1 </td>
<td>Lisp function </td> <td>Lisp function </td>
<td>(N) </td> <td>(SUB1 N) </td>
<td>? </td> <td>LAMBDA-fn </td>
<td>see manual pages <a href="https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=34">26</a>, <a href="https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=72">64</a> </td>
</tr> </tr>
<tr> <tr>
<td>SYSIN </td> <td>SYSIN </td>
<td>Host function </td> <td>Host function </td>
<td>([filename]) </td> <td>(SYSIN ); (SYSIN FILENAME) </td>
<td>(SYSIN) </td>
<td>Read the contents of the file at this <code>filename</code> into the object list. If the file is not a valid Beowulf sysout file, this will probably corrupt the system, you have been warned. File paths will be considered relative to the filepath set when starting Lisp. It is intended that sysout files can be read both from resources within the jar file, and from the file system. If a named file exists in both the file system and the resources, the file system will be preferred. <strong>NOTE THAT</strong> if the provided <code>filename</code> does not end with <code>.lsp</code> (which, if youre writing it from the Lisp REPL, it wont), the extension <code>.lsp</code> will be appended. </td> <td>Read the contents of the file at this <code>filename</code> into the object list. If the file is not a valid Beowulf sysout file, this will probably corrupt the system, you have been warned. File paths will be considered relative to the filepath set when starting Lisp. It is intended that sysout files can be read both from resources within the jar file, and from the file system. If a named file exists in both the file system and the resources, the file system will be preferred. <strong>NOTE THAT</strong> if the provided <code>filename</code> does not end with <code>.lsp</code> (which, if youre writing it from the Lisp REPL, it wont), the extension <code>.lsp</code> will be appended. </td>
</tr> </tr>
<tr> <tr>
<td>SYSOUT </td> <td>SYSOUT </td>
<td>Host function </td> <td>Host function </td>
<td>([] [filepath]) </td> <td>(SYSOUT ); (SYSOUT FILEPATH) </td>
<td>(SYSOUT) </td>
<td>Dump the current content of the object list to file. If no <code>filepath</code> is specified, a file name will be constructed of the symbol <code>Sysout</code> and the current date. File paths will be considered relative to the filepath set when starting Lisp. </td> <td>Dump the current content of the object list to file. If no <code>filepath</code> is specified, a file name will be constructed of the symbol <code>Sysout</code> and the current date. File paths will be considered relative to the filepath set when starting Lisp. </td>
</tr> </tr>
<tr> <tr>
<td>TERPRI </td> <td>TERPRI </td>
<td>? </td> <td>Lisp variable </td>
<td>null </td> <td> </td>
<td>PSEUDO-FUNCTION </td>
<td>? </td> <td>? </td>
</tr> </tr>
<tr> <tr>
<td>TIMES </td> <td>TIMES </td>
<td>Host function </td> <td>Host function </td>
<td>([&amp; args]) </td> <td>(TIMES &amp; ARGS) </td>
<td> </td>
<td>? </td> <td>? </td>
</tr> </tr>
<tr> <tr>
<td>TRACE </td> <td>TRACE </td>
<td>? </td> <td>Host function </td>
<td>null </td> <td>(TRACE S) </td>
<td>? </td> <td>PSEUDO-FUNCTION </td>
<td>Add this symbol <code>s</code> to the set of symbols currently being traced. If <code>s</code> is not a symbol, does nothing. </td>
</tr> </tr>
<tr> <tr>
<td>UNTRACE </td> <td>UNTRACE </td>
<td>? </td> <td>Host function </td>
<td>null </td> <td>(UNTRACE S) </td>
<td>PSEUDO-FUNCTION </td>
<td>? </td> <td>? </td>
</tr> </tr>
<tr> <tr>
<td>ZEROP </td> <td>ZEROP </td>
<td>Lisp function </td> <td>Lisp function </td>
<td>(N) </td> <td>(ZEROP N) </td>
<td>? </td> <td>LAMBDA-fn </td>
<td>see manual pages <a href="https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=34">26</a>, <a href="https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=72">64</a> </td>
</tr> </tr>
</tbody> </tbody>
</table> </table>

View file

@ -1,6 +1,6 @@
<!DOCTYPE html PUBLIC "" <!DOCTYPE html PUBLIC ""
""> "">
<html><head><meta charset="UTF-8" /><title>M-Expressions</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Beowulf</span> <span class="project-version">0.3.0-SNAPSHOT</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 "><a href="intro.html"><div class="inner"><span>beowulf</span></div></a></li><li class="depth-1 current"><a href="mexpr.html"><div class="inner"><span>M-Expressions</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>beowulf</span></div></div></li><li class="depth-2 branch"><a href="beowulf.bootstrap.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>bootstrap</span></div></a></li><li class="depth-2 branch"><a href="beowulf.cons-cell.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>cons-cell</span></div></a></li><li class="depth-2 branch"><a href="beowulf.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-2 branch"><a href="beowulf.gendoc.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>gendoc</span></div></a></li><li class="depth-2 branch"><a href="beowulf.host.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>host</span></div></a></li><li class="depth-2 branch"><a href="beowulf.io.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>io</span></div></a></li><li class="depth-2 branch"><a href="beowulf.oblist.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>oblist</span></div></a></li><li class="depth-2 branch"><a href="beowulf.read.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>read</span></div></a></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>reader</span></div></div></li><li class="depth-3 branch"><a href="beowulf.reader.char-reader.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>char-reader</span></div></a></li><li class="depth-3 branch"><a href="beowulf.reader.generate.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>generate</span></div></a></li><li class="depth-3 branch"><a href="beowulf.reader.macros.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>macros</span></div></a></li><li class="depth-3 branch"><a href="beowulf.reader.parser.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>parser</span></div></a></li><li class="depth-3"><a href="beowulf.reader.simplify.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>simplify</span></div></a></li></ul></div><div class="document" id="content"><div class="doc"><div class="markdown"><h1><a href="#m-expressions" name="m-expressions"></a>M-Expressions</h1> <html><head><meta charset="UTF-8" /><title>M-Expressions</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Beowulf</span> <span class="project-version">0.3.0-SNAPSHOT</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 "><a href="intro.html"><div class="inner"><span>beowulf</span></div></a></li><li class="depth-1 current"><a href="mexpr.html"><div class="inner"><span>M-Expressions</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>beowulf</span></div></div></li><li class="depth-2 branch"><a href="beowulf.bootstrap.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>bootstrap</span></div></a></li><li class="depth-2 branch"><a href="beowulf.cons-cell.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>cons-cell</span></div></a></li><li class="depth-2 branch"><a href="beowulf.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-2 branch"><a href="beowulf.gendoc.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>gendoc</span></div></a></li><li class="depth-2 branch"><a href="beowulf.host.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>host</span></div></a></li><li class="depth-2 branch"><a href="beowulf.io.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>io</span></div></a></li><li class="depth-2 branch"><a href="beowulf.manual.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>manual</span></div></a></li><li class="depth-2 branch"><a href="beowulf.oblist.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>oblist</span></div></a></li><li class="depth-2 branch"><a href="beowulf.read.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>read</span></div></a></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>reader</span></div></div></li><li class="depth-3 branch"><a href="beowulf.reader.char-reader.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>char-reader</span></div></a></li><li class="depth-3 branch"><a href="beowulf.reader.generate.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>generate</span></div></a></li><li class="depth-3 branch"><a href="beowulf.reader.macros.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>macros</span></div></a></li><li class="depth-3 branch"><a href="beowulf.reader.parser.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>parser</span></div></a></li><li class="depth-3"><a href="beowulf.reader.simplify.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>simplify</span></div></a></li><li class="depth-2"><a href="beowulf.scratch.html"><div class="inner"><span class="tree" style="top: -176px;"><span class="top" style="height: 185px;"></span><span class="bottom"></span></span><span>scratch</span></div></a></li></ul></div><div class="document" id="content"><div class="doc"><div class="markdown"><h1><a href="#m-expressions" name="m-expressions"></a>M-Expressions</h1>
<p>M-Expressions (mexprs) are the grammar which John McCarthy origininally used to write Lisp, and the grammar in which many of the function definitions in the <a href="https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf">Lisp 1.5 Programmers Manual</a> are stated. However, I have not seen anywhere a claim that Lisp 1.5 could <em>read</em> M-Expressions, and it is not clear to me whether it was even planned that it should do so.</p> <p>M-Expressions (mexprs) are the grammar which John McCarthy origininally used to write Lisp, and the grammar in which many of the function definitions in the <a href="https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf">Lisp 1.5 Programmers Manual</a> are stated. However, I have not seen anywhere a claim that Lisp 1.5 could <em>read</em> M-Expressions, and it is not clear to me whether it was even planned that it should do so.</p>
<p>Rather, it seems to me probably that M-Expressions were only ever a grammar intended to be written on paper, like <a href="https://en.wikipedia.org/wiki/Backus%E2%80%93Naur_form">Backus Naur Form</a>, to describe and to reason about algorithms.</p> <p>Rather, it seems to me probably that M-Expressions were only ever a grammar intended to be written on paper, like <a href="https://en.wikipedia.org/wiki/Backus%E2%80%93Naur_form">Backus Naur Form</a>, to describe and to reason about algorithms.</p>
<p>I set out to make Beowulf read M-Expressions essentially out of curiousity, to see whether it could be done. I had this idea that if it could be done, I could implement most of Lisp 1.5 simply by copying in the M-Expression definitions out of the manual.</p> <p>I set out to make Beowulf read M-Expressions essentially out of curiousity, to see whether it could be done. I had this idea that if it could be done, I could implement most of Lisp 1.5 simply by copying in the M-Expression definitions out of the manual.</p>

View file

@ -9,9 +9,9 @@
:license {:name "GPL-2.0-or-later" :license {:name "GPL-2.0-or-later"
:url "https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html"} :url "https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html"}
:dependencies [[org.clojure/clojure "1.11.1"] :dependencies [[org.clojure/clojure "1.11.1"]
[org.clojure/math.combinatorics "0.2.0"] ;; not needed in production builds
[org.clojure/math.numeric-tower "0.0.5"] [org.clojure/math.numeric-tower "0.0.5"]
[org.clojure/tools.cli "1.0.214"] [org.clojure/tools.cli "1.0.214"]
[org.clojure/tools.trace "0.7.11"]
[clojure.java-time "1.2.0"] [clojure.java-time "1.2.0"]
[environ "1.2.0"] [environ "1.2.0"]
[instaparse "1.4.12"] [instaparse "1.4.12"]
@ -22,7 +22,9 @@
:plugins [[lein-cloverage "1.2.2"] :plugins [[lein-cloverage "1.2.2"]
[lein-codox "0.10.7"] [lein-codox "0.10.7"]
[lein-environ "1.1.0"]] [lein-environ "1.1.0"]]
:profiles {:uberjar {:aot :all}} :profiles {:uberjar {:aot :all
:omit-source true
:uberjar-exclusions [#"beowulf\.scratch"]}}
:release-tasks [["vcs" "assert-committed"] :release-tasks [["vcs" "assert-committed"]
["change" "version" "leiningen.release/bump-version" "release"] ["change" "version" "leiningen.release/bump-version" "release"]
["vcs" "commit"] ["vcs" "commit"]
@ -34,5 +36,4 @@
["vcs" "commit"]] ["vcs" "commit"]]
:target-path "target/%s" :target-path "target/%s"
:url "https://github.com/simon-brooke/the-great-game" :url "https://github.com/simon-brooke/the-great-game")
)

View file

@ -13,6 +13,34 @@
(APPLY) (APPLY)
(ATOM) (ATOM)
(CAR) (CAR)
(CAAAAR LAMBDA (X) (CAR (CAR (CAR (CAR X)))))
(CAAADR LAMBDA (X) (CAR (CAR (CAR (CDR X)))))
(CAAAR LAMBDA (X) (CAR (CAR (CAR X))))
(CAADAR LAMBDA (X) (CAR (CAR (CDR (CAR X)))))
(CAADDR LAMBDA (X) (CAR (CAR (CDR (CDR X)))))
(CAADR LAMBDA (X) (CAR (CAR (CDR X))))
(CAAR LAMBDA (X) (CAR (CAR X)))
(CADAAR LAMBDA (X) (CAR (CDR (CAR (CAR X)))))
(CADADR LAMBDA (X) (CAR (CDR (CAR (CDR X)))))
(CADAR LAMBDA (X) (CAR (CDR (CAR X))))
(CADDAR LAMBDA (X) (CAR (CDR (CDR (CAR X)))))
(CADDDR LAMBDA (X) (CAR (CDR (CDR (CDR X)))))
(CADDR LAMBDA (X) (CAR (CDR (CDR X))))
(CADR LAMBDA (X) (CAR (CDR X)))
(CDAAAR LAMBDA (X) (CDR (CAR (CAR (CAR X)))))
(CDAADR LAMBDA (X) (CDR (CAR (CAR (CDR X)))))
(CDAAR LAMBDA (X) (CDR (CAR (CAR X))))
(CDADAR LAMBDA (X) (CDR (CAR (CDR (CAR X)))))
(CDADDR LAMBDA (X) (CDR (CAR (CDR (CDR X)))))
(CDADR LAMBDA (X) (CDR (CAR (CDR X))))
(CDAR LAMBDA (X) (CDR (CAR X)))
(CDDAAR LAMBDA (X) (CDR (CDR (CAR (CAR X)))))
(CDDADR LAMBDA (X) (CDR (CDR (CAR (CDR X)))))
(CDDAR LAMBDA (X) (CDR (CDR (CAR X))))
(CDDDAR LAMBDA (X) (CDR (CDR (CDR (CAR X)))))
(CDDDDR LAMBDA (X) (CDR (CDR (CDR (CDR X)))))
(CDDDR LAMBDA (X) (CDR (CDR (CDR X))))
(CDDR LAMBDA (X) (CDR (CDR X)))
(CDR) (CDR)
(CONS) (CONS)
(COPY (COPY
@ -79,6 +107,7 @@
(COND (COND
((NULL X) (U)) ((EQ (CAR X) Y) (CDR X)) ((QUOTE T) (PROP (CDR X) Y U)))) ((NULL X) (U)) ((EQ (CAR X) Y) (CDR X)) ((QUOTE T) (PROP (CDR X) Y U))))
(QUOTIENT) (QUOTIENT)
(RANGE LAMBDA (N M) (COND ((LESSP M N) (QUOTE NIL)) ((QUOTE T) (CONS N (RANGE (ADD1 N) M)))))
(READ) (READ)
(REMAINDER) (REMAINDER)
(REPEAT (REPEAT

View file

@ -0,0 +1,3 @@
;; this isn't a standard Lisp 1.5 function
range[n; m] = [lessp[m; n] -> NIL; T -> cons[n; range[add1[n]; m]]]

View file

@ -249,7 +249,7 @@
(case function-symbol ;; there must be a better way of doing this! (case function-symbol ;; there must be a better way of doing this!
ADD1 (safe-apply ADD1 args) ADD1 (safe-apply ADD1 args)
AND (safe-apply AND args) AND (safe-apply AND args)
APPLY (safe-apply APPLY args) ;; TODO: need to pass the environment and depth APPLY (APPLY (first args) (rest args) environment depth) ;; TODO: need to pass the environment and depth
ATOM (ATOM? (CAR args)) ATOM (ATOM? (CAR args))
CAR (safe-apply CAR args) CAR (safe-apply CAR args)
CDR (safe-apply CDR args) CDR (safe-apply CDR args)

View file

@ -4,7 +4,10 @@
NOTE: this is *very* hacky. You almost certainly do not want to NOTE: this is *very* hacky. You almost certainly do not want to
use this!" use this!"
(:require [beowulf.io :refer [default-sysout SYSIN]] (:require [beowulf.io :refer [default-sysout SYSIN]]
[beowulf.oblist :refer [oblist]] [beowulf.host :refer [ASSOC]]
[beowulf.manual :refer [format-page-references index *manual-url*]]
[beowulf.oblist :refer [NIL oblist]]
[clojure.java.browse :refer [browse-url]]
[clojure.string :refer [join replace upper-case]])) [clojure.string :refer [join replace upper-case]]))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -95,34 +98,56 @@
(= (second entry) 'LAMBDA) (str (cons (first entry) (nth entry 2))) (= (second entry) 'LAMBDA) (str (cons (first entry) (nth entry 2)))
:else "?")) :else "?"))
(defn infer-implementation
[entry]
(case (second entry)
LAMBDA (format "%s-fn" (second entry))
LABEL (format "%s-fn" (second entry))
(or (:implementation (index (keyword (first entry)))) (str entry))))
(defn find-documentation (defn find-documentation
"Find appropriate documentation for this `entry` from the oblist." "Find appropriate documentation for this `entry` from the oblist."
[entry] [entry]
(cond (let [k (keyword (first entry))]
(= (count entry) 1) (if-let [doc (get-metadata-for-entry entry :doc)] (cond
(replace doc "\n" " ") (= (count entry) 1) (if-let [doc (get-metadata-for-entry entry :doc)]
"?") (replace doc "\n" " ")
:else "?")) "?")
(k index) (str "see manual pages " (format-page-references k))
:else "?")))
(defn gen-doc-table (defn gen-doc-table
([] ([]
(gen-doc-table default-sysout)) (gen-doc-table default-sysout))
([sysfile] ([sysfile]
(try (SYSIN sysfile) (when (= NIL @oblist)
(catch Throwable any (try (SYSIN sysfile)
(println (.getMessage any) " while reading " sysfile))) (catch Throwable any
(println (.getMessage any) " while reading " sysfile))))
(join (join
"\n" "\n"
(doall (doall
(concat (concat
'("| Symbol | Type | Signature | Documentation |" '("| Function | Type | Signature | Implementation | Documentation |"
"|--------|------|-----------|---------------|") "|--------------|----------------|------------------|----------------|----------------------|")
(map (map
#(format "| %s | %s | %s | %s |" #(format "| %-12s | %-14s | %-16s | %-14s | %-20s |"
(first %) (first %)
(infer-type %) (infer-type %)
(infer-signature %) (infer-signature %)
(infer-implementation %)
(find-documentation %)) (find-documentation %))
@oblist)))))) @oblist))))))
;; (println (gen-doc-table)) (defn gen-index
([] (gen-index "" "resources/scratch/manual.md"))
([url destination]
(binding [*manual-url* url]
(spit destination
(with-out-str
(doall
(map
println
(list "## Index"
""
(gen-doc-table)))))))))

View file

@ -389,11 +389,11 @@
(defn LESSP (defn LESSP
[x y] [x y]
(< x y)) (if (< x y) T F))
(defn GREATERP (defn GREATERP
[x y] [x y]
(> x y)) (if (> x y) T F))
;;;; Miscellaneous ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; Miscellaneous ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -405,8 +405,11 @@
(defn ERROR (defn ERROR
"Throw an error" "Throw an error"
[& args] [& args]
(throw (ex-info "LISP ERROR" {:cause (apply vector args) (throw (ex-info "LISP ERROR" {:args args
:phase :eval}))) :phase :eval
:function 'ERROR
:type :lisp
:code (or (first args) 'A1)})))
;;;; Assignment and the object list ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; Assignment and the object list ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

769
src/beowulf/manual.clj Normal file
View file

@ -0,0 +1,769 @@
(ns beowulf.manual
"Experimental code for accessing the manual online."
(:require [clojure.string :refer [ends-with? join trim]]))
(def ^:dynamic *manual-url*
"https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf")
(def ^:constant index
"This is data extracted from the index pages of `Lisp 1.5 Programmer's Manual`.
It's here in the hope that we can automatically link to an online PDF link
to the manual when the user invokes a function probably called `DOC` or `HELP`."
{:RECIP
{:fn-name "RECIP",
:call-type "SUBR",
:implementation "",
:page-nos ["26" "64"]},
:QUOTE
{:fn-name "QUOTE",
:call-type "FSUBR",
:implementation "",
:page-nos ["10" "22" "71"]},
:RECLAIM
{:fn-name "RECLAIM",
:call-type "SUBR",
:implementation "PSEUDO-FUNCTION ",
:page-nos ["67"]},
:NUMOB
{:fn-name "NUMOB",
:call-type "SUBR",
:implementation "PSEUDO-FUNCTION ",
:page-nos ["86"]},
:EVLIS
{:fn-name "EVLIS",
:call-type "SUBR",
:implementation "",
:page-nos ["71"]},
:DASH
{:fn-name "DASH",
:call-type "SUBR",
:implementation "PREDICATE APVAL",
:page-nos ["85" "87 "]},
:EQUAL
{:fn-name "EQUAL",
:call-type "SUBR",
:implementation "PREDICATE",
:page-nos ["11" "26" "57"]},
:PRIN1
{:fn-name "PRIN1",
:call-type "SUBR",
:implementation "PSEUDO-FUNCTION ",
:page-nos ["65" "84"]},
:REMFLAG
{:fn-name "REMFLAG",
:call-type "SUBR",
:implementation "PSEUDO-FUNCTION ",
:page-nos ["41" "60"]},
:DEFINE
{:fn-name "DEFINE",
:call-type "EXPR",
:implementation "PSEUDO-FUNCTION",
:page-nos ["15" "18" "58"]},
:PUNCHLAP
{:fn-name "PUNCHLAP",
:call-type "EXPR",
:implementation "PSEUDO-FUNCTION LIBRARY",
:page-nos ["68" "76"]},
:STARTREAD
{:fn-name "STARTREAD",
:call-type "SUBR",
:implementation "PSEUDO-FUNCTION",
:page-nos ["87"]},
:PERIOD
{:fn-name "PERIOD",
:call-type "APVAL",
:implementation "",
:page-nos ["69" "85"]},
:CP1
{:fn-name "CP1",
:call-type "SUBR",
:implementation "",
:page-nos ["66"]},
:NCONC
{:fn-name "NCONC",
:call-type "SUBR",
:implementation "PSEUDO-FUNCTION ",
:page-nos ["62"]},
:EQ
{:fn-name "EQ",
:call-type "SUBR",
:implementation "PREDICATE",
:page-nos ["3" "23" "57"]},
:RPLACD
{:fn-name "RPLACD",
:call-type "SUBR",
:implementation "PSEUDO-FUNCTION",
:page-nos ["41" "58"]},
:PROG2
{:fn-name "PROG2",
:call-type "SUBR",
:implementation "",
:page-nos ["42" "66"]},
:UNCOUNT
{:fn-name "UNCOUNT",
:call-type "SUBR",
:implementation "PSEUDO-FUNCTION",
:page-nos ["34" "66"]},
:ERROR1
{:fn-name "ERROR1",
:call-type "SUBR",
:implementation "PSEUDO-FUNCTION",
:page-nos ["88"]},
:EXPT
{:fn-name "EXPT",
:call-type "SUBR",
:implementation "",
:page-nos ["26" "64"]},
:NOT
{:fn-name "NOT",
:call-type "SUBR",
:implementation "PREDICATE",
:page-nos ["21" "23" "58"]},
:SLASH
{:fn-name "SLASH",
:call-type "APVAL",
:implementation "",
:page-nos ["69" "85"]},
:RPLACA
{:fn-name "RPLACA",
:call-type "SUBR",
:implementation "PSEUDO-FUNCTION",
:page-nos ["41" "58"]},
:QUOTIENT
{:fn-name "QUOTIENT",
:call-type "SUBR",
:implementation "",
:page-nos ["26" "64"]},
:UNPACK
{:fn-name "UNPACK",
:call-type "SUBR",
:implementation "PSEUDO-FUNCTION",
:page-nos ["87"]},
:CONC
{:fn-name "CONC",
:call-type "FEXPR",
:implementation "",
:page-nos ["61"]},
:CAR
{:fn-name "CAR",
:call-type "SUBR",
:implementation "",
:page-nos ["2" "56"]},
:GENSYM
{:fn-name "GENSYM",
:call-type "SUBR",
:implementation "",
:page-nos ["66"]},
:PROP
{:fn-name "PROP",
:call-type "SUBR",
:implementation "FUNCTIONAL ",
:page-nos [" 59"]},
:MEMBER
{:fn-name "MEMBER",
:call-type "SUBR",
:implementation "PREDICATE ",
:page-nos ["11" "62"]},
:UNTRACESET
{:fn-name "UNTRACESET",
:call-type "EXPR",
:implementation "PSEUDO-FUNCTION",
:page-nos ["68"]},
:UNTRACE
{:fn-name "UNTRACE",
:call-type "EXPR",
:implementation "PSEUDO-FUNCTION",
:page-nos ["32" "66"]},
:MINUSP
{:fn-name "MINUSP",
:call-type "SUBR",
:implementation "PREDICATE ",
:page-nos ["26" "64"]},
:F
{:fn-name "F",
:call-type "APVAL",
:implementation "",
:page-nos ["22" "69"]},
:SPECIAL
{:fn-name "SPECIAL",
:call-type "SUBR",
:implementation "PSEUDO-FUNCTION",
:page-nos ["64" "78"]},
:LPAR
{:fn-name "LPAR",
:call-type "APVAL",
:implementation "",
:page-nos ["69" "85"]},
:GO
{:fn-name "GO",
:call-type "FSUBR",
:implementation "PSEUDO-FUNCTION",
:page-nos ["30" "72"]},
:MKNAM
{:fn-name "MKNAM",
:call-type "SUBR",
:implementation "",
:page-nos ["86"]},
:COMMON
{:fn-name "COMMON",
:call-type "SUBR",
:implementation "PSEUDO-FUNCTION",
:page-nos ["64" "78"]},
:NUMBERP
{:fn-name "NUMBERP",
:call-type "SUBR",
:implementation "PREDICATE ",
:page-nos ["26" "64"]},
:CONS
{:fn-name "CONS",
:call-type "SUBR",
:implementation "",
:page-nos ["2" "56"]},
:PLUS
{:fn-name "PLUS",
:call-type "FSUBR",
:implementation "",
:page-nos ["25" "63"]},
:SET
{:fn-name "SET",
:call-type "SUBR",
:implementation "PSEUDO-FUNCTION",
:page-nos ["30" "71"]},
:DOLLAR
{:fn-name "DOLLAR",
:call-type "APVAL",
:implementation "",
:page-nos ["69" "85"]},
:SASSOC
{:fn-name "SASSOC",
:call-type "SUBR",
:implementation "FUNCTIONAL",
:page-nos ["60"]},
:SELECT
{:fn-name "SELECT",
:call-type "FEXPR",
:implementation "",
:page-nos ["66"]},
:OPDEFINE
{:fn-name "OPDEFINE",
:call-type "EXPR",
:implementation "PSEUDO-FUNCTION ",
:page-nos ["65" "75"]},
:PAUSE
{:fn-name "PAUSE",
:call-type "SUBR",
:implementation "PSEUDO-FUNCTION",
:page-nos ["67"]},
:AND
{:fn-name "AND",
:call-type "FSUBR",
:implementation "PREDICATE",
:page-nos ["21" "58"]},
:COMMA
{:fn-name "COMMA",
:call-type "APVAL",
:implementation "",
:page-nos ["69" "85"]},
:EFFACE
{:fn-name "EFFACE",
:call-type "SUBR",
:implementation "PSEUDO-FUNCTION",
:page-nos ["63"]},
:CSETQ
{:fn-name "CSETQ",
:call-type "FEXPR",
:implementation "PSEUDO-FUNCTION",
:page-nos ["59"]},
:OPCHAR
{:fn-name "OPCHAR",
:call-type "SUBR",
:implementation "PREDICATE ",
:page-nos [" 87"]},
:PRINTPROP
{:fn-name "PRINTPROP",
:call-type "EXPR",
:implementation "PSEUDO-FUNCTION LIBRARY ",
:page-nos ["68"]},
:PLB
{:fn-name "PLB",
:call-type "SUBR",
:implementation "PSEUDO- FUNCTION",
:page-nos ["67"]},
:DIGIT
{:fn-name "DIGIT",
:call-type "SUBR",
:implementation "PREDICATE ",
:page-nos ["87"]},
:PUNCHDEF
{:fn-name "PUNCHDEF",
:call-type "EXPR",
:implementation "PSEUDO-FUNCTION LIBRARY",
:page-nos ["68"]},
:ARRAY
{:fn-name "ARRAY",
:call-type "SUBR",
:implementation "PSEUDO-FUNCTION",
:page-nos ["27" "64"]},
:MAX
{:fn-name "MAX",
:call-type "FSUBR",
:implementation "",
:page-nos ["26" "64"]},
:INTERN
{:fn-name "INTERN",
:call-type "SUBR",
:implementation "PSEUDO-FUNCTION",
:page-nos ["67" "87"]},
:NIL
{:fn-name "NIL",
:call-type "APVAL",
:implementation "",
:page-nos ["22" "69"]},
:TIMES
{:fn-name "TIMES",
:call-type "FSUBR",
:implementation "",
:page-nos ["26" "64"]},
:ERROR
{:fn-name "ERROR",
:call-type "SUBR",
:implementation "PSEUDO-FUNCTION",
:page-nos ["32" "66"]},
:PUNCH
{:fn-name "PUNCH",
:call-type "SUBR",
:implementation "PSEUDO-FUNCTION",
:page-nos ["65" "84"]},
:REMPROP
{:fn-name "REMPROP",
:call-type "SUBR",
:implementation "PSEUDO-FUNCTION",
:page-nos ["41" "59"]},
:DIVIDE
{:fn-name "DIVIDE",
:call-type "SUBR",
:implementation "",
:page-nos ["26" "64"]},
:OR
{:fn-name "OR",
:call-type "FSUBR",
:implementation "PREDICATE ",
:page-nos ["21" "58"]},
:SUBLIS
{:fn-name "SUBLIS",
:call-type "SUBR",
:implementation "",
:page-nos ["12" "61"]},
:LAP
{:fn-name "LAP",
:call-type "SUBR",
:implementation "PSEUDO-FUNCTION ",
:page-nos ["65" "73"]},
:PROG
{:fn-name "PROG",
:call-type "FSUBR",
:implementation "",
:page-nos ["29" "71"]},
:T
{:fn-name "T",
:call-type "APVAL",
:implementation "",
:page-nos ["22" "69"]},
:GREATERP
{:fn-name "GREATERP",
:call-type "SUBR",
:implementation "PREDICATE",
:page-nos ["26" "64"]},
:CSET
{:fn-name "CSET",
:call-type "EXPR",
:implementation "PSEUDO-FUNCTION",
:page-nos ["17" "59"]},
:FUNCTION
{:fn-name "FUNCTION",
:call-type "FSUBR",
:implementation "",
:page-nos ["21" "71"]},
:LENGTH
{:fn-name "LENGTH",
:call-type "SUBR",
:implementation "",
:page-nos ["62"]},
:MINUS
{:fn-name "MINUS",
:call-type "SUBR",
:implementation "",
:page-nos ["26" "63"]},
:COND
{:fn-name "COND",
:call-type "FSUBR",
:implementation "",
:page-nos ["18"]},
:APPEND
{:fn-name "APPEND",
:call-type "SUBR",
:implementation "",
:page-nos ["11" "61"]},
:CDR
{:fn-name "CDR",
:call-type "SUBR",
:implementation "",
:page-nos ["3" "56"]},
:OBLIST
{:fn-name "OBLIST",
:call-type "APVAL",
:implementation "",
:page-nos ["69"]},
:READ
{:fn-name "READ",
:call-type "SUBR",
:implementation "PSEUDO-FUNCTION ",
:page-nos ["5" "84"]},
:ERRORSET
{:fn-name "ERRORSET",
:call-type "SUBR",
:implementation "PSEUDO-FUNCTION",
:page-nos ["35" "66"]},
:UNCOMMON
{:fn-name "UNCOMMON",
:call-type "SUBR",
:implementation "PSEUDO-FUNCTION ",
:page-nos ["64" "78"]},
:EVAL
{:fn-name "EVAL",
:call-type "SUBR",
:implementation "",
:page-nos ["71"]},
:MIN
{:fn-name "MIN",
:call-type "FSUBR",
:implementation "",
:page-nos ["26" "64"]},
:PAIR
{:fn-name "PAIR",
:call-type "SUBR",
:implementation "",
:page-nos ["60"]},
:BLANK
{:fn-name "BLANK",
:call-type "APVAL",
:implementation "",
:page-nos ["69" "85"]},
:SETQ
{:fn-name "SETQ",
:call-type "FSUBR",
:implementation "PSEUDO-FUNCTION",
:page-nos ["30" "71"]},
:GET
{:fn-name "GET",
:call-type "SUBR",
:implementation "",
:page-nos ["41" "59"]},
:PRINT
{:fn-name "PRINT",
:call-type "SUBR",
:implementation "PSEUDO-FUNCTION ",
:page-nos ["65" "84"]},
:ENDREAD
{:fn-name "ENDREAD",
:call-type "SUBR",
:implementation "PSEUDO-FUNCTION",
:page-nos ["8 8"]},
:RETURN
{:fn-name "RETURN",
:call-type "SUBR",
:implementation "PSEUDO-FUNCTION",
:page-nos ["30" "72"]},
:LITER
{:fn-name "LITER",
:call-type "SUBR",
:implementation "PREDICATE ",
:page-nos ["87"]},
:EOF
{:fn-name "EOF",
:call-type "APVAL",
:implementation "",
:page-nos ["69" "88"]},
:TRACE
{:fn-name "TRACE",
:call-type "EXPR",
:implementation "PSEUDO-FUNCTION",
:page-nos ["32" "66" "79"]},
:TRACESET
{:fn-name "TRACESET",
:call-type "EXPR",
:implementation "PSEUDO-FUNCTION LIBRARY",
:page-nos ["68"]},
:PACK
{:fn-name "PACK",
:call-type "SUBR",
:implementation "PSEUDO-FUNCTION ",
:page-nos ["86"]},
:NULL
{:fn-name "NULL",
:call-type "SUBR",
:implementation "PREDICATE ",
:page-nos ["11" "57"]},
:CLEARBUFF
{:fn-name "CLEARBUFF",
:call-type "SUBR",
:implementation "PSEUDO-FUNCTION",
:page-nos ["86"]},
:LESSP
{:fn-name "LESSP",
:call-type "SUBR",
:implementation "PREDICATE ",
:page-nos ["26" "64"]},
:TERPRI
{:fn-name "TERPRI",
:call-type "SUBR",
:implementation "PSEUDO-FUNCTION",
:page-nos ["65" "84"]},
:ONEP
{:fn-name "ONEP",
:call-type "SUBR",
:implementation "PREDICATE ",
:page-nos [" 26" "64"]},
:EXCISE
{:fn-name "EXCISE",
:call-type "SUBR",
:implementation "PSEUDO-FUNCTION",
:page-nos ["67" "77"]},
:REMOB
{:fn-name "REMOB",
:call-type "SUBR",
:implementation "PSEUDO-FUNCTION ",
:page-nos ["67"]},
:MAP
{:fn-name "MAP",
:call-type "SUBR",
:implementation "FUNCTIONAL ",
:page-nos ["63"]},
:COMPILE
{:fn-name "COMPILE",
:call-type "SUBR",
:implementation "PSEUDO-FUNCTION",
:page-nos ["64" "76"]},
:ADD1
{:fn-name "ADD1",
:call-type "SUBR",
:implementation "",
:page-nos ["26" "64"]},
:ADVANCE
{:fn-name "ADVANCE",
:call-type "SUBR",
:implementation "PSEUDO-FUNCTION",
:page-nos ["88"]},
:SEARCH
{:fn-name "SEARCH",
:call-type "SUBR",
:implementation "FUNCTIONAL",
:page-nos ["63"]},
:APPLY
{:fn-name "APPLY",
:call-type "SUBR",
:implementation "",
:page-nos ["70"]},
:READLAP
{:fn-name "READLAP",
:call-type "SUBR",
:implementation "PSEUDO-FUNCTION ",
:page-nos ["65" "76"]},
:UNSPECIAL
{:fn-name "UNSPECIAL",
:call-type "SUBR",
:implementation "",
:page-nos ["64" "78"]},
:SUBST
{:fn-name "SUBST",
:call-type "SUBR",
:implementation "",
:page-nos ["11" "61"]},
:COPY
{:fn-name "COPY",
:call-type "SUBR",
:implementation "",
:page-nos ["62"]},
:LOGOR
{:fn-name "LOGOR",
:call-type "FSUBR",
:implementation "",
:page-nos ["26" "64"]},
:LABEL
{:fn-name "LABEL",
:call-type "FSUBR",
:implementation "",
:page-nos ["8" "18" "70"]},
:FIXP
{:fn-name "FIXP",
:call-type "SUBR",
:implementation "PREDICATE",
:page-nos ["26" "64"]},
:SUB1
{:fn-name "SUB1",
:call-type "SUBR",
:implementation "",
:page-nos ["26" "64"]},
:ATTRIB
{:fn-name "ATTRIB",
:call-type "SUBR",
:implementation "PSEUDO-FUNCTION",
:page-nos ["59"]},
:DIFFERENCE
{:fn-name "DIFFERENCE",
:call-type "SUBR",
:implementation "",
:page-nos ["26" "64"]},
:REMAINDER
{:fn-name "REMAINDER",
:call-type "SUBR",
:implementation "",
:page-nos ["26" "64"]},
:REVERSE
{:fn-name "REVERSE",
:call-type "SUBR",
:implementation "",
:page-nos ["6 2"]},
:EOR
{:fn-name "EOR",
:call-type "APVAL",
:implementation "",
:page-nos ["69" "88"]},
:PLUSS
{:fn-name "PLUSS",
:call-type "APVAL",
:implementation "",
:page-nos ["69" "85"]},
:TEMPUS-FUGIT
{:fn-name "TEMPUS-FUGIT",
:call-type "SUBR",
:implementation "PSEUDO-FUNCTION",
:page-nos ["67"]},
:LOAD
{:fn-name "LOAD",
:call-type "SUBR",
:implementation "PSEUDO-FUNCTION",
:page-nos ["67"]},
:CHARCOUNT
{:fn-name "CHARCOUNT",
:call-type "APVAL",
:implementation "",
:page-nos ["69" "87"]},
:RPAR
{:fn-name "RPAR",
:call-type "APVAL",
:implementation "",
:page-nos ["69" "85"]},
:COUNT
{:fn-name "COUNT",
:call-type "SUBR",
:implementation "PSEUDO-FUNCTION",
:page-nos ["34" "66"]},
:SPEAK
{:fn-name "SPEAK",
:call-type "SUBR",
:implementation "PSEUDO-FUNCTION",
:page-nos ["34" "66 "]},
:LOGXOR
{:fn-name "LOGXOR",
:call-type "FSUBR",
:implementation "",
:page-nos ["27" "64"]},
:FLOATP
{:fn-name "FLOATP",
:call-type "SUBR",
:implementation "PREDICATE",
:page-nos ["26" "64"]},
:ATOM
{:fn-name "ATOM",
:call-type "SUBR",
:implementation "PREDICATE",
:page-nos ["3" "57"]},
:EQSIGN
{:fn-name "EQSIGN",
:call-type "APVAL",
:implementation "",
:page-nos ["69" "85"]},
:LIST
{:fn-name "LIST",
:call-type "FSUBR",
:implementation "",
:page-nos ["57"]},
:MAPLIST
{:fn-name "MAPLIST",
:call-type "SUBR",
:implementation "FUNCTIONAL ",
:page-nos ["20" "21" "63"]},
:LOGAND
{:fn-name "LOGAND",
:call-type "FSUBR",
:implementation "",
:page-nos ["27" "64"]},
:FLAG
{:fn-name "FLAG",
:call-type "EXPR",
:implementation "PSEUDO-FUNCTION",
:page-nos ["41" "60"]},
:MAPCON
{:fn-name "MAPCON",
:call-type "SUBR",
:implementation "FUNCTIONAL PSEUDO- FUNCTION",
:page-nos ["63"]},
:STAR
{:fn-name "STAR",
:call-type "APVAL",
:implementation "",
:page-nos ["69" "85"]},
:CURCHAR
{:fn-name "CURCHAR",
:call-type "APVAL",
:implementation "",
:page-nos ["69" "87"]},
:DUMP
{:fn-name "DUMP",
:call-type "SUBR",
:implementation "PSEUDO-FUNCTION",
:page-nos ["67"]},
:DEFLIST
{:fn-name "DEFLIST",
:call-type "EXPR",
:implementation "PSEUDO-FUNCTION",
:page-nos ["41" "58"]},
:LEFTSHIFT
{:fn-name "LEFTSHIFT",
:call-type "SUBR",
:implementation "",
:page-nos ["27" "64"]},
:ZEROP
{:fn-name "ZEROP",
:call-type "SUBR",
:implementation "PREDICATE",
:page-nos ["26" "64"]}})
(defn page-url
"Format the URL for the page in the manual with this `page-no`."
[page-no]
(let [n (read-string page-no)
n' (when (and (number? n)
(ends-with? *manual-url* ".pdf"))
;; annoyingly, the manual has eight pages of front-matter
;; before numbering starts.
(+ n 8))]
(format
(if (ends-with? *manual-url* ".pdf") "%s#page=%s" "%s#page%s")
*manual-url*
(or n' (trim (str page-no))))))
(defn format-page-references
"Format page references from the manual index for the function whose name
is `fn-symbol`."
[fn-symbol]
(let [k (if (keyword? fn-symbol) fn-symbol (keyword fn-symbol))]
(join ", "
(doall
(map
(fn [n]
(let [p (trim n)]
(format "<a href='%s'>%s</a>"
(page-url p) p)))
(:page-nos (index k)))))))

View file

@ -16,7 +16,7 @@
(:require [beowulf.reader.char-reader :refer [read-chars]] (:require [beowulf.reader.char-reader :refer [read-chars]]
[beowulf.reader.generate :refer [generate]] [beowulf.reader.generate :refer [generate]]
[beowulf.reader.parser :refer [parse]] [beowulf.reader.parser :refer [parse]]
[beowulf.reader.simplify :refer [remove-optional-space simplify]] [beowulf.reader.simplify :refer [simplify]]
[clojure.string :refer [join split starts-with? trim]]) [clojure.string :refer [join split starts-with? trim]])
(:import [java.io InputStream] (:import [java.io InputStream]
[instaparse.gll Failure])) [instaparse.gll Failure]))
@ -80,15 +80,17 @@
(if (instance? Failure parse-tree) (if (instance? Failure parse-tree)
(doall (println (number-lines source parse-tree)) (doall (println (number-lines source parse-tree))
(throw (ex-info "Parse failed" (assoc parse-tree :source source)))) (throw (ex-info "Parse failed" (assoc parse-tree :source source))))
(generate (simplify (remove-optional-space parse-tree)))))) (generate (simplify parse-tree)))))
(defn read-from-console (defn read-from-console
"Attempt to read a complete lisp expression from the console. NOTE that this "Attempt to read a complete lisp expression from the console. NOTE that this
will only really work for S-Expressions, not M-Expressions." will only really work for S-Expressions, not M-Expressions."
[] []
(loop [r (read-line)] (loop [r (read-line)]
(if (= (count (re-seq #"\(" r)) (if (and (= (count (re-seq #"\(" r))
(count (re-seq #"\)" r))) (count (re-seq #"\)" r)))
(= (count (re-seq #"\[" r))
(count (re-seq #"\]" r))))
r r
(recur (str r "\n" (read-line)))))) (recur (str r "\n" (read-line))))))

View file

@ -47,8 +47,8 @@
(def ^:dynamic *readmacros* (def ^:dynamic *readmacros*
{:car {'DEFUN (fn [f] {:car {'DEFUN (fn [f]
(LIST 'SET (LIST 'QUOTE (second f)) (LIST 'SET (LIST 'QUOTE (second f))
(CONS 'LAMBDA (rest (rest f))))) (LIST 'QUOTE (CONS 'LAMBDA (rest (rest f))))))
'SETQ (fn [f] (LIST 'SET (LIST 'QUOTE (second f)) (nth f 2)))}}) 'SETQ (fn [f] (LIST 'SET (LIST 'QUOTE (second f)) (LIST 'QUOTE (nth f 2))))}})
(defn expand-macros (defn expand-macros
[form] [form]

View file

@ -60,8 +60,8 @@
arrow := '->'; arrow := '->';
args := mexpr | (opt-space mexpr semi-colon opt-space)* opt-space mexpr opt-space; args := mexpr | (opt-space mexpr semi-colon opt-space)* opt-space mexpr opt-space;
fn-name := mvar; fn-name := mvar;
mvar := #'[a-z]+'; mvar := #'[a-z][a-z0-9]*';
mconst := #'[A-Z]+'; mconst := #'[A-Z][A-Z0-9]*';
semi-colon := ';';" semi-colon := ';';"
;; Infix operators appear in mexprs, e.g. on page 7. Ooops! ;; Infix operators appear in mexprs, e.g. on page 7. Ooops!

View file

@ -25,7 +25,7 @@
;;; ;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(declare simplify) (declare simplify-tree)
(defn remove-optional-space (defn remove-optional-space
[tree] [tree]
@ -48,17 +48,17 @@
(loop [r tree'] (loop [r tree']
(if (and r (vector? r) (keyword? (first r))) (if (and r (vector? r) (keyword? (first r)))
(if (= (first r) key) (if (= (first r) key)
(recur (simplify (second r) context)) (recur (simplify-tree (second r) context))
r) r)
r)) r))
tree'))) tree')))
(defn simplify (defn simplify-tree
"Simplify this parse tree `p`. If `p` is an instaparse failure object, throw "Simplify this parse tree `p`. If `p` is an instaparse failure object, throw
an `ex-info`, with `p` as the value of its `:failure` key. an `ex-info`, with `p` as the value of its `:failure` key.
**NOTE THAT** it is assumed that `remove-optional-space` has been run on the **NOTE THAT** it is assumed that `remove-optional-space` has been run on the
parse tree **BEFORE** it is passed to `simplify`." parse tree **BEFORE** it is passed to `simplify-tree`."
([p] ([p]
(if (if
(instance? Failure p) (instance? Failure p)
@ -67,7 +67,7 @@
{:cause :parse-failure {:cause :parse-failure
:phase :simplify :phase :simplify
:failure p})) :failure p}))
(simplify p :expr))) (simplify-tree p :expr)))
([p context] ([p context]
(cond (cond
(string? p) p (string? p) p
@ -78,8 +78,8 @@
(case (first p) (case (first p)
(:λexpr (:λexpr
:args :bindings :body :cond :cond-clause :defn :dot-terminal :args :bindings :body :cond :cond-clause :defn :dot-terminal
:fncall :lhs :quoted-expr :rhs ) (map #(simplify % context) p) :fncall :lhs :quoted-expr :rhs ) (map #(simplify-tree % context) p)
(:arg :expr :coefficient :fn-name :number) (simplify (second p) context) (:arg :expr :coefficient :fn-name :number) (simplify-tree (second p) context)
(:arrow :dot :e :lpar :lsqb :opt-comment :opt-space :q :quote :rpar :rsqb (:arrow :dot :e :lpar :lsqb :opt-comment :opt-space :q :quote :rpar :rsqb
:semi-colon :sep :space) nil :semi-colon :sep :space) nil
:atom (if :atom (if
@ -97,28 +97,35 @@
[:fncall [:fncall
[:mvar "cons"] [:mvar "cons"]
[:args [:args
(simplify (nth p 1) context) (simplify-tree (nth p 1) context)
(simplify (nth p 2) context)]] (simplify-tree (nth p 2) context)]]
(map #(simplify % context) p)) (map #(simplify-tree % context) p))
:iexp (simplify (second p) context) :iexp (simplify-tree (second p) context)
:iexpr [:iexpr :iexpr [:iexpr
[:lhs (simplify (second p) context)] [:lhs (simplify-tree (second p) context)]
(simplify (nth p 2) context) ;; really should be the operator (simplify-tree (nth p 2) context) ;; really should be the operator
[:rhs (simplify (nth p 3) context)]] [:rhs (simplify-tree (nth p 3) context)]]
:mexpr (if :mexpr (if
(:strict *options*) (:strict *options*)
(throw (throw
(ex-info "Cannot parse meta expressions in strict mode" (ex-info "Cannot parse meta expressions in strict mode"
{:cause :strict})) {:cause :strict}))
(simplify (second p) :mexpr)) (simplify-tree (second p) :mexpr))
:list (if :list (if
(= context :mexpr) (= context :mexpr)
[:fncall [:fncall
[:mvar "list"] [:mvar "list"]
[:args (apply vector (map simplify (rest p)))]] [:args (apply vector (map simplify-tree (rest p)))]]
(map #(simplify % context) p)) (map #(simplify-tree % context) p))
:raw (first (remove empty? (map simplify (rest p)))) :raw (first (remove empty? (map simplify-tree (rest p))))
:sexpr (simplify (second p) :sexpr) :sexpr (simplify-tree (second p) :sexpr)
;;default ;;default
p))) p)))
:else p))) :else p)))
(defn simplify
"Simplify this parse tree `p`. If `p` is an instaparse failure object, throw
an `ex-info`, with `p` as the value of its `:failure` key. Calls
`remove-optional-space` before processing."
[p]
(simplify-tree (remove-optional-space p)))

View file

@ -6,7 +6,7 @@
[beowulf.read :refer [gsp]] [beowulf.read :refer [gsp]]
[beowulf.reader.generate :refer [generate]] [beowulf.reader.generate :refer [generate]]
[beowulf.reader.parser :refer [parse]] [beowulf.reader.parser :refer [parse]]
[beowulf.reader.simplify :refer [simplify]])) [beowulf.reader.simplify :refer [simplify-tree]]))
;; These tests are taken generally from the examples on page 10 of ;; These tests are taken generally from the examples on page 10 of
;; Lisp 1.5 Programmers Manual: ;; Lisp 1.5 Programmers Manual:
@ -74,7 +74,7 @@
(let [expected "(LABEL FF (LAMBDA (X) (COND ((ATOM X) X) ((QUOTE T) (FF (CAR X))))))" (let [expected "(LABEL FF (LAMBDA (X) (COND ((ATOM X) X) ((QUOTE T) (FF (CAR X))))))"
actual (print-str actual (print-str
(generate (generate
(simplify (simplify-tree
(parse "label[ff;λ[[x];[atom[x]->x; T->ff[car[x]]]]]"))))] (parse "label[ff;λ[[x];[atom[x]->x; T->ff[car[x]]]]]"))))]
(is (= actual expected))))) (is (= actual expected)))))

View file

@ -5,7 +5,7 @@
(deftest macro-expansion (deftest macro-expansion
(testing "Expanding DEFUN" (testing "Expanding DEFUN"
(let [expected "(SET (QUOTE FACT) (LAMBDA (X) (COND ((ZEROP X) 1) (T (TIMES X (FACT (SUB1 X)))))))" (let [expected "(SET (QUOTE FACT) (QUOTE (LAMBDA (X) (COND ((ZEROP X) 1) (T (TIMES X (FACT (SUB1 X))))))))"
source "(DEFUN FACT (X) (COND ((ZEROP X) 1) (T (TIMES X (FACT (SUB1 X))))))" source "(DEFUN FACT (X) (COND ((ZEROP X) 1) (T (TIMES X (FACT (SUB1 X))))))"
actual (print-str (gsp source))] actual (print-str (gsp source))]
(is (= actual expected))))) (is (= actual expected)))))