Compare commits

..

17 commits

Author SHA1 Message Date
Simon Brooke a0fc8a3e67 Documentation changes only, chiefly spelling/formatting 2024-08-08 17:51:48 +01:00
Simon Brooke 71fa15462d
Sorted out documentation problem for website. 2023-04-10 15:39:04 +01:00
Simon Brooke 20dec65643
Upversioned to 0.3.0; documentation regenerated. 2023-04-10 15:19:26 +01:00
Simon Brooke 544f222edc
Merge branch 'develop' 2023-04-10 15:12:06 +01:00
Simon Brooke 4bfbec0bba
Problems with release build. Being conservative. 2023-04-10 15:02:59 +01:00
Simon Brooke 362b19ae25
Last minute but: was failing to read the SYSOUT file from the jar. 2023-04-10 14:43:23 +01:00
Simon Brooke 8c5727f5df
All tests pass, documentation regenerated, going for release. 2023-04-10 14:26:08 +01:00
Simon Brooke e5677a8300
Two very quick fixes for failing tests 2023-04-09 20:59:02 +01:00
Simon Brooke cde3d79ff3
Much progress, but bad regression in parsing M-Expressions. 2023-04-09 20:52:16 +01:00
Simon Brooke 1dbc57efff
Experimenting with themed documentation (not yet working) 2023-04-09 10:55:51 +01:00
Simon Brooke d07831d69d Added a logo 2023-04-09 08:54:50 +01:00
Simon Brooke b9a22d0961 PROG is working, but regression in EVAL. 2023-04-07 18:58:32 +01:00
Simon Brooke 022e409c51
The accursed program feature. Written; not tested. 2023-04-07 15:35:45 +01:00
Simon Brooke dd6a9f7fbc Merge remote-tracking branch 'origin/develop' into develop 2023-04-06 19:00:24 +01:00
Simon Brooke 49aa58ea8a Merge branch 'feature/1' into develop 2023-04-06 18:59:59 +01:00
Simon Brooke 10a4a6da71 #1: Some polishing of the property lists fix; documentation work. 2023-04-06 18:59:34 +01:00
Simon Brooke 147b35e72a
Auto stash before checking out "origin/develop" 2023-04-03 13:49:16 +01:00
71 changed files with 12195 additions and 3618 deletions

View file

@ -1,6 +1,16 @@
# Change Log # Change Log
All notable changes to this project will be documented in this file. This change log follows the conventions of [keepachangelog.com](http://keepachangelog.com/). All notable changes to this project will be documented in this file. This change log follows the conventions of [keepachangelog.com](http://keepachangelog.com/).
## [0.3.0] - 2023-04-10
### Changed
- Added property lists in the exact format used by Lisp 1.5;
- Added `ASSOC`, `EFFACE`, `MAPLIST`, `PROG`, and other functions;
- Where there are both interpreted (`EXPR`) and Clojure (`SUBR`) implementations of the same function, the `EXPR` is preferred (it is planned to make this configurable if/when there is a working compiler);
- More error messages/diagnostics are now printed in Old English (it is planned to implement internationalisation so that you can switch to messages you actually understand);
- Documentation improvements.
## [0.2.1] - 2023-03-30 ## [0.2.1] - 2023-03-30
### Changed ### Changed

302
README.md
View file

@ -1,30 +1,80 @@
# beowulf # beowulf
## Þý liste cræfte spræc
LISP 1.5 is to all Lisp dialects as Beowulf is to English literature. LISP 1.5 is to all Lisp dialects as Beowulf is to English literature.
![Beowulf logo](https://simon-brooke.github.io/beowulf/docs/img/beowulf_logo_med.png)
## Contents
* [What this is](#what-this-is)
+ [Status](#status)
+ [BUT WHY?!!?!](#but-why-----)
+ [Project Target](#project-target)
+ [Invoking](#invoking)
+ [Building and Invoking](#building-and-invoking)
+ [Reader macros](#reader-macros)
+ [Functions and symbols implemented](#functions-and-symbols-implemented)
+ [Architectural plan](#architectural-plan)
- [resources/lisp1.5.lsp](#resources-lisp15lsp)
- [beowulf/boostrap.clj](#beowulf-boostrapclj)
- [beowulf/host.clj](#beowulf-hostclj)
- [beowulf/read.clj](#beowulf-readclj)
+ [Commentary](#commentary)
* [Installation](#installation)
+ [Input/output](#input-output)
- [SYSOUT](#sysout)
- [SYSIN](#sysin)
* [Learning Lisp 1.5](#learning-lisp-15)
* [Other Lisp 1.5 resources](#other-lisp-15-resources)
+ [Other implmentations](#other-implementations)
+ [History resources](#history-resources)
* [License](#license)
<small><i><a href='http://ecotrust-canada.github.io/markdown-toc/'>Table of contents generated with markdown-toc</a></i></small>
## What this is ## What this is
A work-in-progress towards an implementation of Lisp 1.5 in Clojure. The 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 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 as described in the manual, with, in so far as is possible, exactly the
same bahaviour - except as documented below. same behaviour &mdash; except as documented below.
### BUT WHY?!!?!
Because.
Because Lisp is the only computer language worth learning, and if a thing
is worth learning, it's worth learning properly; which means going back to
the beginning and trying to understand that.
Because there is, so far as I know, no working implementation of Lisp 1.5
for modern machines.
Because I'm barking mad, and this is therapy.
### Status ### Status
Boots to REPL, but few functions yet available. Working Lisp interpreter, but some key features not yet implemented.
* [Project website](https://simon-brooke.github.io/beowulf/). * [Project website](https://simon-brooke.github.io/beowulf/).
* [Source code documentation](https://simon-brooke.github.io/beowulf/docs/codox/index.html). * [Source code documentation](https://simon-brooke.github.io/beowulf/docs/codox/index.html).
### Building and Invoking ### Project Target
Build with The project target is to be able to run the [Wang algorithm for the propositional calculus](https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=52) given in chapter 8 of the *Lisp 1.5 Programmer's Manual*. When that runs, the project is as far as I am concerned feature complete. I may keep tinkering with it after that and I'll certainly accept pull requests which are in the spirit of the project (i.e. making Beowulf more usable, and/or implementing parts of Lisp 1.5 which I have not implemented), but this isn't intended to be a new language for doing real work; it's an educational and archaeological project, not serious engineering.
lein uberjar Some `readline`-like functionality would be really useful, but my attempt to integrate [JLine](https://github.com/jline/jline3) has not (yet) been successful.
An in-core structure editor would be an extremely nice thing, and I may well implement one.
You are of course welcome to fork the project and do whatever you like with it!
### Invoking
Invoke with Invoke with
java -jar target/uberjar/beowulf-0.2.1-SNAPSHOT-standalone.jar --help java -jar target/uberjar/beowulf-0.3.0-standalone.jar --help
(Obviously, check your version number) (Obviously, check your version number)
@ -33,107 +83,128 @@ Command line arguments as follows:
``` ```
-h, --help Print this message -h, --help Print this message
-p PROMPT, --prompt PROMPT Set the REPL prompt to PROMPT -p PROMPT, --prompt PROMPT Set the REPL prompt to PROMPT
-r INITFILE, --read INITFILE Read Lisp functions from the file INITFILE -r INITFILE, --read SYSOUTFILE Read Lisp sysout from the file SYSOUTFILE
-s, --strict Strictly interpret the Lisp 1.5 language, without extensions. (defaults to `resources/lisp1.5.lsp`)
-s, --strict Strictly interpret the Lisp 1.5 language,
without extensions.
``` ```
To end a session, type `STOP` at the command prompt. To end a session, type `STOP` at the command prompt.
### Building and Invoking
Build with
lein uberjar
### Reader macros ### Reader macros
Currently I don't have Currently `SETQ` and `DEFUN` are implemented as reader macros, sort of. It would
now be possible to reimplement them as `FEXPRs` and so the reader macro functionality will probably go away.
### Functions and symbols implemented ### Functions and symbols implemented
The following functions and symbols are implemented:
| Function | Type | Signature | Implementation | Documentation | | Function | Type | Signature | Implementation | Documentation |
|--------------|----------------|------------------|----------------|----------------------| |--------------|----------------|------------------|----------------|----------------------|
| NIL | Lisp variable | | | ? | | NIL | Lisp variable | ? | | The canonical empty list. See manual pages <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=22'>22</a>, <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=69'>69</a>s |
| T | Lisp variable | | | ? | | T | Lisp variable | ? | | The canonical true value. See manual pages <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=22'>22</a>, <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=69'>69</a> |
| F | Lisp variable | | | ? | | F | Lisp variable | ? | | The canonical false value. See manual pages <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=22'>22</a>, <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=69'>69</a> |
| ADD1 | Host function | (ADD1 X) | | ? | | ADD1 | Host lambda function | x:number | | Add one to the number `x`. |
| 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. | | AND | Host lambda function | expr* | PREDICATE | `T` if and only if none of my `args` evaluate to either `F` or `NIL`, else `F`. <br><br>In `beowulf.host` principally because I don't yet feel confident to define varargs functions in Lisp. |
| 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> | | APPEND | Lisp lambda function | ? | | see manual pages <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=11'>11</a>, <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=61'>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 lambda function | ? | | Apply this `function` to these `arguments` in this `environment` and return the result.<br><br>For bootstrapping, at least, a version of APPLY written in Clojure.<br><br>All args are assumed to be symbols or `beowulf.cons-cell/ConsCell` objects.<br><br>See page <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=13'>13</a> of the Lisp 1.5 Programmers Manual. |
| 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`. | | ASSOC | Lisp lambda function, Host lambda function | a:list | ? | If a is an association list such as the one formed by PAIRLIS in the above example, then assoc will produce the first pair whose first term is x. Thus it is a table searching function. All args are assumed to be `beowulf.cons-cell/ConsCell` objects. See page <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=12'>12</a> of the Lisp 1.5 Programmers Manual.<br><br>**NOTE THAT** this function is overridden by an implementation in Lisp, but is currently still present for bootstrapping. |
| 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. | | ATOM | Host lambda function | x:expr | 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`. |
| CAAAAR | Lisp function | (CAAAAR X) | LAMBDA-fn | ? | | CAR | Host lambda function | list | | Return the item indicated by the first pointer of a pair. NIL is treated specially: the CAR of NIL is NIL. |
| CAAADR | Lisp function | (CAAADR X) | LAMBDA-fn | ? | | CAAAAR | Lisp lambda function | list | ? | ? |
| CAAAR | Lisp function | (CAAAR X) | LAMBDA-fn | ? | | CAAADR | Lisp lambda function | list | ? | ? |
| CAADAR | Lisp function | (CAADAR X) | LAMBDA-fn | ? | | CAAAR | Lisp lambda function | list | ? | ? |
| CAADDR | Lisp function | (CAADDR X) | LAMBDA-fn | ? | | CAADAR | Lisp lambda function | list | ? | ? |
| CAADR | Lisp function | (CAADR X) | LAMBDA-fn | ? | | CAADDR | Lisp lambda function | list | ? | ? |
| CAAR | Lisp function | (CAAR X) | LAMBDA-fn | ? | | CAADR | Lisp lambda function | list | ? | ? |
| CADAAR | Lisp function | (CADAAR X) | LAMBDA-fn | ? | | CAAR | Lisp lambda function | list | ? | ? |
| CADADR | Lisp function | (CADADR X) | LAMBDA-fn | ? | | CADAAR | Lisp lambda function | list | ? | ? |
| CADAR | Lisp function | (CADAR X) | LAMBDA-fn | ? | | CADADR | Lisp lambda function | list | ? | ? |
| CADDAR | Lisp function | (CADDAR X) | LAMBDA-fn | ? | | CADAR | Lisp lambda function | list | ? | ? |
| CADDDR | Lisp function | (CADDDR X) | LAMBDA-fn | ? | | CADDAR | Lisp lambda function | list | ? | ? |
| CADDR | Lisp function | (CADDR X) | LAMBDA-fn | ? | | CADDDR | Lisp lambda function | list | ? | ? |
| CADR | Lisp function | (CADR X) | LAMBDA-fn | ? | | CADDR | Lisp lambda function | list | ? | ? |
| CDAAAR | Lisp function | (CDAAAR X) | LAMBDA-fn | ? | | CADR | Lisp lambda function | list | ? | ? |
| CDAADR | Lisp function | (CDAADR X) | LAMBDA-fn | ? | | CDAAAR | Lisp lambda function | list | ? | ? |
| CDAAR | Lisp function | (CDAAR X) | LAMBDA-fn | ? | | CDAADR | Lisp lambda function | list | ? | ? |
| CDADAR | Lisp function | (CDADAR X) | LAMBDA-fn | ? | | CDAAR | Lisp lambda function | list | ? | ? |
| CDADDR | Lisp function | (CDADDR X) | LAMBDA-fn | ? | | CDADAR | Lisp lambda function | list | ? | ? |
| CDADR | Lisp function | (CDADR X) | LAMBDA-fn | ? | | CDADDR | Lisp lambda function | list | ? | ? |
| CDAR | Lisp function | (CDAR X) | LAMBDA-fn | ? | | CDADR | Lisp lambda function | list | ? | ? |
| CDDAAR | Lisp function | (CDDAAR X) | LAMBDA-fn | ? | | CDAR | Lisp lambda function | list | ? | ? |
| CDDADR | Lisp function | (CDDADR X) | LAMBDA-fn | ? | | CDDAAR | Lisp lambda function | list | ? | ? |
| CDDAR | Lisp function | (CDDAR X) | LAMBDA-fn | ? | | CDDADR | Lisp lambda function | list | ? | ? |
| CDDDAR | Lisp function | (CDDDAR X) | LAMBDA-fn | ? | | CDDAR | Lisp lambda function | list | ? | ? |
| CDDDDR | Lisp function | (CDDDDR X) | LAMBDA-fn | ? | | CDDDAR | Lisp lambda function | list | ? | ? |
| CDDDR | Lisp function | (CDDDR X) | LAMBDA-fn | ? | | CDDDDR | Lisp lambda function | list | ? | ? |
| CDDR | Lisp function | (CDDR X) | LAMBDA-fn | ? | | CDDDR | Lisp lambda function | list | ? | ? |
| 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. | | CDDR | Lisp lambda function | list | ? | ? |
| CONS | Host function | (CONS CAR CDR) | | Construct a new instance of cons cell with this `car` and `cdr`. | | CDR | Host lambda function | list | | Return the item indicated by the second pointer of a pair. NIL is treated specially: the CDR of NIL is NIL. |
| 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> | | CONS | Host lambda function | expr, expr | | Construct a new instance of cons cell with this `car` and `cdr`. |
| 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)) | | CONSP | Host lambda function | o:expr | ? | Return `T` if object `o` is a cons cell, else `F`.<br><br>**NOTE THAT** this is an extension function, not available in strict mode. I believe that Lisp 1.5 did not have any mechanism for testing whether an argument was, or was not, a cons cell. |
| DIFFERENCE | Host function | (DIFFERENCE X Y) | | ? | | COPY | Lisp lambda function | ? | | see manual pages <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=62'>62</a> |
| 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> | | DEFINE | Host lambda function | ? | PSEUDO-FUNCTION | Bootstrap-only version of `DEFINE` which, post boostrap, can be overwritten in LISP. The single argument to `DEFINE` should be an association list of symbols to lambda functions. See page <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=58'>58</a> of the manual. |
| ERROR | Host function | (ERROR & ARGS) | PSEUDO-FUNCTION | Throw an error | | DIFFERENCE | Host lambda function | x:number, y:number | | Returns the result of subtracting the number `y` from the number `x` |
| 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`. | | DIVIDE | Lisp lambda function | x:number, y:number | | see manual pages <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=26'>26</a>, <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=64'>64</a> |
| 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` | | DOC | Host lambda function | ? | ? | Open the page for this `symbol` in the Lisp 1.5 manual, if known, in the default web browser.<br><br>**NOTE THAT** this is an extension function, not available in strct mode. |
| 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. | | EFFACE | Lisp lambda function | ? | PSEUDO-FUNCTION | see manual pages <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=63'>63</a> |
| FACTORIAL | Lisp function | (FACTORIAL N) | LAMBDA-fn | ? | | ERROR | Host lambda function | ? | PSEUDO-FUNCTION | Throw an error |
| FIXP | Host function | (FIXP X) | PREDICATE | ? | | EQ | Host lambda function | ? | PREDICATE | Returns `T` if and only if both `x` and `y` are bound to the same atom, else `NIL`. |
| GENSYM | Host function | (GENSYM ) | | Generate a unique symbol. | | EQUAL | Host lambda function | ? | 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` |
| 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> | | EVAL | Host lambda function | ? | | 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. However, if called with just a single arg, `expr`, I'll assume it's being called from the Clojure REPL and will coerce the `expr` to `ConsCell`. |
| GREATERP | Host function | (GREATERP X Y) | PREDICATE | ? | | FACTORIAL | Lisp lambda function | ? | ? | ? |
| 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. | | FIXP | Host lambda function | ? | PREDICATE | ? |
| INTERSECTION | Lisp function | (INTERSECTION X Y) | LAMBDA-fn | ? | | GENSYM | Host lambda function | ? | | Generate a unique symbol. |
| 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> | | GET | Host lambda function | ? | | From the manual: '`get` is somewhat like `prop`; however its value is car of the rest of the list if the `indicator` is found, and NIL otherwise.'<br><br>It's clear that `GET` is expected to be defined in terms of `PROP`, but we can't implement `PROP` here because we lack `EVAL`; and we can't have `EVAL` here because both it and `APPLY` depends on `GET`.<br><br>OK, It's worse than that: the statement of the definition of `GET` (and of) `PROP` on page <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=59'>59</a> says that the first argument to each must be a list; But the in the definition of `ASSOC` on page 70, when `GET` is called its first argument is always an atom. Since it's `ASSOC` and `EVAL` which I need to make work, I'm going to assume that page 59 is wrong. |
| LESSP | Host function | (LESSP X Y) | PREDICATE | ? | | GREATERP | Host lambda function | ? | 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> | | INTEROP | Host lambda function | ? | ? | ? |
| 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> | | INTERSECTION | Lisp lambda function | ? | ? | ? |
| 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> | | LENGTH | Lisp lambda function | ? | | see manual pages <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=62'>62</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> | | LESSP | Host lambda function | ? | PREDICATE | ? |
| NUMBERP | Host function | (NUMBERP X) | PREDICATE | ? | | MAPLIST | Lisp lambda function | ? | FUNCTIONAL | see manual pages <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=20'>20</a>, <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=21'>21</a>, <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=63'>63</a> |
| 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. | | MEMBER | Lisp lambda function | ? | PREDICATE | see manual pages <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=11'>11</a>, <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=62'>62</a> |
| 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> | | MINUSP | Lisp lambda function | ? | PREDICATE | see manual pages <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=26'>26</a>, <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=64'>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> | | NOT | Lisp lambda function | ? | PREDICATE | see manual pages <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=21'>21</a>, <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=23'>23</a>, <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=58'>58</a> |
| PLUS | Host function | (PLUS & ARGS) | | ? | | NULL | Lisp lambda function | ? | PREDICATE | see manual pages <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=11'>11</a>, <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=57'>57</a> |
| PRETTY | Lisp variable | | (PRETTY) | ? | | NUMBERP | Host lambda function | ? | PREDICATE | ? |
| PRINT | Lisp variable | | PSEUDO-FUNCTION | ? | | OBLIST | Host lambda function | ? | | Return a list of the symbols currently bound on the object list.<br><br>**NOTE THAT** in the Lisp 1.5 manual, footnote at the bottom of page <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=69'>69</a>, it implies that an argument can be passed but I'm not sure of the semantics of this. |
| 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> | | ONEP | Lisp lambda function | ? | PREDICATE | see manual pages <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=26'>26</a>, <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=64'>64</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. | | OR | Host lambda function | ? | PREDICATE | `T` if and only if at least one of my `args` evaluates to something other than either `F` or `NIL`, else `F`.<br><br>In `beowulf.host` principally because I don't yet feel confident to define varargs functions in Lisp. |
| RANGE | Lisp variable | ? | (RANGE (LAMBDA (N M) (COND ((LESSP M N) (QUOTE NIL)) ((QUOTE T) (CONS N (RANGE (ADD1 N) M)))))) | ? | | PAIR | Lisp lambda function | ? | | see manual pages <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=60'>60</a> |
| 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. | | PAIRLIS | Lisp lambda function, Host lambda function | ? | ? | This function gives the list of pairs of corresponding elements of the lists `x` and `y`, and APPENDs this to the list `a`. The resultant list of pairs, which is like a table with two columns, is called an association list. Essentially, it builds the environment on the stack, implementing shallow binding.<br><br>All args are assumed to be `beowulf.cons-cell/ConsCell` objects. See page <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=12'>12</a> of the Lisp 1.5 Programmers Manual.<br><br>**NOTE THAT** this function is overridden by an implementation in Lisp, but is currently still present for bootstrapping. |
| REMAINDER | Host function | (REMAINDER X Y) | | ? | | PLUS | Host lambda function | ? | | ? |
| REPEAT | Lisp function | (REPEAT N X) | LAMBDA-fn | ? | | PRETTY | | ? | ? | ? |
| 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) | | PRINT | | ? | PSEUDO-FUNCTION | see manual pages <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=65'>65</a>, <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=84'>84</a> |
| 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) | | PROG | Host nlambda function | ? | | The accursed `PROG` feature. See page <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=71'>71</a> of the manual.<br><br>Lisp 1.5 introduced `PROG`, and most Lisps have been stuck with it ever since. It introduces imperative programming into what should be a pure functional language, and consequently it's going to be a pig to implement. Broadly, `PROG` is a variadic pseudo function called as a `FEXPR` (or possibly an `FSUBR`, although I'm not presently sure that would even work.) The arguments, which are unevaluated, are a list of forms, the first of which is expected to be a list of symbols which will be treated as names of variables within the program, and the rest of which (the 'program body') are either lists or symbols. Lists are treated as Lisp expressions which may be evaulated in turn. Symbols are treated as targets for the `GO` statement. <ul><li>**GO:** A `GO` statement takes the form of `(GO target)`, where `target` should be one of the symbols which occur at top level among that particular invocation of `PROG`s arguments. A `GO` statement may occur at top level in a PROG, or in a clause of a `COND` statement in a `PROG`, but not in a function called from the `PROG` statement. When a `GO` statement is evaluated, execution should transfer immediately to the expression which is the argument list immediately following the symbol which is its target. If the target is not found, an error with the code `A6` should be thrown.</li><li>**RETURN:** A `RETURN` statement takes the form `(RETURN value)`, where `value` is any value. Following the evaluation of a `RETURN` statement, the `PROG` should immediately exit without executing any further expressions, returning the value.</li><li>**SET and SETQ:** In addition to the above, if a `SET` or `SETQ` expression is encountered in any expression within the `PROG` body, it should affect not the global object list but instead only the local variables of the program.</li><li>**COND:** In **strict** mode, when in normal execution, a `COND` statement none of whose clauses match should not return `NIL` but should throw an error with the code `A3`... *except* that inside a `PROG` body, it should not do so. *sigh*.</li></ul>**Flow of control:** Apart from the exceptions specified above, expressions in the program body are evaluated sequentially. If execution reaches the end of the program body, `NIL` is returned.<br><br>Got all that? Good. |
| 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! | | PROP | Lisp lambda function | ? | FUNCTIONAL | see manual pages <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=59'>59</a> |
| 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> | | QUOTE | Lisp lambda function | ? | | see manual pages <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=10'>10</a>, <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=22'>22</a>, <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=71'>71</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. | | QUOTIENT | Host lambda function | ? | | 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. |
| 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. | | RANGE | Lisp lambda function | ? | ? | ? |
| TERPRI | Lisp variable | | PSEUDO-FUNCTION | ? | | READ | Host lambda function | ? | 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. |
| TIMES | Host function | (TIMES & ARGS) | | ? | | REMAINDER | Host lambda function | ? | | ? |
| 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. | | REPEAT | Lisp lambda function | ? | ? | ? |
| UNTRACE | Host function | (UNTRACE S) | PSEUDO-FUNCTION | ? | | RPLACA | Host lambda function | ? | 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) |
| 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> | | RPLACD | Host lambda function | ? | 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) |
| SEARCH | Lisp lambda function | ? | FUNCTIONAL | see manual pages <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=63'>63</a> |
| SET | Host lambda function | ? | PSEUDO-FUNCTION | Implementation of SET in Clojure. Add to the `oblist` a binding of the value of `var` to the value of `val`.<br><br>**NOTE WELL**: this is not SETQ! |
| SUB1 | Lisp lambda function, Host lambda function | ? | | ? |
| SUB2 | Lisp lambda function | ? | ? | ? |
| SUBLIS | Lisp lambda function | ? | | see manual pages <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=12'>12</a>, <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=61'>61</a> |
| SUBST | Lisp lambda function | ? | | see manual pages <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=11'>11</a>, <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=61'>61</a> |
| SYSIN | Host lambda function | ? | ? | 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.<br><br>**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.<br><br>**NOTE THAT** this is an extension function, not available in strct mode. |
| SYSOUT | Host lambda function | ? | ? | 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.<br><br>**NOTE THAT** this is an extension function, not available in strict mode. |
| TERPRI | | ? | PSEUDO-FUNCTION | see manual pages <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=65'>65</a>, <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=84'>84</a> |
| TIMES | Host lambda function | ? | | ? |
| TRACE | Host lambda function | ? | PSEUDO-FUNCTION | Add this `s` to the set of symbols currently being traced. If `s` is not a symbol or sequence of symbols, does nothing. |
| UNION | Lisp lambda function | ? | ? | ? |
| UNTRACE | Host lambda function | ? | PSEUDO-FUNCTION | Remove this `s` from the set of symbols currently being traced. If `s` is not a symbol or sequence of symbols, does nothing. |
| ZEROP | Lisp lambda function | ? | PREDICATE | see manual pages <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=26'>26</a>, <a href='https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=64'>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
@ -145,8 +216,7 @@ over the Clojure implementations.
### Architectural plan ### Architectural plan
Not everything documented in this section is yet built. It indicates the Not everything documented in this section is yet built. It indicates the direction of travel and intended destination, not the current state.
direction of travel and intended destination, not the current state.
#### resources/lisp1.5.lsp #### resources/lisp1.5.lsp
@ -195,19 +265,6 @@ Intended deviations from the behaviour of the real Lisp reader are as follows:
a comment, as most modern Lisps do; but I do not believe Lisp 1.5 had a comment, as most modern Lisps do; but I do not believe Lisp 1.5 had
this feature. this feature.
### BUT WHY?!!?!
Because.
Because Lisp is the only computer language worth learning, and if a thing
is worth learning, it's worth learning properly; which means going back to
the beginning and trying to understand that.
Because there is, so far as I know, no working implementation of Lisp 1.5
for modern machines.
Because I'm barking mad, and this is therapy.
### Commentary ### Commentary
What's surprised me in working on this is how much more polished Lisp 1.5 is What's surprised me in working on this is how much more polished Lisp 1.5 is
@ -225,11 +282,19 @@ but this is software which is almost sixty years old).
## Installation ## Installation
At present, clone the source and build it using Download the latest [release 'uberjar'](https://github.com/simon-brooke/beowulf/releases) and run it using:
`lein uberjar`. ```bash
java -jar <path name of uberjar>
```
You will require to have [Leiningen](https://leiningen.org/) installed. Or clone the source and build it using:
```bash
lein uberjar`
```
To build it you will require to have [Leiningen](https://leiningen.org/) installed.
### Input/output ### Input/output
@ -262,7 +327,14 @@ processors, but I failed to find the Lisp source of Lisp functions as a text
file, which is why `resources/lisp1.5.lsp` is largely copytyped and file, which is why `resources/lisp1.5.lsp` is largely copytyped and
reconstructed from the manual. reconstructed from the manual.
I'm not at this time aware of any other working Lisp 1.5 implementations. ### Other implementations
There's an online (browser native) Lisp 1.5 implementation [here](https://pages.zick.run/ichigo/) (source code [here](https://github.com/zick/IchigoLisp)). It
even has a working compiler!
### History resources
I'm compiling a [list of links to historical documents on Lisp 1.5](https://simon-brooke.github.io/beowulf/docs/further_reading.html).
## License ## License

View file

@ -1,7 +1,16 @@
# Further Reading # Further Reading
1. [CODING for the MIT-IBM 704 COMPUTER, October 1957](http://bitsavers.org/pdf/mit/computer_center/Coding_for_the_MIT-IBM_704_Computer_Oct57.pdf) 1. [CODING for the MIT-IBM 704 COMPUTER, October 1957](http://bitsavers.org/pdf/mit/computer_center/Coding_for_the_MIT-IBM_704_Computer_Oct57.pdf)
This paper is not about Lisp. But it is about the particular individual computer on which Lisp was first implemented, and it is written in part by members of the Lisp team. I have found it useful in understanding the software environment in which, and the constraints under which, Lisp was written.
2. [MIT AI Memo 1, John McCarthy, September 1958](https://www.softwarepreservation.org/projects/LISP/MIT/AIM-001.pdf) 2. [MIT AI Memo 1, John McCarthy, September 1958](https://www.softwarepreservation.org/projects/LISP/MIT/AIM-001.pdf)
This is, as far as I can find, the earliest specification document of the Lisp project.
3. [Lisp 1 Programmer's Manual, Phyllis Fox, March 1960](https://bitsavers.org/pdf/mit/rle_lisp/LISP_I_Programmers_Manual_Mar60.pdf) 3. [Lisp 1 Programmer's Manual, Phyllis Fox, March 1960](https://bitsavers.org/pdf/mit/rle_lisp/LISP_I_Programmers_Manual_Mar60.pdf)
4. [Lisp 1.5 Programmer's Manual, Michael I. Levin, August 1962](https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=81) 4. [Lisp 1.5 Programmer's Manual, Michael I. Levin, August 1962](https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=81)
This book is essential reading: it documents in some detail the first fully realised Lisp language system.
5. [Early LISP History (1956 - 1959), Herbert Stoyan, August 1984](https://dl.acm.org/doi/pdf/10.1145/800055.802047#page=3) 5. [Early LISP History (1956 - 1959), Herbert Stoyan, August 1984](https://dl.acm.org/doi/pdf/10.1145/800055.802047#page=3)
6. [The Roots of Lisp, Paul Graham, 2001](http://www.paulgraham.com/rootsoflisp.html)
6. [The Revenge of the Nerds, Paul Graham, 2002](http://www.paulgraham.com/icad.html)
This is mainly about why to use Lisp as a language for modern commercial software, but has useful insights into where it comes from.
> So the short explanation of why this 1950s language is not obsolete is that it was not technology but math, and math doesn't get stale.

View file

@ -5,10 +5,10 @@
**Massachusetts Institute of Technology** **Massachusetts Institute of Technology**
> John McCarthy > [John McCarthy](https://en.wikipedia.org/wiki/John_McCarthy_(computer_scientist))
> Paul W. Abrahams > [Paul W. Abrahams](https://mitpress.mit.edu/author/paul-w-abrahams-31449/)
> Daniel J. Edwards > [Daniel J. Edwards](https://www.chessprogramming.org/Daniel_Edwards)
> Timothy P. Hart > [Timothy P. Hart](https://www.chessprogramming.org/Timothy_Hart)
> The M. I.T. Press > The M. I.T. Press
> Massachusetts Institute of Technology > Massachusetts Institute of Technology
@ -43,11 +43,11 @@ The over-all design of the LISP Programming System is the work of John McCarthy
This manual was written by Michael I. Levin. This manual was written by Michael I. Levin.
The interpreter was programmed by Stephen B. Russell and Daniel J. Edwards. The print and read programs were written by John McCarthy, Klim Maling, Daniel J. Edwards, and Paul W, Abrahams. The interpreter was programmed by [Stephen B. Russell](https://en.wikipedia.org/wiki/Steve_Russell_(computer_scientist)) and Daniel J. Edwards. The print and read programs were written by John McCarthy, Klim Maling, Daniel J. Edwards, and Paul W. Abrahams.
The garbage collector and arithmetic features Were written by Daniel J. Edwards. The compiler and assembler were written by Timothy P. Hart and Michael I. Levin. An earlier compiler was written by Robert Brayton. The garbage collector and arithmetic features Were written by Daniel J. Edwards. The compiler and assembler were written by Timothy P. Hart and Michael I. Levin. An earlier compiler was written by Robert Brayton.
The "LISP 1 Programmer's Manual" March 1, 1960, was written by Phyllis A. Fox. Additional programs and suggestions were contributed by the following members of the Artificial Intelligence Group of the Research Laboratory of Electronics: Marvin L. Minsky, Bertram Raphael, Louis Hodes, David M. R. Park, David C. Luckham, Daniel G. Bobrow, James R. Slagle, and Nathaniel Rochester. The "LISP 1 Programmer's Manual" March 1, 1960, was written by [Phyllis A. Fox](https://en.wikipedia.org/wiki/Phyllis_Fox). Additional programs and suggestions were contributed by the following members of the Artificial Intelligence Group of the Research Laboratory of Electronics: Marvin L. Minsky, Bertram Raphael, Louis Hodes, David M. R. Park, David C. Luckham, Daniel G. Bobrow, James R. Slagle, and Nathaniel Rochester.
August 17, 1962 August 17, 1962
@ -2816,13 +2816,14 @@ Note that the following M-expression is different from that given in Section I,
the result is the same. the result is the same.
``` ```
sublis[x;y] [null[x] -- y; sublis[x;y] = [null[x] -> y;
null[y] -- y; null[y] -> y;
T -. search[x; T -> search[x;
k[[j]; equal[y;caar[j]]]; lambda[[j]; equal[y;caar[j]]];
k[[j]; cdar[j]]; lambda[[j]; cdar[j]];
k[[j];[atom[y] - y; lambda[[j]; [atom[y] -> y;
T -c cons [sublis [x;car [y]];sublis [x;cdr [y]]]]]]] T -> cons[sublis[x; car[y]];
sublis[x; cdr[y]]]]]]]
``` ```
### List Handling Functions ### List Handling Functions
@ -3291,127 +3292,136 @@ NIL
by performing by performing
EVAL (OBLIST NIL). EVAL (OBLIST NIL).
<a name="page70">page 70</a>
## APPENDIX B : THE LISP INTERPRETER ## APPENDIX B : THE LISP INTERPRETER
This appendix is written in mixed M-expressions and English. Its purpose is to This appendix is written in mixed M-expressions and English. Its purpose is to describe as closely as possible the actual working of the interpreter and PROG feature. The functions `evalquote`, `apply`, `eval`, `evlis`, `evcon`, and the `PROG` feature are defined by using a language that follows the M-expression notation as closely as possible and contains some insertions in English.
describe as closely as possible the actual working of the interpreter and PROG feature.
The functions evalquote, ---- apply, eval, evlis, evcon, and the PROG feature are defined
by using a language that follows the M-expression notation as closely as possible and
contains some insertions in English.
###### evalquote[fn;args]=[get [fn; FEXPR] vget [fn; FSUBR] - ```mexpr
evalquote[fn; args]=[get[fn; FEXPR] v get[fn; FSUBR] -> eval[cons [ fn; args]; NIL];
T -> apply[fn; args; NIL]
```
eval[cons [ fn; args]; NIL] This definition shows that `evalquote` is capable of handling special forms as a sort of exception. Apply cannot handle special forms and will give error `A2` if given one as its first argument.
The following definition of `apply` is an enlargement of the one given in Section I. It shows how functional arguments bound by FUNARG are processed, and describes the way in which machine language subroutines are called.
In this description, `spread` can be regarded as a pseudo-function of one argument. This argument is a list. `spread` puts the individual items of this list into the AC, MQ,
$ARG3,... the standard cells *[general purpose registers]* for transmitting arguments to functions.
This definition shows that evalquote is capable of handling special forms as a sort
of exception. Apply cannot handle special forms and will give error A2 if given one as
its first argument.
The following definition'of apply is an enlargement of the one given in Section I. It
shows how functional arguments bound by FUNARG are processed, and describes the
way in which machine language subroutines are called.
In this description, spread can be regarded as a pseudo-function of one argument.
This argument is a list. spread puts the individual items of this list into the AC, MQ,
$ARG3,... the standard cells for transmitting arguments to functions.
These M-expressions should not be taken too literally. In many cases, the actual These M-expressions should not be taken too literally. In many cases, the actual
program is a store and transfer where a recursion is suggested by these definitions. program is a store and transfer where a recursion is suggested by these definitions.
```mexpr
apply[fn; args; a]=[ apply[fn; args; a]=[
null [fn]-NIL; null[fn] -> NIL;
at ~rn[fn]-[~et [fn; EXPR]-~~~~~ [expr^1 ; args ; a]; atom[fn] -> [get[fn; EXPR] -> apply[expr ; args ; a];
spread[args]; get[fn; subr] -> {spread[args];
$ALIST := a;
TSX subr, 4};
T -> apply[cdr[sassoc[fn; a; lambda[[];error [A2]]]]; args ;a];
eq[car[fn]; LABEL] -> apply[caddr[fn];args;
cons[cons[cadr[fn];
caddr[fn]];a]];
eq[car[fn]; FUNARG] -> apply[cadr[fn]; args; caddr[fn]];
eq[car [fn]; LAMBDA] -> eval[caddr[fn];
nconc [pair[cadr[fn]; args]; a]];
T -> apply[eval[fn; a]; args; a]]
```
*NOTE THAT the formatting of this MEXPR is beyond the capabilities of Markdown to reproduce; this is a rational reconstruction, but to be perfectly certain of the interpretation consult the PDF*
T-apply[cdr[sassoc [fn;a;~[[];error [~2]]]];ar~s ;a];
eq[car[fn]; ~~~~~]-a~~l~[caddr[fn];ar~s;cons[cons[cadr[fn];caddr[fn]];a]];
eq[car[fn]; ~~~~~~]-a~~1~[cadr [fn]; args; caddr [fn]];
eq[car [fn]; LAMBDA]-eval[caddr[fn]; nconc [pair[cadr[fn]; args]; a]];
~-a~~ly[eval[fn;a];ar~s ;a]]
1. The value of get is set aside. This is the meaning of the apparent free or unde-
fined variable -
* eval[f orm; a]= [ -----
null[f orm]-NIL;
numberp[f orm]-f orm;
atom[form]-[get[f O~~;APVAL]-car [apval^1 1;
~~cdr[sassoc[form;a;~[[ ];error[A8]]]]];
eq[car[f O~~];QUOTE]-cadr [form]; 2
eq[car [form]; FUNCTION]-~~~~[FUNARG; cadr [form];a];
eq[car [form]; COND]-evcon[cdr[form]; a];
eq[car [form]; ~~OG]-~ro~[cdr [form]; a];
atom[car[form]] -[get[car [form];~~~~]-~a~~l~[ex~r;^1 evlis[cdr lforrn];a];a];
get[car[form];~~~~~]-apply[fexpr !list[cdr [form];a];a];
spread[evlis [cdr [form]; a]];
get[car[form];~~~~]-
TSX subr f 4
AC: =cdr [ form];
get[car[form];F~u~R]-, MQ: = $ALIST: =a; ;
# (TSx fsubr!4 } 1. The value of get is set aside. This is the meaning of the apparent free or undefined variable.
~-e~al[~0ns[cdr[sas~0~[car[form];a;~[[];error[~9]]]]; <a name="page71">page 71</a>
```mexpr
eval[form; a]= [
null[form] -> NIL;
numberp[form] -> form;
atom[form] -> [get[form; APVAL] -> car[apval];
T -> cdr[sassoc[form; a; lambda[[ ]; error[A8]]]]];
eq[car[form]; QUOTE] -> cadr[form];
eq[car[form]; FUNCTION] -> list[FUNARG; cadr[form]; a];
eq[car [form]; COND] -> evcon[cdr[form]; a];
eq[car [form]; PROG] -> prog[cdr[form]; a];
atom[car[form]] -> [get[car [form]; EXPR] ->
apply[expr; evlis[cdr[form]; a]; a];
get[car[form]; FEXPR] ->
apply[fexpr; list[cdr[form]; a]; a];
get[car[form]; SUBR] -> {spread[evlis[cdr[form]; a]];
$ALIST := a;
TSX subr 4};
get[car[form]; FSUBR] -> {AC := cdr[form];
MQ := $ALIST := a;
TSX fsubr 4}
T -> eval[cons[cdr[sassoc[car[form]; a;
lambda[[];error[A9]]]];
cdr[form]]; a]]; cdr[form]]; a]];
T-apply [car [form];evlis [cdr [form]; a]; a]] T-apply [car [form];evlis [cdr [form]; a]; a]]
evcon[c; a]= [null[c]--error [A3];
eval[caar[ c]; a]-eval[cadar [a];a]; evcon[c; a] = [null[c] -> error[A3];
T-evcon[cdr [ c];a]] eval[caar[c]; a] -> eval[cadar[a]; a];
evlis[ - m; a] =maplist [m; ~[[j]; eval[car[j]; a]]] T -> evcon[cdr[ c]; a]]
The PROG Feature
evlis[m; a] = maplist[m; lambda[[j]; eval[car[j]; a]]]
```
### The PROG Feature
The PROG feature is an FSUBR coded into the system. It can best be explained in The PROG feature is an FSUBR coded into the system. It can best be explained in
English, although it is possible to define it by using M-expressions. English, although it is possible to define it by using M-expressions.
1. As soon as the PROG feature is entered, the list of program variables is used 1. As soon as the PROG feature is entered, the list of program variables is used
to make a new list in which each one is paired with NIL. This is then appended to the to make a new list in which each one is paired with NIL. This is then appended to the current a-list. Thus each program variable is set to NIL at the entrance to the program.
current a-list. Thus each program variable is set to NIL at the entrance to the program.
2. The remainder of the program is searched for atomic symbols that are under- 2. The remainder of the program is searched for atomic symbols that are under-
stood to be location symbols. A go-list is formed in which each location symbol is stood to be location symbols. A go-list is formed in which each location symbol is paired with a pointer into the remainder of the program.
paired with a pointer into the remainder of the program. 3. When a set or a setq - is encountered, the name of the variable is located on the a-list. The value of the variable (or cdr of the pair) is actually replaced with the new value.
3. When a set or a setq - is encountered, the name of the variable is located on the
a-list. The value of the variable (or cs of the pair) is actually replaced with the new
value.
1. The value of get is set aside. This is the meaning of the apparent free or unde-
fined variable-
2. In the actual system this is handled by an FSUBR rather than as the separate special
case as shown here.
If the variable is bound several times on the a-list, only the first or most recent -----
occurrence is changed. If the current binding of the variable is at a higher level than 1. The value of get is set aside. This is the meaning of the apparent free or undefined variable.
the entrance to the prog, then the change will remain in effect throughout the scope 2. In the actual system this is handled by an FSUBR rather than as the separate special case as shown here.
of that binding, and the old value will be lost.
If the variable does not occur on the a-list, then error diagnostic A4 or A5 will
occur.
4. When a return is encountered at any point, its argument is evaluated and returned <a name="page72">page 72</a>
as the value of the most recent prog that has been entered.
If the variable is bound several times on the a-list, only the first or most recent occurrence is changed. If the current binding of the variable is at a higher level than the entrance to the prog, then the change will remain in effect throughout the scope of that binding, and the old value will be lost.
If the variable does not occur on the a-list, then error diagnostic `A4` or `A5` will occur.
4. When a return is encountered at any point, its argument is evaluated and returned as the value of the most recent prog that has been entered.
5. The form go may be used only in two ways. 5. The form go may be used only in two ways.
a. (GO X) may occur on the top level of the prog, x must be a location symbol a. `(GO X)` may occur on the top level of the prog, `x` must be a location symbol of this `prog` and not another one on a higher or lower level.
of this prog and not another one on a higher or lower level. b. This form may also occur as one of the value parts of a conditional expression, if this conditional expression occurs on the top level of the `prog`.
b. This form may also occur as one of the value parts of a conditional expres- If a `go` is used incorrectly or refers to a nonexistent location, error diagnostic `A6` will occur.
sion, if this conditional expression occurs on the top level of the prog.
If a go - is used incorrectly or refers to a nonexistent location, error diagnostic A6 6. When the form cond occurs on the top level of a `prog`, it differs from other
will occur. `cond`s in the following ways.
6. When the form cond occurs on the top level of a prog, it differs from other a. It is the only instance in which a `go` can occur inside a `cond`.
conds in the following ways. b. If the `cond` runs out of clauses, error diagnostic `A3` will not occur. Instead, the `prog` will continue with the next statement.
a. It is the only instance in which a gocan occur inside a cond.
b. If the cond runs out of clauses, error diagnostic A3 will not occur. Instead,
the prog will c6ntinue with the next statement.
7. When a statement is executed, this has the following meaning, with the exception 7. When a statement is executed, this has the following meaning, with the exception
of the special forms cond, go, return, setq and the pseudo-functionset, all of which of the special forms `cond`, `go`, `return`, `setq` and the pseudo-function `set`, all of which are peculiar to `prog`.
are peculiar to prog. The statement `s` is executed by performing `eval[s;a]`, where `a` is the current a-list, and then ignoring the value.
The statement 5 is executed by performing eval[s;a], where 2 is the current a-list,
and then ignoring the value.
8. If a prog runs out of statements, its value is NIL. 8. If a prog runs out of statements, its value is NIL.
When a prog - is compiled, it will have the same effect as when it is interpreted, When a prog - is compiled, it will have the same effect as when it is interpreted, although the method of execution is much different; for example, a go is always cornpiled as a transfer. The following points should be noted concerning declared variables.<sup>1</sup>
although the method of execution is much different; for example, a go is always corn-
piled as a transfer. The following points should be noted concerning declared variables.^1
1. Program variables follow the same rules as h variables do. 1. Program variables follow the same rules as h variables do.
a. If a variable is purely local, it need not be declared. a. If a variable is purely local, it need not be declared.
b. Special variables can be used as free variables in compiled functions. They b. Special variables can be used as free variables in compiled functions. They may be set at a lower level than that at which they are bound.
may be set at a lower level than that at which they are bound. c. Common program variables maintain complete communication between compiled programs and the interpreter.
c. Common program variables maintain complete communication between com-
piled programs and the interpreter.
2. & as distinct from setq can only be used to set common variables. 2. & as distinct from setq can only be used to set common variables.
-----
1. See Appendix D for an explanation of variable declaration. 1. See Appendix D for an explanation of variable declaration.
APPENDIX C : THE LISP ASSEMBLY PROGRAM (LAP) <a name="page73">page 73</a>
## APPENDIX C : THE LISP ASSEMBLY PROGRAM (LAP)
lap is a two-pass assembler. It was specifically designed for use by the new com- lap is a two-pass assembler. It was specifically designed for use by the new com-
piler, but it can also be used for defining functions in machine language, and for making piler, but it can also be used for defining functions in machine language, and for making
@ -3455,6 +3465,9 @@ FSUBR. n is the number of arguments which the subroutine expects.
Symbols Symbols
Atomic symbols appearing on the listing (except NIL or the first item on the listing) Atomic symbols appearing on the listing (except NIL or the first item on the listing)
<a name="page74">page 74</a>
are treated as location symbols. The appearance of the symbol defines it as the location are treated as location symbols. The appearance of the symbol defines it as the location
of the next instruction in the listing. During pass one, these symbols and their values of the next instruction in the listing. During pass one, these symbols and their values
are made into a pair list, and appended to the initial symbol table to form the final sym- are made into a pair list, and appended to the initial symbol table to form the final sym-
@ -3500,6 +3513,8 @@ literal will not be created if it is equal to one that already exists.
4. If the field is of the form (SPECIAL x), then the value is the address of the 4. If the field is of the form (SPECIAL x), then the value is the address of the
SPECIAL cell on the property list of x. If one does not already exist, it will be created. SPECIAL cell on the property list of x. If one does not already exist, it will be created.
<a name="page75">page 75</a>
The SPECIAL cell itself (but not the entire atom) is protected against garbage collection. The SPECIAL cell itself (but not the entire atom) is protected against garbage collection.
5. In all other cases, the field is assumed to be a list of subfields, and their sum 5. In all other cases, the field is assumed to be a list of subfields, and their sum
@ -3566,8 +3581,10 @@ LAP ( (6217Q (TRA NIL) )NIL)
LAP ( (NIL (CLA A) (TSX 6204Q) (TRA B) ) LAP ( (NIL (CLA A) (TSX 6204Q) (TRA B) )
( (A 6243Q) (B 6220Q) ) ) ( (A 6243Q) (B 6220Q) ) )
APPENDIX D <a name="page76">page 76</a>
THE LISP COMPILER
## APPENDIX D : THE LISP COMPILER
The LISP Compiler is a program written in LISP that translates S-expression defi- The LISP Compiler is a program written in LISP that translates S-expression defi-
nitions of functions into machine language subroutines. It is an optional feature that nitions of functions into machine language subroutines. It is an optional feature that
makes programs run many times faster than they would if they were to be interpreted makes programs run many times faster than they would if they were to be interpreted
@ -3580,12 +3597,13 @@ space. Thus an EXPR, or an FEXPR, has been changed to a SUBR or an FSUBR,
respectively. respectively.
Experience has shown that compiled programs run anywhere from 10 to 100 times Experience has shown that compiled programs run anywhere from 10 to 100 times
as fast as interpreted programs, the time depending upon the nature of the program. as fast as interpreted programs, the time depending upon the nature of the program.
Compiled programs are also more economical with memory than their corresponding 1 Compiled programs are also more economical with memory than their corresponding
S-expressions, taking only from 50 per cent to 80 per cent as much space.' S-expressions, taking only from 50 per cent to 80 per cent as much space.<sup>1</sup>
The major part of the compiler is a translator or function from the S-expression The major part of the compiler is a translator or function from the S-expression
function notation into the assembly language, LAP. The only reasons why the compiler function notation into the assembly language, LAP. The only reasons why the compiler
is regarded as a pseudo-function are that it calls LAP, and it removes EXPRts and is regarded as a pseudo-function are that it calls LAP, and it removes EXPRts and
FEXPR1s when it has finished compiling. FEXPR1s when it has finished compiling.
The compiler has an interesting and perhaps unique history. It was developed in The compiler has an interesting and perhaps unique history. It was developed in
the following steps: the following steps:
@ -3600,18 +3618,20 @@ tape is created, the entire compiler was punched out in assembly language by usi
punc hlap. punc hlap.
4. When a system tape is to be made, the compiler in assembly language is read 4. When a system tape is to be made, the compiler in assembly language is read
in by using readlap. in by using readlap.
The compiler is called by using the pseudo-function compile. The argument of com-
- pile is a list of the names of functions to be compiled. Each atomic symbol on this list The compiler is called by using the pseudo-function compile. The argument of compile is a list of the names of functions to be compiled. Each atomic symbol on this list
should have either an EXPR or an FEXPR on its property list before being compiled. should have either an EXPR or an FEXPR on its property list before being compiled.
The processing of each function occurs in three steps. First, the S-expression for The processing of each function occurs in three steps. First, the S-expression for
the function is translated into assembly language. If no S-expression is found, then the the function is translated into assembly language. If no S-expression is found, then the
compiler will print this fact and proceed with the next function. Second, the assembly compiler will print this fact and proceed with the next function. Second, the assembly
-----
1. Since the compiled program is binary program space, which is normally 1. Since the compiled program is binary program space, which is normally
not otherwise accessible, one gains as free storage the total space formerly occupied not otherwise accessible, one gains as free storage the total space formerly occupied
by the S-expression definition. by the S-expression definition.
<a name="page77">page 77</a>
language program is assembled by LAP. Finally, if no error has occurred, then the language program is assembled by LAP. Finally, if no error has occurred, then the
EXPR or FEXPR is removed from the property list. When certain errors caused by EXPR or FEXPR is removed from the property list. When certain errors caused by
undeclared free variables occur, the compiler will print a diagnostic and continue. undeclared free variables occur, the compiler will print a diagnostic and continue.
@ -3658,6 +3678,8 @@ When a variable is used free, it must have been bound by a higher level function
If a program is being run interpretively, and a free variable is used without having been If a program is being run interpretively, and a free variable is used without having been
bound on a higher level, error diagnostic *A^89 will occur. bound on a higher level, error diagnostic *A^89 will occur.
<a name="page78">page 78</a>
If the program is being run compiled, the diagnostic may not occur, and the variable If the program is being run compiled, the diagnostic may not occur, and the variable
may have value NIL. may have value NIL.
There are three types of variables in compiled functions: ordinary variables, There are three types of variables in compiled functions: ordinary variables,
@ -3699,6 +3721,8 @@ Consider the following definition of a function dot by using an S-expression:
(YDOT (LAMBDA (X Y) (MAPLIST X (FUNCTION (YDOT (LAMBDA (X Y) (MAPLIST X (FUNCTION
(LAMBDA (J) (CONS (CAR J) Y)) )))) (LAMBDA (J) (CONS (CAR J) Y)) ))))
<a name="page79">page 79</a>
Following the word FUNCTION is a functional constant. If we consider it as a sep- Following the word FUNCTION is a functional constant. If we consider it as a sep-
arate function, it is evident that it contains a bound variable "Jtt, and a free variable arate function, it is evident that it contains a bound variable "Jtt, and a free variable
"Yfl. This free variable must be declared SPECIAL or COMMON, even though it is "Yfl. This free variable must be declared SPECIAL or COMMON, even though it is
@ -3733,6 +3757,8 @@ form the instruction TSX and plant this on top of the STR.
2. Once a direct TSX link is made, this particular calling point will not be traced. 2. Once a direct TSX link is made, this particular calling point will not be traced.
(Link will not make a TSX as long as the called function is being traced. ) (Link will not make a TSX as long as the called function is being traced. )
<a name="page80">page 80</a>
## APPENDIX E : OVERLORD - THE MONITOR ## APPENDIX E : OVERLORD - THE MONITOR
Overlord is the monitor of the LISP System. It controls the handling of tapes, the Overlord is the monitor of the LISP System. It controls the handling of tapes, the
@ -3773,6 +3799,8 @@ card columns to use are as follows.
address data word address data word
<a name="page81">page 81</a>
Overlord cards have the Overlord direction beginning in column 8. If the card has Overlord cards have the Overlord direction beginning in column 8. If the card has
no other field, then comments may begin in column 16. Otherwise, the other fields of no other field, then comments may begin in column 16. Otherwise, the other fields of
the card begin in column 16 and are separated by commas. The comments may begin the card begin in column 16 and are separated by commas. The comments may begin
@ -3833,6 +3861,8 @@ Causes the computer to halt. An end of file mark is written on SYSPOT. An end
of file is written on SYSPPT only if it has been used. If the FIN card was read on-line, of file is written on SYSPPT only if it has been used. If the FIN card was read on-line,
the computer halts after doing these things. If the FIN card came from SYSPIT, then the computer halts after doing these things. If the FIN card came from SYSPIT, then
<a name="page82">page 82</a>
SYSPIT is advanced past the next end of file mark before the halt occurs. SYSPIT is advanced past the next end of file mark before the halt occurs.
Use of Sense Switches Use of Sense Switches
@ -3856,6 +3886,8 @@ become a system tape containing the basic system plus any changes that have been
onto it. It may be mounted on the SYSTAP drive for some future run to use definitions onto it. It may be mounted on the SYSTAP drive for some future run to use definitions
that have been set onto it. that have been set onto it.
<a name="page83">page 83</a>
## APPENDIX F : LISP INPUT AND OUTPUT ## APPENDIX F : LISP INPUT AND OUTPUT
This appendix describes the LISP read and write programs and the character- This appendix describes the LISP read and write programs and the character-
@ -3897,6 +3929,8 @@ b. The first two characters must not be $ $.
c. It must be delimited on either side by a character from class C. c. It must be delimited on either side by a character from class C.
There is a provision for reading in atomic symbols containing arbitrary characters. There is a provision for reading in atomic symbols containing arbitrary characters.
<a name="page84">page 84</a>
This is done by punching the form $$dsd, where s is any string of up to 30 characters, This is done by punching the form $$dsd, where s is any string of up to 30 characters,
and d is any character not contained in the string s. Only the string s is used in and d is any character not contained in the string s. Only the string s is used in
forming the print name of the atomic symbol; d and the dollar signs will not appear when forming the print name of the atomic symbol; d and the dollar signs will not appear when
@ -3940,6 +3974,9 @@ to Z. Each letter is a legitimate atomic symbol, and therefore may be referred t
a straightforward way, without ambiguity. a straightforward way, without ambiguity.
The second group of legal characters consists of the digits from 0 to 9. These The second group of legal characters consists of the digits from 0 to 9. These
must be handled with some care because if a digit is considered as an ordinary integer must be handled with some care because if a digit is considered as an ordinary integer
<a name="page85">page 85</a>
rather than a character a new nonunique object will be created corresponding to it, and rather than a character a new nonunique object will be created corresponding to it, and
this object will not be the same as the character object for the same digit, even though this object will not be the same as the character object for the same digit, even though
it has the same print name. Since the character-handling programs depend on the char- it has the same print name. Since the character-handling programs depend on the char-
@ -3992,6 +4029,8 @@ Examples
EVAL (DOLLAR NIL) value is " $ EVAL (DOLLAR NIL) value is " $
EVAL ((PRINT PERIOD) NIL) value is ". and If. is also printed. EVAL ((PRINT PERIOD) NIL) value is ". and If. is also printed.
<a name="page86">page 86</a>
The remaining characters are all illegal as far as the key punch is concerned. The The remaining characters are all illegal as far as the key punch is concerned. The
two characters corresponding to 12 and 72 have been reserved for end-of-file and end- two characters corresponding to 12 and 72 have been reserved for end-of-file and end-
of-record, respectively, The end-of-file character has print name $EOF$ and the end- of-record, respectively, The end-of-file character has print name $EOF$ and the end-
@ -4036,6 +4075,8 @@ whose print name is in BOFFO.
sented by the sequence of characters in BOFFO. (Positive decimal integers from sented by the sequence of characters in BOFFO. (Positive decimal integers from
0 to 9 are converted so as to point to the corresponding character object. ) 0 to 9 are converted so as to point to the corresponding character object. )
<a name="page87">page 87</a>
5. unpack [x]: SUBR pseudo-function 5. unpack [x]: SUBR pseudo-function
This function has as argument a pointer to a full word. unpack considers This function has as argument a pointer to a full word. unpack considers
the full word to be a set of 6 BCD characters, and has as value a list of these the full word to be a set of 6 BCD characters, and has as value a list of these
@ -4074,9 +4115,10 @@ an object). There is also an object CHARCOUNT whose value is an integer object g
the column just read on the card, i. e., the column number of the character given by the column just read on the card, i. e., the column number of the character given by
CURCHAR. There are three functions which affect the value of CURCHAR: CURCHAR. There are three functions which affect the value of CURCHAR:
1. startread [ 1: : SUBR ps eudo-function #### 1. startread [ ] : SUBR ps eudo-function
startread is a function of no arguments which causes a new card to be read. startread is a function of no arguments which causes a new card to be read. The value of startread is the first character on that card, or more precisely,
The value of startread is the first character on that card, or more precisely,
<a name="page88">page 88</a>
the object corresponding to the first character on the card. If an end-of-file the object corresponding to the first character on the card. If an end-of-file
condition exists, the value of startread is $EOF$. The value of CURCHAR condition exists, the value of startread is $EOF$. The value of CURCHAR
@ -4085,35 +4127,30 @@ becomes 1. Both CURCHAR and CHARCOUNT are undefined until a startread
is performed. A startread may be performed before the current card has been is performed. A startread may be performed before the current card has been
completely read. completely read.
2. advance [ 1: SUBR pseudo -function #### 2. advance [ ] : SUBR pseudo -function
advance is a function of no arguments which causes the next character to be
read. The value of advance is that character. After the 72nd character on the
card has been read, the next advance will have value $EOR$. After reading
$EOR$, the next advance will act like a startread, i. e., will read the first char-
acter of the next card unless an end-of-file condition exists. The new value of
CURCHAR is the same as the output of advance; executing advance also increases
the value of CHARCOUNT by 1. However, CHARCOUNT is undefined when
CURCHAR is either $EOR $ or $EOF $.
3. endread [ 1: SUBR pseudo-function
endread is a function of no arguments which causes the remainder of the
card to be read and ignored. endread sets CURCHAR to $EOR$ and leaves
CHARCOUNT undefined; the value of endread is always $EOR $. An advance
following endread acts like a startread. If CURCHAR already has value $EOR $
and endread is performed, CURCHAR will remain the same and endread will,
as usual, have value $EOR $.
Diagnostic Function advance is a function of no arguments which causes the next character to be read. The value of advance is that character. After the 72nd character on the card has been read, the next advance will have value $EOR$. After reading $EOR$, the next advance will act like a startread, i. e., will read the first char acter of the next card unless an end-of-file condition exists. The new value of CURCHAR is the same as the output of advance; executing advance also increases the value of CHARCOUNT by 1. However, CHARCOUNT is undefined when CURCHAR is either $EOR $ or $EOF $.
error 1 [ 1: SUBR pseudo-function #### 3. endread [ ] : SUBR pseudo-function
errorL is a function of no arguments and has value NIL. It should be executed
endread is a function of no arguments which causes the remainder of the card to be read and ignored. endread sets CURCHAR to $EOR$ and leaves CHARCOUNT undefined; the value of endread is always $EOR $. An advance following endread acts like a startread. If CURCHAR already has value $EOR $ and endread is performed, CURCHAR will remain the same and endread will, as usual, have value $EOR $.
### Diagnostic Function
#### error 1 [ ]: SUBR pseudo-function
error1 is a function of no arguments and has value NIL. It should be executed
only while reading characters from a card (or tape). Its effect is to mark the char- only while reading characters from a card (or tape). Its effect is to mark the char-
acter just read, i. e., CURCHAR, so that when the end of the card is reached, either acter just read, i. e., CURCHAR, so that when the end of the card is reached, either
by successive advances or by an endread, the entire card is printed out along with by successive advances or by an endread, the entire card is printed out along with
a visual pointer to the defective character. For a line consisting of ABCDEFG fol- a visual pointer to the defective character. For a line consisting of ABCDEFG fol-
lowed by blanks, a pointer to C would look like this: lowed by blanks, a pointer to C would look like this:
```
v v
ABCDEFG ABCDEFG
A A
```
If error 1 is performed an even number of times on the same character, the A will If error 1 is performed an even number of times on the same character, the A will
not appear. If error1 is performed before the first startread or while CURCHAR not appear. If error1 is performed before the first startread or while CURCHAR
has value $EOR $ or $EOF $, it will have no effect. Executing a startread before has value $EOR $ or $EOF $, it will have no effect. Executing a startread before
@ -4122,28 +4159,27 @@ card is considered to have been completed when CURCHAR has been set to $EOR$.
Successive endreads will cause the error l printout to be reprinted. Any number Successive endreads will cause the error l printout to be reprinted. Any number
of characters in a given line may be marked by error1. of characters in a given line may be marked by error1.
<a name="page89">page 89</a>
## APPENDIX G : MEMORY ALLOCATION AND THE GARBAGE COLLECTOR ## APPENDIX G : MEMORY ALLOCATION AND THE GARBAGE COLLECTOR
The following diagram shows the way in which space is allocated in the LISP System. The following diagram shows the way in which space is allocated in the LISP System.
Loader | Address (octal) | Assigned to |
LAP | --------------- | ------------------------------------------------------------ |
| 77777 | ----- |
Compiler | | Loader |
| 77600 | ----- |
Free Storage | | LAP |
| | Compiler |
Full Words | 70000 | ----- |
| | Free storage |
Push-Down List | | Full words |
| | Pushdown list |
Binary Program Space | | Binary program space |
| 17000 | |
Interpreter, I/O, Read | | Interpreter, I/O, Read Print, Arithmetic, Overlord, Garbage Collector, and other system coding |
Print, Arithmetic, | 00000 | |
Overlord, Garbage
Collector, and other
system coding
The addresses in this chart are only approximate. The available space is divided The addresses in this chart are only approximate. The available space is divided
among binary program space, push-down list, full-word space, and free-storage space among binary program space, push-down list, full-word space, and free-storage space
@ -4159,6 +4195,9 @@ FEXPR1s, evalquote doublets waiting to be executed, APVALts, and partial results
the computation that is in progress. the computation that is in progress.
Full-word space is filled with the BCD characters of PNAMEts, the actual numbers Full-word space is filled with the BCD characters of PNAMEts, the actual numbers
<a name="page90">page 90</a>
of numerical atomic structures, and the TXL words of SUBRtsB FSUBRts, and SYMts. of numerical atomic structures, and the TXL words of SUBRtsB FSUBRts, and SYMts.
All available words in the free-storage area that are not in use are strung together All available words in the free-storage area that are not in use are strung together
in one long list called the free-storage list. Every time a word is needed (for example, in one long list called the free-storage list. Every time a word is needed (for example,
@ -4193,6 +4232,8 @@ can be recognized by the stationary pattern of the MQ lights. Any trap that prev
completion of a garbage collection will create a panic condition in memory from which completion of a garbage collection will create a panic condition in memory from which
there is no recovery. there is no recovery.
<a name="page91">page 91</a>
## APPENDIX H : RECURSION AND THE PUSH-DOWN LIST ## APPENDIX H : RECURSION AND THE PUSH-DOWN LIST
One of the most powerful resources of the LISP language is its ability to accept One of the most powerful resources of the LISP language is its ability to accept
@ -4239,6 +4280,9 @@ ter 1, to place the arguments on the push-down list, and to set up the parameter
the push-down block. the push-down block.
Because pointers to list structures are normally stored on the push-down list, the Because pointers to list structures are normally stored on the push-down list, the
<a name="page92">page 92</a>
garbage collector must mark the currently active portion of the push-down list during a garbage collector must mark the currently active portion of the push-down list during a
garbage collection. Sometimes quantities are placed on the push- down list which should garbage collection. Sometimes quantities are placed on the push- down list which should
not be marked. In this case, the sign bit must be negative. Cells on the active portion not be marked. In this case, the sign bit must be negative. Cells on the active portion
@ -4250,6 +4294,8 @@ list has the name of the function to which it belongs, it is possible to form a
these names. This is called the backtrace, and is normally printed out after error these names. This is called the backtrace, and is normally printed out after error
diagnostics. diagnostics.
<a name="page93">page 93</a>
## APPENDIX I : LISP FOR SHARE DISTRIBUTION ## APPENDIX I : LISP FOR SHARE DISTRIBUTION
The Artificial Intelligence Project at Stanford University has produced a version of The Artificial Intelligence Project at Stanford University has produced a version of
@ -4294,6 +4340,8 @@ the time spent in the packet being finished. This time printout, to be meaningfu
requires the computer to have a millisecond clock in cell 5 (RPQ F 89349, with mil- requires the computer to have a millisecond clock in cell 5 (RPQ F 89349, with mil-
lisecond feature). lisecond feature).
<a name="page94">page 94</a>
It is also possible to determine how much time is required to execute a given func- It is also possible to determine how much time is required to execute a given func-
tion. llTIMEl()lt initializes two time cells to zero and prints out, in the same format tion. llTIMEl()lt initializes two time cells to zero and prints out, in the same format
that is used for the evalquote time printout, two times, and these are both zero. that is used for the evalquote time printout, two times, and these are both zero.
@ -4338,6 +4386,9 @@ after x number of function entrances. Furthermore, when the tracecount mecha-
nism has been activated, by execution of ltTRACECOUNT(x)ll, some of the blank nism has been activated, by execution of ltTRACECOUNT(x)ll, some of the blank
space in the garbage collector printout will be used to output the number of function space in the garbage collector printout will be used to output the number of function
entrances which have taken place up to the time of the garbage collection; each time entrances which have taken place up to the time of the garbage collection; each time
<a name="page95">page 95</a>
the arguments or value of a traced function are printed the number of function en- the arguments or value of a traced function are printed the number of function en-
trances will be printed; and if an error occurs, the number of function entrances ac- trances will be printed; and if an error occurs, the number of function entrances ac-
complished before the error will be printed. complished before the error will be printed.
@ -4384,6 +4435,9 @@ of LISP to communicate between different systems. The functions tape, -- rewind,
ttTAPE(s)tt, where s is a list, allows the user to specify up to ten scratch tapes; ttTAPE(s)tt, where s is a list, allows the user to specify up to ten scratch tapes;
if more than ten are specified, only the first ten are used. The value of tape is its if more than ten are specified, only the first ten are used. The value of tape is its
argument. The initial tape settings are, from one to ten, A4, A5, A6, A7, A8, B2, argument. The initial tape settings are, from one to ten, A4, A5, A6, A7, A8, B2,
<a name="page96">page 96</a>
B3, B4, B5, B6. The tapes must be specified by the octal number that occurs in the B3, B4, B5, B6. The tapes must be specified by the octal number that occurs in the
address portion of a machine-language instruction to rewind that tape; that is, a four- address portion of a machine-language instruction to rewind that tape; that is, a four-
digit octal number is required - the first (high-order) digit is a 1 if channel A is de- digit octal number is required - the first (high-order) digit is a 1 if channel A is de-
@ -4429,6 +4483,8 @@ Evalquote is available to the programmer as a LISP function - thus, one may now
write I1(EVALQUOTE APPEND ((A)(B C D)))I1, rather than "(EVAL (QUOTE (APPEND write I1(EVALQUOTE APPEND ((A)(B C D)))I1, rather than "(EVAL (QUOTE (APPEND
(A)(B C D))) NIL)", should one desire to do so. (A)(B C D))) NIL)", should one desire to do so.
<a name="page97">page 97</a>
### Backtrace ### Backtrace
This function was copied (not quite literally) from M. I. T.'s LISP system on the This function was copied (not quite literally) from M. I. T.'s LISP system on the
@ -4477,6 +4533,9 @@ defined results.
For the convenience of those who find it difficult to get along with the tlCONDn form For the convenience of those who find it difficult to get along with the tlCONDn form
of the conditional statement, the following "IF" forms are provided in the new system. of the conditional statement, the following "IF" forms are provided in the new system.
<a name="page98">page 98</a>
"IF (a THEN b ELSE c)I1 and "IF (a b c)I1 are equivalent to nCOND ((a b)(T c))". "IF "IF (a THEN b ELSE c)I1 and "IF (a b c)I1 are equivalent to nCOND ((a b)(T c))". "IF
(a THEN b)n and "IF (a b)" are equivalent to "COND ((a b))". (a THEN b)n and "IF (a b)" are equivalent to "COND ((a b))".
@ -4518,6 +4577,8 @@ Characteristics of the System
The set-up deck supplied with the SHARE LISP system produces a system tape The set-up deck supplied with the SHARE LISP system produces a system tape
with the following properties: with the following properties:
<a name="page99">page 99</a>
Size (in words) - Size (in words) -
Binary Program Space 14000 octal Binary Program Space 14000 octal
Push-Down List 5000 octal Push-Down List 5000 octal
@ -4539,7 +4600,9 @@ SW5 on to suppress SYSPOT output
SW6 on to return to overlord after accumulator printout resulting from 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 <a name="page100">page 100</a>
## Index to function descriptions
| Function | Call type | Implementation | Pages | | Function | Call type | Implementation | Pages |
|--------------|------------|------------------|------------------------------| |--------------|------------|------------------|------------------------------|

View file

@ -1,4 +1,6 @@
# The properties of the system, and their values: here be dragons # The properties of the system, and their values
## here be dragons
Lisp is the list processing language; that is what its name means. It processes data structures built of lists - which may be lists of lists, or lists of numbers, or lists of any other sort of data item provided for by the designers of the system. Lisp is the list processing language; that is what its name means. It processes data structures built of lists - which may be lists of lists, or lists of numbers, or lists of any other sort of data item provided for by the designers of the system.

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -11,238 +11,394 @@
002&nbsp;&nbsp;&nbsp;&nbsp;&quot;Essentially,&nbsp;the&nbsp;`-main`&nbsp;function&nbsp;and&nbsp;the&nbsp;bootstrap&nbsp;read-eval-print&nbsp;loop.&quot; 002&nbsp;&nbsp;&nbsp;&nbsp;&quot;Essentially,&nbsp;the&nbsp;`-main`&nbsp;function&nbsp;and&nbsp;the&nbsp;bootstrap&nbsp;read-eval-print&nbsp;loop.&quot;
</span><br/> </span><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <span class="not-tracked" title="0 out of 0 forms covered">
003&nbsp;&nbsp;&nbsp;&nbsp;(:require&nbsp;[beowulf.bootstrap&nbsp;:refer&nbsp;[EVAL&nbsp;oblist&nbsp;*options*]] 003&nbsp;&nbsp;&nbsp;&nbsp;(:require&nbsp;[beowulf.bootstrap&nbsp;:refer&nbsp;[EVAL]]
</span><br/> </span><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <span class="not-tracked" title="0 out of 0 forms covered">
004&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[beowulf.read&nbsp;:refer&nbsp;[READ]] 004&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[beowulf.io&nbsp;:refer&nbsp;[default-sysout&nbsp;SYSIN]]
</span><br/> </span><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <span class="not-tracked" title="0 out of 0 forms covered">
005&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[clojure.java.io&nbsp;:as&nbsp;io] 005&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[beowulf.oblist&nbsp;:refer&nbsp;[*options*&nbsp;NIL]]
</span><br/> </span><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <span class="not-tracked" title="0 out of 0 forms covered">
006&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[clojure.pprint&nbsp;:refer&nbsp;[pprint]] 006&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[beowulf.read&nbsp;:refer&nbsp;[READ&nbsp;read-from-console]]
</span><br/> </span><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <span class="not-tracked" title="0 out of 0 forms covered">
007&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[clojure.tools.cli&nbsp;:refer&nbsp;[parse-opts]] 007&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[clojure.java.io&nbsp;:as&nbsp;io]
</span><br/> </span><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <span class="not-tracked" title="0 out of 0 forms covered">
008&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[environ.core&nbsp;:refer&nbsp;[env]]) 008&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[clojure.pprint&nbsp;:refer&nbsp;[pprint]]
</span><br/> </span><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <span class="not-tracked" title="0 out of 0 forms covered">
009&nbsp;&nbsp;&nbsp;&nbsp;(:gen-class)) 009&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[clojure.string&nbsp;:refer&nbsp;[trim]]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
010&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[clojure.tools.cli&nbsp;:refer&nbsp;[parse-opts]])
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
011&nbsp;&nbsp;&nbsp;&nbsp;(:gen-class))
</span><br/> </span><br/>
<span class="blank" title="0 out of 0 forms covered"> <span class="blank" title="0 out of 0 forms covered">
010&nbsp;&nbsp; 012&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
011&nbsp;&nbsp;(def&nbsp;cli-options
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
012&nbsp;&nbsp;&nbsp;&nbsp;[[&quot;-h&quot;&nbsp;&quot;--help&quot;]
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
013&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[&quot;-p&nbsp;PROMPT&quot;&nbsp;&quot;--prompt&nbsp;PROMPT&quot;&nbsp;&quot;Set&nbsp;the&nbsp;REPL&nbsp;prompt&nbsp;to&nbsp;PROMPT&quot;
</span><br/> </span><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <span class="not-tracked" title="0 out of 0 forms covered">
014&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:default&nbsp;&quot;Sprecan::&quot;] 013&nbsp;&nbsp;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
015&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[&quot;-r&nbsp;INITFILE&quot;&nbsp;&quot;--read&nbsp;INITFILE&quot;&nbsp;&quot;Read&nbsp;Lisp&nbsp;functions&nbsp;from&nbsp;the&nbsp;file&nbsp;INITFILE&quot;
</span><br/>
<span class="covered" title="8 out of 8 forms covered">
016&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:validate&nbsp;[#(and
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
017&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(.exists&nbsp;(io&#x2F;file&nbsp;%))
</span><br/> </span><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <span class="not-tracked" title="0 out of 0 forms covered">
018&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(.canRead&nbsp;(io&#x2F;file&nbsp;%))) 014&nbsp;&nbsp;;;;
</span><br/> </span><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <span class="not-tracked" title="0 out of 0 forms covered">
019&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;Could&nbsp;not&nbsp;find&nbsp;initfile&quot;]] 015&nbsp;&nbsp;;;;&nbsp;Copyright&nbsp;(C)&nbsp;2022-2023&nbsp;Simon&nbsp;Brooke
</span><br/> </span><br/>
<span class="covered" title="4 out of 4 forms covered"> <span class="not-tracked" title="0 out of 0 forms covered">
020&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[&quot;-s&quot;&nbsp;&quot;--strict&quot;&nbsp;&quot;Strictly&nbsp;interpret&nbsp;the&nbsp;Lisp&nbsp;1.5&nbsp;language,&nbsp;without&nbsp;extensions.&quot;] 016&nbsp;&nbsp;;;;
</span><br/> </span><br/>
<span class="covered" title="4 out of 4 forms covered"> <span class="not-tracked" title="0 out of 0 forms covered">
021&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[&quot;-t&quot;&nbsp;&quot;--trace&quot;&nbsp;&quot;Trace&nbsp;Lisp&nbsp;evaluation.&quot;]]) 017&nbsp;&nbsp;;;;&nbsp;This&nbsp;program&nbsp;is&nbsp;free&nbsp;software;&nbsp;you&nbsp;can&nbsp;redistribute&nbsp;it&nbsp;and&#x2F;or
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
018&nbsp;&nbsp;;;;&nbsp;modify&nbsp;it&nbsp;under&nbsp;the&nbsp;terms&nbsp;of&nbsp;the&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
019&nbsp;&nbsp;;;;&nbsp;as&nbsp;published&nbsp;by&nbsp;the&nbsp;Free&nbsp;Software&nbsp;Foundation;&nbsp;either&nbsp;version&nbsp;2
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
020&nbsp;&nbsp;;;;&nbsp;of&nbsp;the&nbsp;License,&nbsp;or&nbsp;(at&nbsp;your&nbsp;option)&nbsp;any&nbsp;later&nbsp;version.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
021&nbsp;&nbsp;;;;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
022&nbsp;&nbsp;;;;&nbsp;This&nbsp;program&nbsp;is&nbsp;distributed&nbsp;in&nbsp;the&nbsp;hope&nbsp;that&nbsp;it&nbsp;will&nbsp;be&nbsp;useful,
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
023&nbsp;&nbsp;;;;&nbsp;but&nbsp;WITHOUT&nbsp;ANY&nbsp;WARRANTY;&nbsp;without&nbsp;even&nbsp;the&nbsp;implied&nbsp;warranty&nbsp;of
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
024&nbsp;&nbsp;;;;&nbsp;MERCHANTABILITY&nbsp;or&nbsp;FITNESS&nbsp;FOR&nbsp;A&nbsp;PARTICULAR&nbsp;PURPOSE.&nbsp;&nbsp;See&nbsp;the
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
025&nbsp;&nbsp;;;;&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License&nbsp;for&nbsp;more&nbsp;details.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
026&nbsp;&nbsp;;;;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
027&nbsp;&nbsp;;;;&nbsp;You&nbsp;should&nbsp;have&nbsp;received&nbsp;a&nbsp;copy&nbsp;of&nbsp;the&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
028&nbsp;&nbsp;;;;&nbsp;along&nbsp;with&nbsp;this&nbsp;program;&nbsp;if&nbsp;not,&nbsp;write&nbsp;to&nbsp;the&nbsp;Free&nbsp;Software
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
029&nbsp;&nbsp;;;;&nbsp;Foundation,&nbsp;Inc.,&nbsp;51&nbsp;Franklin&nbsp;Street,&nbsp;Fifth&nbsp;Floor,&nbsp;Boston,&nbsp;MA&nbsp;&nbsp;02110-1301,&nbsp;USA.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
030&nbsp;&nbsp;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
031&nbsp;&nbsp;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
</span><br/> </span><br/>
<span class="blank" title="0 out of 0 forms covered"> <span class="blank" title="0 out of 0 forms covered">
022&nbsp;&nbsp; 032&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
023&nbsp;&nbsp;(defn&nbsp;repl
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
024&nbsp;&nbsp;&nbsp;&nbsp;&quot;Read&#x2F;eval&#x2F;print&nbsp;loop.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
025&nbsp;&nbsp;&nbsp;&nbsp;[prompt]
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
026&nbsp;&nbsp;&nbsp;&nbsp;(loop&nbsp;[]
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
027&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(print&nbsp;prompt)
</span><br/> </span><br/>
<span class="covered" title="2 out of 2 forms covered"> <span class="covered" title="2 out of 2 forms covered">
028&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(flush) 033&nbsp;&nbsp;(def&nbsp;stop-word&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
029&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(try
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
030&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[input&nbsp;(read-line)]
</span><br/>
<span class="partial" title="2 out of 3 forms covered">
031&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cond
</span><br/>
<span class="covered" title="11 out of 11 forms covered">
032&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(=&nbsp;input&nbsp;&quot;quit&quot;)&nbsp;(throw&nbsp;(ex-info&nbsp;&quot;\nFærwell!&quot;&nbsp;{:cause&nbsp;:quit}))
</span><br/>
<span class="covered" title="16 out of 16 forms covered">
033&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;input&nbsp;(println&nbsp;(str&nbsp;&quot;&gt;&nbsp;&nbsp;&quot;&nbsp;(print-str&nbsp;(EVAL&nbsp;(READ&nbsp;input)&nbsp;@oblist))))
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
034&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:else&nbsp;(println)))
</span><br/> </span><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <span class="not-tracked" title="0 out of 0 forms covered">
035&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(catch 034&nbsp;&nbsp;&nbsp;&nbsp;&quot;The&nbsp;word&nbsp;which,&nbsp;if&nbsp;submitted&nbsp;an&nbsp;an&nbsp;input&nbsp;line,&nbsp;will&nbsp;cause&nbsp;Beowulf&nbsp;to&nbsp;quit.
</span><br/> </span><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <span class="not-tracked" title="0 out of 0 forms covered">
036&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Exception 035&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Question:&nbsp;should&nbsp;this&nbsp;be&nbsp;`forlǣte`?&quot;
</span><br/> </span><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <span class="not-tracked" title="0 out of 0 forms covered">
037&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e 036&nbsp;&nbsp;&nbsp;&nbsp;&quot;STOP&quot;)
</span><br/> </span><br/>
<span class="covered" title="4 out of 4 forms covered"> <span class="blank" title="0 out of 0 forms covered">
038&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[data&nbsp;(ex-data&nbsp;e)] 037&nbsp;&nbsp;
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
039&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(println&nbsp;(.getMessage&nbsp;e))
</span><br/> </span><br/>
<span class="covered" title="1 out of 1 forms covered"> <span class="covered" title="1 out of 1 forms covered">
040&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if 038&nbsp;&nbsp;(def&nbsp;cli-options
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
041&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;data
</span><br/> </span><br/>
<span class="covered" title="6 out of 6 forms covered"> <span class="covered" title="6 out of 6 forms covered">
042&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(case&nbsp;(:cause&nbsp;data) 039&nbsp;&nbsp;&nbsp;&nbsp;[[&quot;-f&nbsp;FILEPATH&quot;&nbsp;&quot;--file-path&nbsp;FILEPATH&quot;
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
043&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:parse-failure&nbsp;(println&nbsp;(:failure&nbsp;data))
</span><br/> </span><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <span class="not-tracked" title="0 out of 0 forms covered">
044&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:strict&nbsp;nil&nbsp;;;&nbsp;the&nbsp;message,&nbsp;which&nbsp;has&nbsp;already&nbsp;been&nbsp;printed,&nbsp;is&nbsp;enough. 040&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;Set&nbsp;the&nbsp;path&nbsp;to&nbsp;the&nbsp;directory&nbsp;for&nbsp;reading&nbsp;and&nbsp;writing&nbsp;Lisp&nbsp;files.&quot;
</span><br/> </span><br/>
<span class="covered" title="2 out of 2 forms covered"> <span class="partial" title="3 out of 20 forms covered">
045&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:quit&nbsp;(throw&nbsp;e) 041&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:validate&nbsp;[#(and&nbsp;(.exists&nbsp;(io&#x2F;file&nbsp;%))
</span><br/> </span><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <span class="not-covered" title="0 out of 4 forms covered">
046&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;default 042&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(.isDirectory&nbsp;(io&#x2F;file&nbsp;%))
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
043&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(.canRead&nbsp;(io&#x2F;file&nbsp;%))
</span><br/> </span><br/>
<span class="not-covered" title="0 out of 3 forms covered"> <span class="not-covered" title="0 out of 3 forms covered">
047&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(pprint&nbsp;data)))))) 044&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(.canWrite&nbsp;(io&#x2F;file&nbsp;%)))
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
048&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(recur)))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
049&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
050&nbsp;&nbsp;(defn&nbsp;-main
</span><br/> </span><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <span class="not-tracked" title="0 out of 0 forms covered">
051&nbsp;&nbsp;&nbsp;&nbsp;&quot;Parse&nbsp;options,&nbsp;print&nbsp;the&nbsp;banner,&nbsp;read&nbsp;the&nbsp;init&nbsp;file&nbsp;if&nbsp;any,&nbsp;and&nbsp;enter&nbsp;the 045&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;File&nbsp;path&nbsp;must&nbsp;exist&nbsp;and&nbsp;must&nbsp;be&nbsp;a&nbsp;directory.&quot;]]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
052&nbsp;&nbsp;&nbsp;&nbsp;read&#x2F;eval&#x2F;print&nbsp;loop.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
053&nbsp;&nbsp;&nbsp;&nbsp;[&amp;&nbsp;opts]
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
054&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[args&nbsp;(parse-opts&nbsp;opts&nbsp;cli-options)]
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
055&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(println
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
056&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(str
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
057&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;\nHider&nbsp;wilcuman.&nbsp;Béowulf&nbsp;is&nbsp;mín&nbsp;nama.\n&quot;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
058&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
059&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(System&#x2F;getProperty&nbsp;&quot;beowulf.version&quot;)
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
060&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(str&nbsp;&quot;Síðe&nbsp;&quot;&nbsp;(System&#x2F;getProperty&nbsp;&quot;beowulf.version&quot;)&nbsp;&quot;\n&quot;))
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
061&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
062&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:help&nbsp;(:options&nbsp;args))
</span><br/> </span><br/>
<span class="covered" title="3 out of 3 forms covered"> <span class="covered" title="3 out of 3 forms covered">
063&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:summary&nbsp;args)) 046&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[&quot;-h&quot;&nbsp;&quot;--help&quot;]
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
047&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[&quot;-p&nbsp;PROMPT&quot;&nbsp;&quot;--prompt&nbsp;PROMPT&quot;&nbsp;&quot;Set&nbsp;the&nbsp;REPL&nbsp;prompt&nbsp;to&nbsp;PROMPT&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
048&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:default&nbsp;&quot;Sprecan::&quot;]
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
049&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[&quot;-r&nbsp;SYSOUTFILE&quot;&nbsp;&quot;--read&nbsp;SYSOUTFILE&quot;&nbsp;&quot;Read&nbsp;Lisp&nbsp;system&nbsp;from&nbsp;file&nbsp;SYSOUTFILE&quot;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
050&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:default&nbsp;default-sysout
</span><br/>
<span class="partial" title="3 out of 8 forms covered">
051&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:validate&nbsp;[#(and
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
052&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(.exists&nbsp;(io&#x2F;file&nbsp;%))
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
053&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(.canRead&nbsp;(io&#x2F;file&nbsp;%)))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
054&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;Could&nbsp;not&nbsp;find&nbsp;sysout&nbsp;file&quot;]]
</span><br/> </span><br/>
<span class="covered" title="4 out of 4 forms covered"> <span class="covered" title="4 out of 4 forms covered">
064&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if&nbsp;(:errors&nbsp;args) 055&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[&quot;-s&quot;&nbsp;&quot;--strict&quot;&nbsp;&quot;Strictly&nbsp;interpret&nbsp;the&nbsp;Lisp&nbsp;1.5&nbsp;language,&nbsp;without&nbsp;extensions.&quot;]
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
056&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[&quot;-t&quot;&nbsp;&quot;--time&quot;&nbsp;&quot;Time&nbsp;evaluations.&quot;]])
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
057&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
058&nbsp;&nbsp;(defn-&nbsp;re&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
059&nbsp;&nbsp;&nbsp;&nbsp;&quot;Like&nbsp;REPL,&nbsp;but&nbsp;it&nbsp;isn&#x27;t&nbsp;a&nbsp;loop&nbsp;and&nbsp;doesn&#x27;t&nbsp;print.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
060&nbsp;&nbsp;&nbsp;&nbsp;[input]
</span><br/>
<span class="covered" title="7 out of 7 forms covered">
061&nbsp;&nbsp;&nbsp;&nbsp;(EVAL&nbsp;(READ&nbsp;input)&nbsp;NIL&nbsp;0))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
062&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
063&nbsp;&nbsp;(defn&nbsp;repl
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
064&nbsp;&nbsp;&nbsp;&nbsp;&quot;Read&#x2F;eval&#x2F;print&nbsp;loop.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
065&nbsp;&nbsp;&nbsp;&nbsp;[prompt]
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
066&nbsp;&nbsp;&nbsp;&nbsp;(loop&nbsp;[]
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
067&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(print&nbsp;prompt)
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
068&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(flush)
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
069&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(try
</span><br/> </span><br/>
<span class="covered" title="9 out of 9 forms covered"> <span class="covered" title="9 out of 9 forms covered">
065&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(apply&nbsp;str&nbsp;(interpose&nbsp;&quot;;&nbsp;&quot;&nbsp;(:errors&nbsp;args)))) 070&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if-let&nbsp;[input&nbsp;(trim&nbsp;(read-from-console))]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
066&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;\nSprecan&nbsp;&#x27;quit&#x27;&nbsp;&nbsp;laéfan\n&quot;))
</span><br/>
<span class="covered" title="12 out of 12 forms covered">
067&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(binding&nbsp;[*options*&nbsp;(:options&nbsp;args)]
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
068&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(try
</span><br/>
<span class="covered" title="10 out of 10 forms covered">
069&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(repl&nbsp;(str&nbsp;(:prompt&nbsp;(:options&nbsp;args))&nbsp;&quot;&nbsp;&quot;))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
070&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(catch
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
071&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Exception
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
072&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e
</span><br/> </span><br/>
<span class="covered" title="4 out of 4 forms covered"> <span class="covered" title="4 out of 4 forms covered">
073&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[data&nbsp;(ex-data&nbsp;e)] 071&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if&nbsp;(=&nbsp;input&nbsp;stop-word)
</span><br/> </span><br/>
<span class="covered" title="1 out of 1 forms covered"> <span class="covered" title="7 out of 7 forms covered">
074&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if 072&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(throw&nbsp;(ex-info&nbsp;&quot;\nFærwell!&quot;&nbsp;{:cause&nbsp;:quit}))
</span><br/> </span><br/>
<span class="covered" title="1 out of 1 forms covered"> <span class="covered" title="2 out of 2 forms covered">
075&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;data 073&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(println&nbsp;
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
074&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(str&nbsp;&quot;&gt;&nbsp;&nbsp;&quot;&nbsp;
</span><br/> </span><br/>
<span class="covered" title="6 out of 6 forms covered"> <span class="covered" title="6 out of 6 forms covered">
076&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(case&nbsp;(:cause&nbsp;data) 075&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(print-str&nbsp;(if&nbsp;(:time&nbsp;*options*)
</span><br/>
<span class="not-covered" title="0 out of 18 forms covered">
076&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(time&nbsp;(re&nbsp;input))
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
077&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(re&nbsp;input))))))&nbsp;
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
078&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(println))
</span><br/> </span><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <span class="not-tracked" title="0 out of 0 forms covered">
077&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:quit&nbsp;nil 079&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(catch
</span><br/> </span><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <span class="not-tracked" title="0 out of 0 forms covered">
078&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;default 080&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Exception
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
081&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
082&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[data&nbsp;(ex-data&nbsp;e)]
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
083&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(println&nbsp;(.getMessage&nbsp;e))
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
084&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(when
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
085&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;data
</span><br/>
<span class="partial" title="5 out of 6 forms covered">
086&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(case&nbsp;(:cause&nbsp;data)
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
087&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:parse-failure&nbsp;(println&nbsp;(:failure&nbsp;data))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
088&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:strict&nbsp;nil&nbsp;;;&nbsp;the&nbsp;message,&nbsp;which&nbsp;has&nbsp;already&nbsp;been&nbsp;printed,&nbsp;is&nbsp;enough.
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
089&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:quit&nbsp;(throw&nbsp;e)
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
090&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;default
</span><br/> </span><br/>
<span class="not-covered" title="0 out of 3 forms covered"> <span class="not-covered" title="0 out of 3 forms covered">
079&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(pprint&nbsp;data)) 091&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(pprint&nbsp;data))))))
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
092&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(recur)))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
093&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
094&nbsp;&nbsp;(defn&nbsp;-main
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
095&nbsp;&nbsp;&nbsp;&nbsp;&quot;Parse&nbsp;options,&nbsp;print&nbsp;the&nbsp;banner,&nbsp;read&nbsp;the&nbsp;init&nbsp;file&nbsp;if&nbsp;any,&nbsp;and&nbsp;enter&nbsp;the
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
096&nbsp;&nbsp;&nbsp;&nbsp;read&#x2F;eval&#x2F;print&nbsp;loop.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
097&nbsp;&nbsp;&nbsp;&nbsp;[&amp;&nbsp;opts]
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
098&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[args&nbsp;(parse-opts&nbsp;opts&nbsp;cli-options)]
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
099&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(println
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
100&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(str
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
101&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;\nHider&nbsp;wilcuman.&nbsp;Béowulf&nbsp;is&nbsp;mín&nbsp;nama.\n&quot;
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
102&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(when
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
103&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(System&#x2F;getProperty&nbsp;&quot;beowulf.version&quot;)
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
104&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(str&nbsp;&quot;Síðe&nbsp;&quot;&nbsp;(System&#x2F;getProperty&nbsp;&quot;beowulf.version&quot;)&nbsp;&quot;\n&quot;))
</span><br/>
<span class="partial" title="1 out of 2 forms covered">
105&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(when
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
106&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:help&nbsp;(:options&nbsp;args))
</span><br/> </span><br/>
<span class="not-covered" title="0 out of 3 forms covered"> <span class="not-covered" title="0 out of 3 forms covered">
080&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(println&nbsp;e)))))))) 107&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:summary&nbsp;args))
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
108&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(when&nbsp;(:errors&nbsp;args)
</span><br/>
<span class="covered" title="9 out of 9 forms covered">
109&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(apply&nbsp;str&nbsp;(interpose&nbsp;&quot;;&nbsp;&quot;&nbsp;(:errors&nbsp;args))))
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
110&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;\nSprecan&nbsp;&#x27;&quot;&nbsp;stop-word&nbsp;&quot;&#x27;&nbsp;&nbsp;laéfan\n&quot;))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
111&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span><br/>
<span class="covered" title="12 out of 12 forms covered">
112&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(binding&nbsp;[*options*&nbsp;(:options&nbsp;args)]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
113&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;(pprint&nbsp;*options*)
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
114&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(when&nbsp;(:read&nbsp;*options*)
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
115&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(try&nbsp;(SYSIN&nbsp;(:read&nbsp;*options*))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
116&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(catch&nbsp;Throwable&nbsp;any
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
117&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(println&nbsp;any))))
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
118&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(try
</span><br/>
<span class="covered" title="10 out of 10 forms covered">
119&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(repl&nbsp;(str&nbsp;(:prompt&nbsp;(:options&nbsp;args))&nbsp;&quot;&nbsp;&quot;))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
120&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(catch
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
121&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Exception
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
122&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
123&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[data&nbsp;(ex-data&nbsp;e)]
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
124&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
125&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;data
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
126&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(case&nbsp;(:cause&nbsp;data)
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
127&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:quit&nbsp;nil
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
128&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;default
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
129&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(do
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
130&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(println&nbsp;&quot;STÆFLEAHTER:&nbsp;&quot;&nbsp;(.getMessage&nbsp;e))
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
131&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(pprint&nbsp;data)))
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
132&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(println&nbsp;e))))))))
</span><br/> </span><br/>
</body> </body>
</html> </html>

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,395 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" href="../coverage.css"/> <title> beowulf/interop.clj </title>
</head>
<body>
<span class="covered" title="1 out of 1 forms covered">
001&nbsp;&nbsp;(ns&nbsp;beowulf.interop
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
002&nbsp;&nbsp;&nbsp;&nbsp;(:require&nbsp;[beowulf.cons-cell&nbsp;:refer&nbsp;[make-beowulf-list]]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
003&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[beowulf.host&nbsp;:refer&nbsp;[CAR&nbsp;CDR]]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
004&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[beowulf.oblist&nbsp;:refer&nbsp;[*options*&nbsp;NIL]]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
005&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[clojure.string&nbsp;:as&nbsp;s&nbsp;:refer&nbsp;[last-index-of&nbsp;lower-case&nbsp;split
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
006&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;upper-case]]))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
007&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
008&nbsp;&nbsp;;;;;&nbsp;INTEROP&nbsp;feature&nbsp;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
009&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
010&nbsp;&nbsp;(defn&nbsp;listify-qualified-name
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
011&nbsp;&nbsp;&nbsp;&nbsp;&quot;We&nbsp;need&nbsp;to&nbsp;be&nbsp;able&nbsp;to&nbsp;print&nbsp;something&nbsp;we&nbsp;can&nbsp;link&nbsp;to&nbsp;the&nbsp;particular&nbsp;Clojure
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
012&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;function&nbsp;`subr`&nbsp;in&nbsp;a&nbsp;form&nbsp;in&nbsp;which&nbsp;Lisp&nbsp;1.5&nbsp;is&nbsp;able&nbsp;to&nbsp;read&nbsp;it&nbsp;back&nbsp;in&nbsp;and
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
013&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;relink&nbsp;it.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
014&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
015&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;This&nbsp;assumes&nbsp;`subr`&nbsp;is&nbsp;either&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
016&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1.&nbsp;a&nbsp;string&nbsp;in&nbsp;the&nbsp;format&nbsp;`#&#x27;beowulf.io&#x2F;SYSIN`&nbsp;or&nbsp;`beowulf.io&#x2F;SYSIN`;&nbsp;or
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
017&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2.&nbsp;something&nbsp;which,&nbsp;when&nbsp;coerced&nbsp;to&nbsp;a&nbsp;string&nbsp;with&nbsp;`str`,&nbsp;will&nbsp;have&nbsp;such
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
018&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a&nbsp;format.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
019&nbsp;&nbsp;&nbsp;&nbsp;[subr]
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
020&nbsp;&nbsp;&nbsp;&nbsp;(make-beowulf-list
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
021&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
022&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#(symbol&nbsp;(upper-case&nbsp;%))
</span><br/>
<span class="not-covered" title="0 out of 9 forms covered">
023&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(remove&nbsp;empty?&nbsp;(split&nbsp;(str&nbsp;subr)&nbsp;#&quot;[#&#x27;.&#x2F;]&quot;)))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
024&nbsp;&nbsp;
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
025&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
026&nbsp;&nbsp;(defn&nbsp;interpret-qualified-name
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
027&nbsp;&nbsp;&nbsp;&nbsp;&quot;For&nbsp;interoperation&nbsp;with&nbsp;Clojure,&nbsp;it&nbsp;will&nbsp;often&nbsp;be&nbsp;necessary&nbsp;to&nbsp;pass
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
028&nbsp;&nbsp;&nbsp;&nbsp;qualified&nbsp;names&nbsp;that&nbsp;are&nbsp;not&nbsp;representable&nbsp;in&nbsp;Lisp&nbsp;1.5.&nbsp;This&nbsp;function
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
029&nbsp;&nbsp;&nbsp;&nbsp;takes&nbsp;a&nbsp;sequence&nbsp;in&nbsp;the&nbsp;form&nbsp;`(PART&nbsp;PART&nbsp;PART...&nbsp;NAME)`&nbsp;and&nbsp;returns
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
030&nbsp;&nbsp;&nbsp;&nbsp;a&nbsp;symbol&nbsp;in&nbsp;the&nbsp;form&nbsp;`part.part.part&#x2F;NAME`.&nbsp;This&nbsp;symbol&nbsp;will&nbsp;then&nbsp;be
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
031&nbsp;&nbsp;&nbsp;&nbsp;tried&nbsp;in&nbsp;both&nbsp;that&nbsp;form&nbsp;and&nbsp;lower-cased.&nbsp;Names&nbsp;with&nbsp;hyphens&nbsp;or
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
032&nbsp;&nbsp;&nbsp;&nbsp;underscores&nbsp;cannot&nbsp;be&nbsp;represented&nbsp;with&nbsp;this&nbsp;scheme.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
033&nbsp;&nbsp;&nbsp;&nbsp;([l]
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
034&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(symbol
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
035&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[n&nbsp;(s&#x2F;join&nbsp;&quot;.&quot;&nbsp;
</span><br/>
<span class="covered" title="13 out of 13 forms covered">
036&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(concat&nbsp;(map&nbsp;#(lower-case&nbsp;(str&nbsp;%))&nbsp;(butlast&nbsp;l))&nbsp;
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
037&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(list&nbsp;(last&nbsp;l))))
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
038&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s&nbsp;(last-index-of&nbsp;n&nbsp;&quot;.&quot;)]
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
039&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if&nbsp;s
</span><br/>
<span class="covered" title="13 out of 13 forms covered">
040&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(str&nbsp;(subs&nbsp;n&nbsp;0&nbsp;s)&nbsp;&quot;&#x2F;&quot;&nbsp;(subs&nbsp;n&nbsp;(inc&nbsp;s)))
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
041&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;n)))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
042&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
043&nbsp;&nbsp;(defn&nbsp;to-beowulf
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
044&nbsp;&nbsp;&nbsp;&nbsp;&quot;Return&nbsp;a&nbsp;beowulf-native&nbsp;representation&nbsp;of&nbsp;the&nbsp;Clojure&nbsp;object&nbsp;`o`.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
045&nbsp;&nbsp;&nbsp;&nbsp;Numbers&nbsp;and&nbsp;symbols&nbsp;are&nbsp;unaffected.&nbsp;Collections&nbsp;have&nbsp;to&nbsp;be&nbsp;converted;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
046&nbsp;&nbsp;&nbsp;&nbsp;strings&nbsp;must&nbsp;be&nbsp;converted&nbsp;to&nbsp;symbols.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
047&nbsp;&nbsp;&nbsp;&nbsp;[o]
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
048&nbsp;&nbsp;&nbsp;&nbsp;(cond
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
049&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(coll?&nbsp;o)&nbsp;(make-beowulf-list&nbsp;o)
</span><br/>
<span class="not-covered" title="0 out of 8 forms covered">
050&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(string?&nbsp;o)&nbsp;(symbol&nbsp;(s&#x2F;upper-case&nbsp;o))
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
051&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:else&nbsp;o))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
052&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
053&nbsp;&nbsp;(defn&nbsp;to-clojure
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
054&nbsp;&nbsp;&nbsp;&nbsp;&quot;If&nbsp;l&nbsp;is&nbsp;a&nbsp;`beowulf.cons_cell.ConsCell`,&nbsp;return&nbsp;a&nbsp;Clojure&nbsp;list&nbsp;having&nbsp;the&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
055&nbsp;&nbsp;&nbsp;&nbsp;same&nbsp;members&nbsp;in&nbsp;the&nbsp;same&nbsp;order.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
056&nbsp;&nbsp;&nbsp;&nbsp;[l]
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
057&nbsp;&nbsp;&nbsp;&nbsp;(cond
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
058&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(not&nbsp;(instance?&nbsp;beowulf.cons_cell.ConsCell&nbsp;l))
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
059&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;l
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
060&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(=&nbsp;(CDR&nbsp;l)&nbsp;NIL)
</span><br/>
<span class="covered" title="7 out of 7 forms covered">
061&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(list&nbsp;(to-clojure&nbsp;(CAR&nbsp;l)))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
062&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:else
</span><br/>
<span class="covered" title="12 out of 12 forms covered">
063&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(conj&nbsp;(to-clojure&nbsp;(CDR&nbsp;l))&nbsp;(to-clojure&nbsp;(CAR&nbsp;l)))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
064&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
065&nbsp;&nbsp;(defn&nbsp;INTEROP
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
066&nbsp;&nbsp;&nbsp;&nbsp;&quot;Clojure&nbsp;(or&nbsp;other&nbsp;host&nbsp;environment)&nbsp;interoperation&nbsp;API.&nbsp;`fn-symbol`&nbsp;is&nbsp;expected
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
067&nbsp;&nbsp;&nbsp;&nbsp;to&nbsp;be&nbsp;either
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
068&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
069&nbsp;&nbsp;&nbsp;&nbsp;1.&nbsp;a&nbsp;symbol&nbsp;bound&nbsp;in&nbsp;the&nbsp;host&nbsp;environment&nbsp;to&nbsp;a&nbsp;function;&nbsp;or
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
070&nbsp;&nbsp;&nbsp;&nbsp;2.&nbsp;a&nbsp;sequence&nbsp;(list)&nbsp;of&nbsp;symbols&nbsp;forming&nbsp;a&nbsp;qualified&nbsp;path&nbsp;name&nbsp;bound&nbsp;to&nbsp;a
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
071&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;function.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
072&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
073&nbsp;&nbsp;&nbsp;&nbsp;Lower&nbsp;case&nbsp;characters&nbsp;cannot&nbsp;normally&nbsp;be&nbsp;represented&nbsp;in&nbsp;Lisp&nbsp;1.5,&nbsp;so&nbsp;both&nbsp;the
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
074&nbsp;&nbsp;&nbsp;&nbsp;upper&nbsp;case&nbsp;and&nbsp;lower&nbsp;case&nbsp;variants&nbsp;of&nbsp;`fn-symbol`&nbsp;will&nbsp;be&nbsp;tried.&nbsp;If&nbsp;the
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
075&nbsp;&nbsp;&nbsp;&nbsp;function&nbsp;you&#x27;re&nbsp;looking&nbsp;for&nbsp;has&nbsp;a&nbsp;mixed&nbsp;case&nbsp;name,&nbsp;that&nbsp;is&nbsp;not&nbsp;currently
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
076&nbsp;&nbsp;&nbsp;&nbsp;accessible.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
077&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
078&nbsp;&nbsp;&nbsp;&nbsp;`args`&nbsp;is&nbsp;expected&nbsp;to&nbsp;be&nbsp;a&nbsp;Lisp&nbsp;1.5&nbsp;list&nbsp;of&nbsp;arguments&nbsp;to&nbsp;be&nbsp;passed&nbsp;to&nbsp;that
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
079&nbsp;&nbsp;&nbsp;&nbsp;function.&nbsp;Return&nbsp;value&nbsp;must&nbsp;be&nbsp;something&nbsp;acceptable&nbsp;to&nbsp;Lisp&nbsp;1.5,&nbsp;so&nbsp;either
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
080&nbsp;&nbsp;&nbsp;&nbsp;a&nbsp;symbol,&nbsp;a&nbsp;number,&nbsp;or&nbsp;a&nbsp;Lisp&nbsp;1.5&nbsp;list.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
081&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
082&nbsp;&nbsp;&nbsp;&nbsp;If&nbsp;`fn-symbol`&nbsp;is&nbsp;not&nbsp;found&nbsp;(even&nbsp;when&nbsp;cast&nbsp;to&nbsp;lower&nbsp;case),&nbsp;or&nbsp;is&nbsp;not&nbsp;a&nbsp;function,
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
083&nbsp;&nbsp;&nbsp;&nbsp;or&nbsp;the&nbsp;value&nbsp;returned&nbsp;cannot&nbsp;be&nbsp;represented&nbsp;in&nbsp;Lisp&nbsp;1.5,&nbsp;an&nbsp;exception&nbsp;is&nbsp;thrown
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
084&nbsp;&nbsp;&nbsp;&nbsp;with&nbsp;`:cause`&nbsp;bound&nbsp;to&nbsp;`:interop`&nbsp;and&nbsp;`:detail`&nbsp;set&nbsp;to&nbsp;a&nbsp;value&nbsp;representing&nbsp;the
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
085&nbsp;&nbsp;&nbsp;&nbsp;actual&nbsp;problem.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
086&nbsp;&nbsp;&nbsp;&nbsp;[fn-symbol&nbsp;args]
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
087&nbsp;&nbsp;&nbsp;&nbsp;(if-not&nbsp;(:strict&nbsp;*options*)
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
088&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
089&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[q-name&nbsp;(if
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
090&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(seq?&nbsp;fn-symbol)
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
091&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(interpret-qualified-name&nbsp;fn-symbol)
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
092&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fn-symbol)
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
093&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;l-name&nbsp;(symbol&nbsp;(s&#x2F;lower-case&nbsp;q-name))
</span><br/>
<span class="partial" title="1 out of 3 forms covered">
094&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;f&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cond
</span><br/>
<span class="partial" title="1 out of 2 forms covered">
095&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(try
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
096&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(fn?&nbsp;(eval&nbsp;l-name))
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
097&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(catch&nbsp;java.lang.ClassNotFoundException&nbsp;_&nbsp;nil))&nbsp;l-name
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
098&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(try
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
099&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(fn?&nbsp;(eval&nbsp;q-name))
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
100&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(catch&nbsp;java.lang.ClassNotFoundException&nbsp;_&nbsp;nil))&nbsp;q-name
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
101&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:else&nbsp;(throw
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
102&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(ex-info
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
103&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(str&nbsp;&quot;INTEROP:&nbsp;ungecnáwen&nbsp;þegnung&nbsp;`&quot;&nbsp;fn-symbol&nbsp;&quot;`&quot;)
</span><br/>
<span class="not-covered" title="0 out of 7 forms covered">
104&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{:cause&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:interop
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
105&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:detail&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:not-found
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
106&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fn-symbol
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
107&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:also-tried&nbsp;l-name})))
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
108&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;args&#x27;&nbsp;&nbsp;(to-clojure&nbsp;args)]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
109&nbsp;&nbsp;;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(print&nbsp;(str&nbsp;&quot;INTEROP:&nbsp;eahtiende&nbsp;`&quot;&nbsp;(cons&nbsp;f&nbsp;args&#x27;)&nbsp;&quot;`&quot;))
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
110&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(flush)
</span><br/>
<span class="covered" title="7 out of 7 forms covered">
111&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[result&nbsp;(eval&nbsp;(conj&nbsp;args&#x27;&nbsp;f))]&nbsp;;;&nbsp;this&nbsp;has&nbsp;the&nbsp;potential&nbsp;to&nbsp;blow&nbsp;up&nbsp;the&nbsp;world
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
112&nbsp;&nbsp;;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(println&nbsp;(str&nbsp;&quot;;&nbsp;ágiefende&nbsp;`&quot;&nbsp;result&nbsp;&quot;`&quot;))
</span><br/>
<span class="partial" title="4 out of 6 forms covered">
113&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cond
</span><br/>
<span class="partial" title="4 out of 5 forms covered">
114&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(instance?&nbsp;beowulf.cons_cell.ConsCell&nbsp;result)&nbsp;result
</span><br/>
<span class="partial" title="3 out of 6 forms covered">
115&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(coll?&nbsp;result)&nbsp;(make-beowulf-list&nbsp;result)
</span><br/>
<span class="partial" title="3 out of 4 forms covered">
116&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(symbol?&nbsp;result)&nbsp;result
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
117&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(string?&nbsp;result)&nbsp;(symbol&nbsp;result)
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
118&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(number?&nbsp;result)&nbsp;result
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
119&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:else&nbsp;(throw
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
120&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(ex-info
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
121&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(str&nbsp;&quot;INTEROP:&nbsp;Ne&nbsp;can&nbsp;eahtiende&nbsp;`&quot;&nbsp;result&nbsp;&quot;`&nbsp;to&nbsp;Lisp&nbsp;1.5.&quot;)
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
122&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{:cause&nbsp;&nbsp;:interop
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
123&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:detail&nbsp;:not-representable
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
124&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:result&nbsp;result})))))
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
125&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(throw
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
126&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(ex-info
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
127&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(str&nbsp;&quot;INTEROP&nbsp;ne&nbsp;āfand&nbsp;innan&nbsp;Lisp&nbsp;1.5.&quot;)
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
128&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{:cause&nbsp;&nbsp;:interop
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
129&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:detail&nbsp;:strict}))))
</span><br/>
</body>
</html>

View file

@ -0,0 +1,521 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" href="../coverage.css"/> <title> beowulf/io.clj </title>
</head>
<body>
<span class="covered" title="1 out of 1 forms covered">
001&nbsp;&nbsp;(ns&nbsp;beowulf.io
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
002&nbsp;&nbsp;&nbsp;&nbsp;&quot;Non-standard&nbsp;extensions&nbsp;to&nbsp;Lisp&nbsp;1.5&nbsp;to&nbsp;read&nbsp;and&nbsp;write&nbsp;to&nbsp;the&nbsp;filesystem.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
003&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
004&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Lisp&nbsp;1.5&nbsp;had&nbsp;only&nbsp;`READ`,&nbsp;which&nbsp;read&nbsp;one&nbsp;S-Expression&nbsp;at&nbsp;a&nbsp;time,&nbsp;and&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
005&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;various&nbsp;forms&nbsp;of&nbsp;`PRIN*`&nbsp;functions,&nbsp;which&nbsp;printed&nbsp;to&nbsp;the&nbsp;line&nbsp;printer.&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
006&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;There&nbsp;was&nbsp;also&nbsp;`PUNCH`,&nbsp;which&nbsp;wrote&nbsp;to&nbsp;a&nbsp;card&nbsp;punch.&nbsp;It&nbsp;does&nbsp;not&nbsp;seem&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
007&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;that&nbsp;there&nbsp;was&nbsp;any&nbsp;concept&nbsp;of&nbsp;an&nbsp;interactive&nbsp;terminal.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
008&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
009&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;See&nbsp;Appendix&nbsp;E,&nbsp;`OVERLORD&nbsp;-&nbsp;THE&nbsp;MONITOR`,&nbsp;and&nbsp;Appendix&nbsp;F,&nbsp;`LISP&nbsp;INPUT
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
010&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AND&nbsp;OUTPUT`.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
011&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
012&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;For&nbsp;our&nbsp;purposes,&nbsp;to&nbsp;save&nbsp;the&nbsp;current&nbsp;state&nbsp;of&nbsp;the&nbsp;Lisp&nbsp;system&nbsp;it&nbsp;should
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
013&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;be&nbsp;sufficient&nbsp;to&nbsp;print&nbsp;the&nbsp;current&nbsp;contents&nbsp;of&nbsp;the&nbsp;oblist&nbsp;to&nbsp;file;&nbsp;and&nbsp;to
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
014&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;restore&nbsp;a&nbsp;previous&nbsp;state&nbsp;from&nbsp;file,&nbsp;to&nbsp;overwrite&nbsp;the&nbsp;contents&nbsp;of&nbsp;the&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
015&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;oblist&nbsp;with&nbsp;data&nbsp;from&nbsp;that&nbsp;file.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
016&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
017&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Hence&nbsp;functions&nbsp;SYSOUT&nbsp;and&nbsp;SYSIN,&nbsp;which&nbsp;do&nbsp;just&nbsp;that.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
018&nbsp;&nbsp;&nbsp;&nbsp;(:require&nbsp;[beowulf.cons-cell&nbsp;:refer&nbsp;[make-beowulf-list&nbsp;make-cons-cell
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
019&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pretty-print]]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
020&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[beowulf.host&nbsp;:refer&nbsp;[CADR&nbsp;CAR&nbsp;CDDR&nbsp;CDR]]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
021&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[beowulf.interop&nbsp;:refer&nbsp;[interpret-qualified-name
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
022&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;listify-qualified-name]]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
023&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[beowulf.oblist&nbsp;:refer&nbsp;[*options*&nbsp;NIL&nbsp;oblist]]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
024&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[beowulf.read&nbsp;:refer&nbsp;[READ]]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
025&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[clojure.java.io&nbsp;:refer&nbsp;[file&nbsp;resource]]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
026&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[clojure.string&nbsp;:refer&nbsp;[ends-with?]]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
027&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[java-time.api&nbsp;:refer&nbsp;[local-date&nbsp;local-date-time]]))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
028&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
029&nbsp;&nbsp;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
030&nbsp;&nbsp;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
031&nbsp;&nbsp;;;;&nbsp;Copyright&nbsp;(C)&nbsp;2022-2023&nbsp;Simon&nbsp;Brooke
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
032&nbsp;&nbsp;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
033&nbsp;&nbsp;;;;&nbsp;This&nbsp;program&nbsp;is&nbsp;free&nbsp;software;&nbsp;you&nbsp;can&nbsp;redistribute&nbsp;it&nbsp;and&#x2F;or
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
034&nbsp;&nbsp;;;;&nbsp;modify&nbsp;it&nbsp;under&nbsp;the&nbsp;terms&nbsp;of&nbsp;the&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
035&nbsp;&nbsp;;;;&nbsp;as&nbsp;published&nbsp;by&nbsp;the&nbsp;Free&nbsp;Software&nbsp;Foundation;&nbsp;either&nbsp;version&nbsp;2
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
036&nbsp;&nbsp;;;;&nbsp;of&nbsp;the&nbsp;License,&nbsp;or&nbsp;(at&nbsp;your&nbsp;option)&nbsp;any&nbsp;later&nbsp;version.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
037&nbsp;&nbsp;;;;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
038&nbsp;&nbsp;;;;&nbsp;This&nbsp;program&nbsp;is&nbsp;distributed&nbsp;in&nbsp;the&nbsp;hope&nbsp;that&nbsp;it&nbsp;will&nbsp;be&nbsp;useful,
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
039&nbsp;&nbsp;;;;&nbsp;but&nbsp;WITHOUT&nbsp;ANY&nbsp;WARRANTY;&nbsp;without&nbsp;even&nbsp;the&nbsp;implied&nbsp;warranty&nbsp;of
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
040&nbsp;&nbsp;;;;&nbsp;MERCHANTABILITY&nbsp;or&nbsp;FITNESS&nbsp;FOR&nbsp;A&nbsp;PARTICULAR&nbsp;PURPOSE.&nbsp;&nbsp;See&nbsp;the
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
041&nbsp;&nbsp;;;;&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License&nbsp;for&nbsp;more&nbsp;details.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
042&nbsp;&nbsp;;;;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
043&nbsp;&nbsp;;;;&nbsp;You&nbsp;should&nbsp;have&nbsp;received&nbsp;a&nbsp;copy&nbsp;of&nbsp;the&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
044&nbsp;&nbsp;;;;&nbsp;along&nbsp;with&nbsp;this&nbsp;program;&nbsp;if&nbsp;not,&nbsp;write&nbsp;to&nbsp;the&nbsp;Free&nbsp;Software
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
045&nbsp;&nbsp;;;;&nbsp;Foundation,&nbsp;Inc.,&nbsp;51&nbsp;Franklin&nbsp;Street,&nbsp;Fifth&nbsp;Floor,&nbsp;Boston,&nbsp;MA&nbsp;&nbsp;02110-1301,&nbsp;USA.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
046&nbsp;&nbsp;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
047&nbsp;&nbsp;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
048&nbsp;&nbsp;
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
049&nbsp;&nbsp;(def&nbsp;^:constant&nbsp;default-sysout&nbsp;&quot;lisp1.5.lsp&quot;)
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
050&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
051&nbsp;&nbsp;(defn-&nbsp;full-path
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
052&nbsp;&nbsp;&nbsp;&nbsp;[fp]
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
053&nbsp;&nbsp;&nbsp;&nbsp;(str
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
054&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if&nbsp;(:filepath&nbsp;*options*)
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
055&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(str&nbsp;(:filepath&nbsp;*options*)&nbsp;(java.io.File&#x2F;separator))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
056&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;&quot;)
</span><br/>
<span class="partial" title="12 out of 14 forms covered">
057&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if&nbsp;(and&nbsp;(string?&nbsp;fp)
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
058&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(&gt;&nbsp;(count&nbsp;fp)&nbsp;0)
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
059&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(not=&nbsp;fp&nbsp;&quot;NIL&quot;))
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
060&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fp
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
061&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(str&nbsp;&quot;Sysout-&quot;&nbsp;(local-date)))
</span><br/>
<span class="partial" title="6 out of 7 forms covered">
062&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if&nbsp;(ends-with?&nbsp;fp&nbsp;&quot;.lsp&quot;)
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
063&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
064&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;.lsp&quot;)))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
065&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
066&nbsp;&nbsp;;;&nbsp;(find-var&nbsp;(symbol&nbsp;&quot;beowulf.io&#x2F;SYSIN&quot;))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
067&nbsp;&nbsp;;;&nbsp;(@(resolve&nbsp;(symbol&nbsp;&quot;beowulf.host&#x2F;TIMES&quot;))&nbsp;2&nbsp;2)
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
068&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
069&nbsp;&nbsp;(defn&nbsp;safely-wrap-subr
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
070&nbsp;&nbsp;&nbsp;&nbsp;[entry]
</span><br/>
<span class="not-covered" title="0 out of 7 forms covered">
071&nbsp;&nbsp;&nbsp;&nbsp;(cond&nbsp;(=&nbsp;entry&nbsp;NIL)&nbsp;NIL
</span><br/>
<span class="not-covered" title="0 out of 7 forms covered">
072&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(=&nbsp;(CAR&nbsp;entry)&nbsp;&#x27;SUBR)&nbsp;(make-cons-cell
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
073&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(CAR&nbsp;entry)
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
074&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(make-cons-cell
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
075&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(listify-qualified-name&nbsp;(CADR&nbsp;entry))
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
076&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(CDDR&nbsp;entry)))
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
077&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:else&nbsp;(make-cons-cell
</span><br/>
<span class="not-covered" title="0 out of 8 forms covered">
078&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(CAR&nbsp;entry)&nbsp;(safely-wrap-subr&nbsp;(CDR&nbsp;entry)))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
079&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
080&nbsp;&nbsp;(defn&nbsp;safely-wrap-subrs
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
081&nbsp;&nbsp;&nbsp;&nbsp;[objects]
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
082&nbsp;&nbsp;&nbsp;&nbsp;(make-beowulf-list&nbsp;(map&nbsp;safely-wrap-subr&nbsp;objects)))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
083&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
084&nbsp;&nbsp;(defn&nbsp;SYSOUT
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
085&nbsp;&nbsp;&nbsp;&nbsp;&quot;Dump&nbsp;the&nbsp;current&nbsp;content&nbsp;of&nbsp;the&nbsp;object&nbsp;list&nbsp;to&nbsp;file.&nbsp;If&nbsp;no&nbsp;`filepath`&nbsp;is
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
086&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;specified,&nbsp;a&nbsp;file&nbsp;name&nbsp;will&nbsp;be&nbsp;constructed&nbsp;of&nbsp;the&nbsp;symbol&nbsp;`Sysout`&nbsp;and&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
087&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;the&nbsp;current&nbsp;date.&nbsp;File&nbsp;paths&nbsp;will&nbsp;be&nbsp;considered&nbsp;relative&nbsp;to&nbsp;the&nbsp;filepath
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
088&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;set&nbsp;when&nbsp;starting&nbsp;Lisp.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
089&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
090&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;**NOTE&nbsp;THAT**&nbsp;this&nbsp;is&nbsp;an&nbsp;extension&nbsp;function,&nbsp;not&nbsp;available&nbsp;in&nbsp;strct&nbsp;mode.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
091&nbsp;&nbsp;&nbsp;&nbsp;([]
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
092&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(SYSOUT&nbsp;nil))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
093&nbsp;&nbsp;&nbsp;&nbsp;([filepath]
</span><br/>
<span class="not-covered" title="0 out of 7 forms covered">
094&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(spit&nbsp;(full-path&nbsp;(str&nbsp;filepath))
</span><br/>
<span class="not-covered" title="0 out of 15 forms covered">
095&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(with-out-str
</span><br/>
<span class="not-covered" title="0 out of 9 forms covered">
096&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(println&nbsp;(apply&nbsp;str&nbsp;(repeat&nbsp;79&nbsp;&quot;;&quot;)))
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
097&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(println&nbsp;(format&nbsp;&quot;;;&nbsp;Beowulf&nbsp;%s&nbsp;Sysout&nbsp;file&nbsp;generated&nbsp;at&nbsp;%s&quot;
</span><br/>
<span class="not-covered" title="0 out of 7 forms covered">
098&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(or&nbsp;(System&#x2F;getProperty&nbsp;&quot;beowulf.version&quot;)&nbsp;&quot;&quot;)
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
099&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(local-date-time)))
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
100&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(when&nbsp;(System&#x2F;getenv&nbsp;&quot;USER&quot;)
</span><br/>
<span class="not-covered" title="0 out of 7 forms covered">
101&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(println&nbsp;(format&nbsp;&quot;;;&nbsp;generated&nbsp;by&nbsp;%s&quot;&nbsp;(System&#x2F;getenv&nbsp;&quot;USER&quot;))))
</span><br/>
<span class="not-covered" title="0 out of 9 forms covered">
102&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(println&nbsp;(apply&nbsp;str&nbsp;(repeat&nbsp;79&nbsp;&quot;;&quot;)))
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
103&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(println)
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
104&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[output&nbsp;(safely-wrap-subrs&nbsp;@oblist)]
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
105&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(pretty-print&nbsp;output)
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
106&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;)))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
107&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
108&nbsp;&nbsp;(defn&nbsp;resolve-subr
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
109&nbsp;&nbsp;&nbsp;&nbsp;&quot;If&nbsp;this&nbsp;oblist&nbsp;`entry`&nbsp;references&nbsp;a&nbsp;subroutine,&nbsp;attempt&nbsp;to&nbsp;fix&nbsp;up&nbsp;that
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
110&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reference.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
111&nbsp;&nbsp;&nbsp;&nbsp;([entry]
</span><br/>
<span class="partial" title="9 out of 12 forms covered">
112&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(or&nbsp;(resolve-subr&nbsp;entry&nbsp;&#x27;SUBR)
</span><br/>
<span class="partial" title="1 out of 6 forms covered">
113&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(resolve-subr&nbsp;entry&nbsp;&#x27;FSUBR)))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
114&nbsp;&nbsp;&nbsp;&nbsp;([entry&nbsp;prop]
</span><br/>
<span class="covered" title="7 out of 7 forms covered">
115&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cond&nbsp;(=&nbsp;entry&nbsp;NIL)&nbsp;NIL
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
116&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(=&nbsp;(CAR&nbsp;entry)&nbsp;prop)&nbsp;(try
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
117&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(make-cons-cell
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
118&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(CAR&nbsp;entry)
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
119&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(make-cons-cell
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
120&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(interpret-qualified-name
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
121&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(CADR&nbsp;entry))
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
122&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(CDDR&nbsp;entry)))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
123&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(catch&nbsp;Exception&nbsp;_
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
124&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(print&nbsp;&quot;Warnung:&nbsp;ne&nbsp;can&nbsp;āfinde&nbsp;&quot;
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
125&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(CADR&nbsp;entry))
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
126&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(CDDR&nbsp;entry)))
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
127&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:else&nbsp;(make-cons-cell
</span><br/>
<span class="covered" title="8 out of 8 forms covered">
128&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(CAR&nbsp;entry)&nbsp;(resolve-subr&nbsp;(CDR&nbsp;entry))))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
129&nbsp;&nbsp;
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
130&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
131&nbsp;&nbsp;(defn-&nbsp;resolve-subroutines
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
132&nbsp;&nbsp;&nbsp;&nbsp;&quot;Attempt&nbsp;to&nbsp;fix&nbsp;up&nbsp;the&nbsp;references&nbsp;to&nbsp;subroutines&nbsp;(Clojure&nbsp;functions)&nbsp;among
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
133&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;these&nbsp;`objects`,&nbsp;being&nbsp;new&nbsp;content&nbsp;for&nbsp;the&nbsp;object&nbsp;list.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
134&nbsp;&nbsp;&nbsp;&nbsp;[objects]
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
135&nbsp;&nbsp;&nbsp;&nbsp;(make-beowulf-list
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
136&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
137&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;resolve-subr
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
138&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;objects)))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
139&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
140&nbsp;&nbsp;(defn&nbsp;SYSIN
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
141&nbsp;&nbsp;&nbsp;&nbsp;&quot;Read&nbsp;the&nbsp;contents&nbsp;of&nbsp;the&nbsp;file&nbsp;at&nbsp;this&nbsp;`filename`&nbsp;into&nbsp;the&nbsp;object&nbsp;list.&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
142&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
143&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;If&nbsp;the&nbsp;file&nbsp;is&nbsp;not&nbsp;a&nbsp;valid&nbsp;Beowulf&nbsp;sysout&nbsp;file,&nbsp;this&nbsp;will&nbsp;probably&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
144&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;corrupt&nbsp;the&nbsp;system,&nbsp;you&nbsp;have&nbsp;been&nbsp;warned.&nbsp;File&nbsp;paths&nbsp;will&nbsp;be&nbsp;considered&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
145&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;relative&nbsp;to&nbsp;the&nbsp;filepath&nbsp;set&nbsp;when&nbsp;starting&nbsp;Lisp.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
146&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
147&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;It&nbsp;is&nbsp;intended&nbsp;that&nbsp;sysout&nbsp;files&nbsp;can&nbsp;be&nbsp;read&nbsp;both&nbsp;from&nbsp;resources&nbsp;within
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
148&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;the&nbsp;jar&nbsp;file,&nbsp;and&nbsp;from&nbsp;the&nbsp;file&nbsp;system.&nbsp;If&nbsp;a&nbsp;named&nbsp;file&nbsp;exists&nbsp;in&nbsp;both&nbsp;the
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
149&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;file&nbsp;system&nbsp;and&nbsp;the&nbsp;resources,&nbsp;the&nbsp;file&nbsp;system&nbsp;will&nbsp;be&nbsp;preferred.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
150&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
151&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;**NOTE&nbsp;THAT**&nbsp;if&nbsp;the&nbsp;provided&nbsp;`filename`&nbsp;does&nbsp;not&nbsp;end&nbsp;with&nbsp;`.lsp`&nbsp;(which,
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
152&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;you&#x27;re&nbsp;writing&nbsp;it&nbsp;from&nbsp;the&nbsp;Lisp&nbsp;REPL,&nbsp;it&nbsp;won&#x27;t),&nbsp;the&nbsp;extension&nbsp;`.lsp`
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
153&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;will&nbsp;be&nbsp;appended.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
154&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
155&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;**NOTE&nbsp;THAT**&nbsp;this&nbsp;is&nbsp;an&nbsp;extension&nbsp;function,&nbsp;not&nbsp;available&nbsp;in&nbsp;strct&nbsp;mode.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
156&nbsp;&nbsp;&nbsp;&nbsp;([]
</span><br/>
<span class="not-covered" title="0 out of 13 forms covered">
157&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(SYSIN&nbsp;(or&nbsp;(:read&nbsp;*options*)&nbsp;(str&nbsp;&quot;resources&#x2F;&quot;&nbsp;default-sysout))))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
158&nbsp;&nbsp;&nbsp;&nbsp;([filename]
</span><br/>
<span class="covered" title="8 out of 8 forms covered">
159&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[fp&nbsp;(file&nbsp;(full-path&nbsp;(str&nbsp;filename)))
</span><br/>
<span class="covered" title="9 out of 9 forms covered">
160&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;file&nbsp;(when&nbsp;(and&nbsp;(.exists&nbsp;fp)&nbsp;(.canRead&nbsp;fp))&nbsp;fp)
</span><br/>
<span class="partial" title="4 out of 5 forms covered">
161&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;res&nbsp;(try&nbsp;(resource&nbsp;filename)
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
162&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(catch&nbsp;Throwable&nbsp;_&nbsp;nil))
</span><br/>
<span class="covered" title="11 out of 11 forms covered">
163&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;content&nbsp;(try&nbsp;(READ&nbsp;(slurp&nbsp;(or&nbsp;file&nbsp;res)))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
164&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(catch&nbsp;Throwable&nbsp;_
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
165&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(throw&nbsp;(ex-info&nbsp;&quot;Ne&nbsp;can&nbsp;ārǣde&quot;
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
166&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{:context&nbsp;&quot;SYSIN&quot;
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
167&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:filename&nbsp;filename
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
168&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:filepath&nbsp;fp}))))]
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
169&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(swap!&nbsp;oblist
</span><br/>
<span class="partial" title="7 out of 10 forms covered">
170&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#(when&nbsp;(or&nbsp;%&nbsp;(seq&nbsp;content))
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
171&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(resolve-subroutines&nbsp;content))))))
</span><br/>
</body>
</html>

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,143 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" href="../coverage.css"/> <title> beowulf/oblist.clj </title>
</head>
<body>
<span class="covered" title="1 out of 1 forms covered">
001&nbsp;&nbsp;(ns&nbsp;beowulf.oblist
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
002&nbsp;&nbsp;&nbsp;&nbsp;&quot;A&nbsp;namespace&nbsp;mainly&nbsp;devoted&nbsp;to&nbsp;the&nbsp;object&nbsp;list&nbsp;and&nbsp;other&nbsp;top&nbsp;level
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
003&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;global&nbsp;variables.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
004&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
005&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Yes,&nbsp;this&nbsp;makes&nbsp;little&nbsp;sense,&nbsp;but&nbsp;if&nbsp;you&nbsp;put&nbsp;them&nbsp;anywhere&nbsp;else&nbsp;you&nbsp;end
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
006&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;up&nbsp;in&nbsp;cyclic&nbsp;dependency&nbsp;hell.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
007&nbsp;&nbsp;&nbsp;&nbsp;)
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
008&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
009&nbsp;&nbsp;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
010&nbsp;&nbsp;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
011&nbsp;&nbsp;;;;&nbsp;Copyright&nbsp;(C)&nbsp;2022-2023&nbsp;Simon&nbsp;Brooke
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
012&nbsp;&nbsp;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
013&nbsp;&nbsp;;;;&nbsp;This&nbsp;program&nbsp;is&nbsp;free&nbsp;software;&nbsp;you&nbsp;can&nbsp;redistribute&nbsp;it&nbsp;and&#x2F;or
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
014&nbsp;&nbsp;;;;&nbsp;modify&nbsp;it&nbsp;under&nbsp;the&nbsp;terms&nbsp;of&nbsp;the&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
015&nbsp;&nbsp;;;;&nbsp;as&nbsp;published&nbsp;by&nbsp;the&nbsp;Free&nbsp;Software&nbsp;Foundation;&nbsp;either&nbsp;version&nbsp;2
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
016&nbsp;&nbsp;;;;&nbsp;of&nbsp;the&nbsp;License,&nbsp;or&nbsp;(at&nbsp;your&nbsp;option)&nbsp;any&nbsp;later&nbsp;version.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
017&nbsp;&nbsp;;;;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
018&nbsp;&nbsp;;;;&nbsp;This&nbsp;program&nbsp;is&nbsp;distributed&nbsp;in&nbsp;the&nbsp;hope&nbsp;that&nbsp;it&nbsp;will&nbsp;be&nbsp;useful,
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
019&nbsp;&nbsp;;;;&nbsp;but&nbsp;WITHOUT&nbsp;ANY&nbsp;WARRANTY;&nbsp;without&nbsp;even&nbsp;the&nbsp;implied&nbsp;warranty&nbsp;of
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
020&nbsp;&nbsp;;;;&nbsp;MERCHANTABILITY&nbsp;or&nbsp;FITNESS&nbsp;FOR&nbsp;A&nbsp;PARTICULAR&nbsp;PURPOSE.&nbsp;&nbsp;See&nbsp;the
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
021&nbsp;&nbsp;;;;&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License&nbsp;for&nbsp;more&nbsp;details.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
022&nbsp;&nbsp;;;;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
023&nbsp;&nbsp;;;;&nbsp;You&nbsp;should&nbsp;have&nbsp;received&nbsp;a&nbsp;copy&nbsp;of&nbsp;the&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
024&nbsp;&nbsp;;;;&nbsp;along&nbsp;with&nbsp;this&nbsp;program;&nbsp;if&nbsp;not,&nbsp;write&nbsp;to&nbsp;the&nbsp;Free&nbsp;Software
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
025&nbsp;&nbsp;;;;&nbsp;Foundation,&nbsp;Inc.,&nbsp;51&nbsp;Franklin&nbsp;Street,&nbsp;Fifth&nbsp;Floor,&nbsp;Boston,&nbsp;MA&nbsp;&nbsp;02110-1301,&nbsp;USA.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
026&nbsp;&nbsp;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
027&nbsp;&nbsp;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
028&nbsp;&nbsp;
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
029&nbsp;&nbsp;(def&nbsp;NIL
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
030&nbsp;&nbsp;&nbsp;&nbsp;&quot;The&nbsp;canonical&nbsp;empty&nbsp;list&nbsp;symbol.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
031&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
032&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TODO:&nbsp;this&nbsp;doesn&#x27;t&nbsp;really&nbsp;work,&nbsp;because&nbsp;(from&nbsp;Clojure)&nbsp;`(empty?&nbsp;NIL)`&nbsp;throws
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
033&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;an&nbsp;exception.&nbsp;It&nbsp;might&nbsp;be&nbsp;better&nbsp;to&nbsp;subclass&nbsp;beowulf.cons_cell.ConsCell&nbsp;to&nbsp;create
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
034&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a&nbsp;new&nbsp;singleton&nbsp;class&nbsp;Nil&nbsp;which&nbsp;overrides&nbsp;the&nbsp;`empty`&nbsp;method&nbsp;of&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
035&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IPersistentCollection?&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
036&nbsp;&nbsp;&nbsp;&nbsp;&#x27;NIL)
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
037&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
038&nbsp;&nbsp;(def&nbsp;oblist
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
039&nbsp;&nbsp;&nbsp;&nbsp;&quot;The&nbsp;default&nbsp;environment.&quot;
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
040&nbsp;&nbsp;&nbsp;&nbsp;(atom&nbsp;NIL))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
041&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
042&nbsp;&nbsp;(def&nbsp;^:dynamic&nbsp;*options*
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
043&nbsp;&nbsp;&nbsp;&nbsp;&quot;Command&nbsp;line&nbsp;options&nbsp;from&nbsp;invocation.&quot;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
044&nbsp;&nbsp;&nbsp;&nbsp;{})
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
045&nbsp;&nbsp;
</span><br/>
</body>
</html>

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,233 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" href="../../coverage.css"/> <title> beowulf/reader/char_reader.clj </title>
</head>
<body>
<span class="covered" title="1 out of 1 forms covered">
001&nbsp;&nbsp;(ns&nbsp;beowulf.reader.char-reader
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
002&nbsp;&nbsp;&nbsp;&nbsp;&quot;Provide&nbsp;sensible&nbsp;line&nbsp;editing,&nbsp;auto&nbsp;completion,&nbsp;and&nbsp;history&nbsp;recall.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
003&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
004&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;None&nbsp;of&nbsp;what&#x27;s&nbsp;needed&nbsp;here&nbsp;is&nbsp;really&nbsp;working&nbsp;yet,&nbsp;and&nbsp;a&nbsp;pull&nbsp;request&nbsp;with
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
005&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a&nbsp;working&nbsp;implementation&nbsp;would&nbsp;be&nbsp;greatly&nbsp;welcomed.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
006&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
007&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;##&nbsp;What&#x27;s&nbsp;needed&nbsp;(rough&nbsp;specification)
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
008&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
009&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1.&nbsp;Carriage&nbsp;return&nbsp;**does&nbsp;not**&nbsp;cause&nbsp;input&nbsp;to&nbsp;be&nbsp;returned,&nbsp;**unless**
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
010&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a.&nbsp;the&nbsp;number&nbsp;of&nbsp;open&nbsp;brackets&nbsp;`(`&nbsp;and&nbsp;closing&nbsp;brackets&nbsp;`)`&nbsp;match;&nbsp;and
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
011&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b.&nbsp;the&nbsp;number&nbsp;of&nbsp;open&nbsp;square&nbsp;brackets&nbsp;`[`&nbsp;and&nbsp;closing&nbsp;square&nbsp;brackets&nbsp;`]`&nbsp;also&nbsp;match;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
012&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2.&nbsp;&lt;Ctrl-D&gt;&nbsp;aborts&nbsp;editing&nbsp;and&nbsp;returns&nbsp;the&nbsp;string&nbsp;`STOP`;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
013&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3.&nbsp;&lt;Up-arrow&gt;&nbsp;and&nbsp;&lt;down-arrow&gt;&nbsp;scroll&nbsp;back&nbsp;and&nbsp;forward&nbsp;through&nbsp;history,&nbsp;but&nbsp;ideally&nbsp;I&#x27;d&nbsp;like&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
014&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this&nbsp;to&nbsp;be&nbsp;the&nbsp;Lisp&nbsp;history&nbsp;(i.e.&nbsp;the&nbsp;history&nbsp;of&nbsp;S-Expressions&nbsp;actually&nbsp;read&nbsp;by&nbsp;`READ`,&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
015&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rather&nbsp;than&nbsp;the&nbsp;strings&nbsp;which&nbsp;were&nbsp;supplied&nbsp;to&nbsp;`READ`);
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
016&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4.&nbsp;&lt;Tab&gt;&nbsp;offers&nbsp;potential&nbsp;auto-completions&nbsp;taken&nbsp;from&nbsp;the&nbsp;value&nbsp;of&nbsp;`(OBLIST)`,&nbsp;ideally&nbsp;the
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
017&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;current&nbsp;value,&nbsp;not&nbsp;the&nbsp;value&nbsp;at&nbsp;the&nbsp;time&nbsp;the&nbsp;session&nbsp;started;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
018&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;5.&nbsp;&lt;Back-arrow&gt;&nbsp;and&nbsp;&lt;Forward-arrow&gt;&nbsp;offer&nbsp;movement&nbsp;and&nbsp;editing&nbsp;within&nbsp;the&nbsp;line.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
019&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
020&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TODO:&nbsp;There&nbsp;are&nbsp;multiple&nbsp;problems&nbsp;with&nbsp;JLine;&nbsp;a&nbsp;better&nbsp;solution&nbsp;might&nbsp;be
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
021&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;to&nbsp;start&nbsp;from&nbsp;here:
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
022&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;7931988&#x2F;how-to-manipulate-control-characters&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
023&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;(:import&nbsp;[org.jline.reader&nbsp;LineReader&nbsp;LineReaderBuilder]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
024&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[org.jline.terminal&nbsp;TerminalBuilder])
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
025&nbsp;&nbsp;&nbsp;&nbsp;)
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
026&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
027&nbsp;&nbsp;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
028&nbsp;&nbsp;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
029&nbsp;&nbsp;;;;&nbsp;Copyright&nbsp;(C)&nbsp;2022-2023&nbsp;Simon&nbsp;Brooke
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
030&nbsp;&nbsp;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
031&nbsp;&nbsp;;;;&nbsp;This&nbsp;program&nbsp;is&nbsp;free&nbsp;software;&nbsp;you&nbsp;can&nbsp;redistribute&nbsp;it&nbsp;and&#x2F;or
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
032&nbsp;&nbsp;;;;&nbsp;modify&nbsp;it&nbsp;under&nbsp;the&nbsp;terms&nbsp;of&nbsp;the&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
033&nbsp;&nbsp;;;;&nbsp;as&nbsp;published&nbsp;by&nbsp;the&nbsp;Free&nbsp;Software&nbsp;Foundation;&nbsp;either&nbsp;version&nbsp;2
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
034&nbsp;&nbsp;;;;&nbsp;of&nbsp;the&nbsp;License,&nbsp;or&nbsp;(at&nbsp;your&nbsp;option)&nbsp;any&nbsp;later&nbsp;version.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
035&nbsp;&nbsp;;;;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
036&nbsp;&nbsp;;;;&nbsp;This&nbsp;program&nbsp;is&nbsp;distributed&nbsp;in&nbsp;the&nbsp;hope&nbsp;that&nbsp;it&nbsp;will&nbsp;be&nbsp;useful,
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
037&nbsp;&nbsp;;;;&nbsp;but&nbsp;WITHOUT&nbsp;ANY&nbsp;WARRANTY;&nbsp;without&nbsp;even&nbsp;the&nbsp;implied&nbsp;warranty&nbsp;of
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
038&nbsp;&nbsp;;;;&nbsp;MERCHANTABILITY&nbsp;or&nbsp;FITNESS&nbsp;FOR&nbsp;A&nbsp;PARTICULAR&nbsp;PURPOSE.&nbsp;&nbsp;See&nbsp;the
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
039&nbsp;&nbsp;;;;&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License&nbsp;for&nbsp;more&nbsp;details.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
040&nbsp;&nbsp;;;;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
041&nbsp;&nbsp;;;;&nbsp;You&nbsp;should&nbsp;have&nbsp;received&nbsp;a&nbsp;copy&nbsp;of&nbsp;the&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
042&nbsp;&nbsp;;;;&nbsp;along&nbsp;with&nbsp;this&nbsp;program;&nbsp;if&nbsp;not,&nbsp;write&nbsp;to&nbsp;the&nbsp;Free&nbsp;Software
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
043&nbsp;&nbsp;;;;&nbsp;Foundation,&nbsp;Inc.,&nbsp;51&nbsp;Franklin&nbsp;Street,&nbsp;Fifth&nbsp;Floor,&nbsp;Boston,&nbsp;MA&nbsp;&nbsp;02110-1301,&nbsp;USA.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
044&nbsp;&nbsp;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
045&nbsp;&nbsp;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
046&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
047&nbsp;&nbsp;;;&nbsp;It&nbsp;looks&nbsp;from&nbsp;the&nbsp;example&nbsp;given&nbsp;[here](https:&#x2F;&#x2F;github.com&#x2F;jline&#x2F;jline3&#x2F;blob&#x2F;master&#x2F;demo&#x2F;src&#x2F;main&#x2F;java&#x2F;org&#x2F;jline&#x2F;demo&#x2F;Repl.java)
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
048&nbsp;&nbsp;;;&nbsp;as&nbsp;though&nbsp;JLine&nbsp;could&nbsp;be&nbsp;used&nbsp;to&nbsp;build&nbsp;a&nbsp;perfect&nbsp;line-reader&nbsp;for&nbsp;Beowulf;&nbsp;but&nbsp;it&nbsp;also
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
049&nbsp;&nbsp;;;&nbsp;looks&nbsp;as&nbsp;though&nbsp;you&#x27;d&nbsp;need&nbsp;a&nbsp;DPhil&nbsp;in&nbsp;JLine&nbsp;to&nbsp;write&nbsp;it,&nbsp;and&nbsp;I&nbsp;don&#x27;t&nbsp;have
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
050&nbsp;&nbsp;;;&nbsp;the&nbsp;time.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
051&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
052&nbsp;&nbsp;;;&nbsp;(def&nbsp;get-reader
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
053&nbsp;&nbsp;;;&nbsp;&nbsp;&nbsp;&quot;Return&nbsp;a&nbsp;reader,&nbsp;first&nbsp;constructing&nbsp;it&nbsp;if&nbsp;necessary.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
054&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
055&nbsp;&nbsp;;;&nbsp;&nbsp;&nbsp;&nbsp;**NOTE&nbsp;THAT**&nbsp;this&nbsp;is&nbsp;not&nbsp;settled&nbsp;API.&nbsp;The&nbsp;existence&nbsp;and&nbsp;call&nbsp;signature&nbsp;of
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
056&nbsp;&nbsp;;;&nbsp;&nbsp;&nbsp;&nbsp;this&nbsp;function&nbsp;is&nbsp;not&nbsp;guaranteed&nbsp;in&nbsp;future&nbsp;versions.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
057&nbsp;&nbsp;;;&nbsp;&nbsp;&nbsp;(memoize&nbsp;(fn&nbsp;[]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
058&nbsp;&nbsp;;;&nbsp;&nbsp;&nbsp;(let&nbsp;[term&nbsp;(.build&nbsp;(.system&nbsp;(TerminalBuilder&#x2F;builder)&nbsp;true))]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
059&nbsp;&nbsp;;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(.build&nbsp;(.terminal&nbsp;(LineReaderBuilder&#x2F;builder)&nbsp;term))))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
060&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
061&nbsp;&nbsp;;;&nbsp;(defn&nbsp;read-chars
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
062&nbsp;&nbsp;;;&nbsp;&nbsp;&nbsp;&quot;A&nbsp;drop-in&nbsp;replacement&nbsp;for&nbsp;`clojure.core&#x2F;read-line`,&nbsp;except&nbsp;that&nbsp;line&nbsp;editing
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
063&nbsp;&nbsp;;;&nbsp;&nbsp;&nbsp;&nbsp;and&nbsp;history&nbsp;should&nbsp;be&nbsp;enabled.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
064&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
065&nbsp;&nbsp;;;&nbsp;&nbsp;&nbsp;&nbsp;**NOTE&nbsp;THAT**&nbsp;this&nbsp;does&nbsp;not&nbsp;work&nbsp;yet,&nbsp;but&nbsp;it&nbsp;is&nbsp;in&nbsp;the&nbsp;API&nbsp;because&nbsp;I&nbsp;hope&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
066&nbsp;&nbsp;;;&nbsp;&nbsp;&nbsp;&nbsp;that&nbsp;it&nbsp;will&nbsp;work&nbsp;later!&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
067&nbsp;&nbsp;;;&nbsp;&nbsp;&nbsp;[]&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
068&nbsp;&nbsp;;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[eddie&nbsp;(get-reader)]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
069&nbsp;&nbsp;;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(loop&nbsp;[s&nbsp;(.readLine&nbsp;eddie)]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
070&nbsp;&nbsp;;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if&nbsp;(and&nbsp;(=&nbsp;(count&nbsp;(re-seq&nbsp;#&quot;\(&quot;&nbsp;s))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
071&nbsp;&nbsp;;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(count&nbsp;(re-seq&nbsp;#&quot;\)&quot;&nbsp;s)))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
072&nbsp;&nbsp;;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(=&nbsp;(count&nbsp;(re-seq&nbsp;#&quot;\[]&quot;&nbsp;s))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
073&nbsp;&nbsp;;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(count&nbsp;(re-seq&nbsp;#&quot;\]&quot;&nbsp;s))))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
074&nbsp;&nbsp;;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
075&nbsp;&nbsp;;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(recur&nbsp;(str&nbsp;s&nbsp;&quot;&nbsp;&quot;&nbsp;(.readLine&nbsp;eddie)))))))
</span><br/>
</body>
</html>

View file

@ -0,0 +1,836 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" href="../../coverage.css"/> <title> beowulf/reader/generate.clj </title>
</head>
<body>
<span class="covered" title="1 out of 1 forms covered">
001&nbsp;&nbsp;(ns&nbsp;beowulf.reader.generate
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
002&nbsp;&nbsp;&nbsp;&nbsp;&quot;Generating&nbsp;S-Expressions&nbsp;from&nbsp;parse&nbsp;trees.&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
003&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
004&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;##&nbsp;From&nbsp;Lisp&nbsp;1.5&nbsp;Programmers&nbsp;Manual,&nbsp;page&nbsp;10
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
005&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*Note&nbsp;that&nbsp;I&#x27;ve&nbsp;retyped&nbsp;much&nbsp;of&nbsp;this,&nbsp;since&nbsp;copy&#x2F;pasting&nbsp;out&nbsp;of&nbsp;PDF&nbsp;is&nbsp;less
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
006&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;than&nbsp;reliable.&nbsp;Any&nbsp;typos&nbsp;are&nbsp;mine.*
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
007&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
008&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*Quote&nbsp;starts:*
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
009&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
010&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;We&nbsp;are&nbsp;now&nbsp;in&nbsp;a&nbsp;position&nbsp;to&nbsp;define&nbsp;the&nbsp;universal&nbsp;LISP&nbsp;function
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
011&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`evalquote[fn;args]`,&nbsp;When&nbsp;evalquote&nbsp;is&nbsp;given&nbsp;a&nbsp;function&nbsp;and&nbsp;a&nbsp;list&nbsp;of&nbsp;arguments
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
012&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;that&nbsp;function,&nbsp;it&nbsp;computes&nbsp;the&nbsp;value&nbsp;of&nbsp;the&nbsp;function&nbsp;applied&nbsp;to&nbsp;the&nbsp;arguments.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
013&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LISP&nbsp;functions&nbsp;have&nbsp;S-expressions&nbsp;as&nbsp;arguments.&nbsp;In&nbsp;particular,&nbsp;the&nbsp;argument&nbsp;`fn`
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
014&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;of&nbsp;the&nbsp;function&nbsp;evalquote&nbsp;must&nbsp;be&nbsp;an&nbsp;S-expression.&nbsp;Since&nbsp;we&nbsp;have&nbsp;been
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
015&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;writing&nbsp;functions&nbsp;as&nbsp;M-expressions,&nbsp;it&nbsp;is&nbsp;necessary&nbsp;to&nbsp;translate&nbsp;them&nbsp;into
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
016&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;S-expressions.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
017&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
018&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The&nbsp;following&nbsp;rules&nbsp;define&nbsp;a&nbsp;method&nbsp;of&nbsp;translating&nbsp;functions&nbsp;written&nbsp;in&nbsp;the
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
019&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;meta-language&nbsp;into&nbsp;S-expressions.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
020&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1.&nbsp;If&nbsp;the&nbsp;function&nbsp;is&nbsp;represented&nbsp;by&nbsp;its&nbsp;name,&nbsp;it&nbsp;is&nbsp;translated&nbsp;by&nbsp;changing
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
021&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;all&nbsp;of&nbsp;the&nbsp;letters&nbsp;to&nbsp;upper&nbsp;case,&nbsp;making&nbsp;it&nbsp;an&nbsp;atomic&nbsp;symbol.&nbsp;Thus&nbsp;`car`&nbsp;is&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
022&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;translated&nbsp;to&nbsp;`CAR`.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
023&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2.&nbsp;If&nbsp;the&nbsp;function&nbsp;uses&nbsp;the&nbsp;lambda&nbsp;notation,&nbsp;then&nbsp;the&nbsp;expression
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
024&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`λ[[x&nbsp;..;xn];&nbsp;ε]`&nbsp;is&nbsp;translated&nbsp;into&nbsp;`(LAMBDA&nbsp;(X1&nbsp;...XN)&nbsp;ε*)`,&nbsp;where&nbsp;ε*&nbsp;is&nbsp;the&nbsp;translation
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
025&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;of&nbsp;ε.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
026&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3.&nbsp;If&nbsp;the&nbsp;function&nbsp;begins&nbsp;with&nbsp;label,&nbsp;then&nbsp;the&nbsp;translation&nbsp;of
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
027&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`label[α;ε]`&nbsp;is&nbsp;`(LABEL&nbsp;α*&nbsp;ε*)`.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
028&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
029&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Forms&nbsp;are&nbsp;translated&nbsp;as&nbsp;follows:
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
030&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1.&nbsp;A&nbsp;variable,&nbsp;like&nbsp;a&nbsp;function&nbsp;name,&nbsp;is&nbsp;translated&nbsp;by&nbsp;using&nbsp;uppercase&nbsp;letters.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
031&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Thus&nbsp;the&nbsp;translation&nbsp;of&nbsp;`var1`&nbsp;is&nbsp;`VAR1`.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
032&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2.&nbsp;The&nbsp;obvious&nbsp;translation&nbsp;of&nbsp;letting&nbsp;a&nbsp;constant&nbsp;translate&nbsp;into&nbsp;itself&nbsp;will&nbsp;not
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
033&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;work.&nbsp;Since&nbsp;the&nbsp;translation&nbsp;of&nbsp;`x`&nbsp;is&nbsp;`X`,&nbsp;the&nbsp;translation&nbsp;of&nbsp;`X`&nbsp;must&nbsp;be&nbsp;something
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
034&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;to&nbsp;avoid&nbsp;ambiguity.&nbsp;The&nbsp;solution&nbsp;is&nbsp;to&nbsp;quote&nbsp;it.&nbsp;Thus&nbsp;`X`&nbsp;is&nbsp;translated
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
035&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;into&nbsp;`(QUOTE&nbsp;X)`.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
036&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3.&nbsp;The&nbsp;form&nbsp;`fn[argl;.&nbsp;..;argn]`&nbsp;is&nbsp;translated&nbsp;into&nbsp;`(fn*&nbsp;argl*&nbsp;...argn*)`
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
037&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4.&nbsp;The&nbsp;conditional&nbsp;expression&nbsp;`[pl-el;...;pn-en]`&nbsp;is&nbsp;translated&nbsp;into
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
038&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`(COND&nbsp;(p1*&nbsp;e1*)...(pn*&nbsp;en*))`
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
039&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
040&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;##&nbsp;Examples
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
041&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;```
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
042&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;M-expressions&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;S-expressions&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
043&nbsp;&nbsp;&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
044&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;x&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;X&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
045&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;car&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CAR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
046&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;car[x]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(CAR&nbsp;X)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
047&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;T&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(QUOTE&nbsp;T)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
048&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ff[car&nbsp;[x]]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(FF&nbsp;(CAR&nbsp;X))&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
049&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[atom[x]-&gt;x;&nbsp;T-&gt;ff[car[x]]]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(COND&nbsp;((ATOM&nbsp;X)&nbsp;X)&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
050&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;((QUOTE&nbsp;T)(FF&nbsp;(CAR&nbsp;X))))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
051&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;label[ff;λ[[x];[atom[x]-&gt;x;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(LABEL&nbsp;FF&nbsp;(LAMBDA&nbsp;(X)&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
052&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;T-&gt;ff[car[x]]]]]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(COND&nbsp;((ATOM&nbsp;X)&nbsp;X)&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
053&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;((QUOTE&nbsp;T)(FF&nbsp;(CAR&nbsp;X))))))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
054&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;```
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
055&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
056&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*quote&nbsp;ends*
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
057&nbsp;&nbsp;&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
058&nbsp;&nbsp;&nbsp;&nbsp;(:require&nbsp;[beowulf.cons-cell&nbsp;:refer&nbsp;[make-beowulf-list&nbsp;make-cons-cell]]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
059&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[beowulf.reader.macros&nbsp;:refer&nbsp;[expand-macros]]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
060&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[beowulf.oblist&nbsp;:refer&nbsp;[NIL]]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
061&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[clojure.math.numeric-tower&nbsp;:refer&nbsp;[expt]]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
062&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[clojure.string&nbsp;:refer&nbsp;[upper-case]]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
063&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[clojure.tools.trace&nbsp;:refer&nbsp;[deftrace]]))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
064&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
065&nbsp;&nbsp;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
066&nbsp;&nbsp;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
067&nbsp;&nbsp;;;;&nbsp;Copyright&nbsp;(C)&nbsp;2022-2023&nbsp;Simon&nbsp;Brooke
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
068&nbsp;&nbsp;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
069&nbsp;&nbsp;;;;&nbsp;This&nbsp;program&nbsp;is&nbsp;free&nbsp;software;&nbsp;you&nbsp;can&nbsp;redistribute&nbsp;it&nbsp;and&#x2F;or
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
070&nbsp;&nbsp;;;;&nbsp;modify&nbsp;it&nbsp;under&nbsp;the&nbsp;terms&nbsp;of&nbsp;the&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
071&nbsp;&nbsp;;;;&nbsp;as&nbsp;published&nbsp;by&nbsp;the&nbsp;Free&nbsp;Software&nbsp;Foundation;&nbsp;either&nbsp;version&nbsp;2
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
072&nbsp;&nbsp;;;;&nbsp;of&nbsp;the&nbsp;License,&nbsp;or&nbsp;(at&nbsp;your&nbsp;option)&nbsp;any&nbsp;later&nbsp;version.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
073&nbsp;&nbsp;;;;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
074&nbsp;&nbsp;;;;&nbsp;This&nbsp;program&nbsp;is&nbsp;distributed&nbsp;in&nbsp;the&nbsp;hope&nbsp;that&nbsp;it&nbsp;will&nbsp;be&nbsp;useful,
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
075&nbsp;&nbsp;;;;&nbsp;but&nbsp;WITHOUT&nbsp;ANY&nbsp;WARRANTY;&nbsp;without&nbsp;even&nbsp;the&nbsp;implied&nbsp;warranty&nbsp;of
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
076&nbsp;&nbsp;;;;&nbsp;MERCHANTABILITY&nbsp;or&nbsp;FITNESS&nbsp;FOR&nbsp;A&nbsp;PARTICULAR&nbsp;PURPOSE.&nbsp;&nbsp;See&nbsp;the
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
077&nbsp;&nbsp;;;;&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License&nbsp;for&nbsp;more&nbsp;details.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
078&nbsp;&nbsp;;;;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
079&nbsp;&nbsp;;;;&nbsp;You&nbsp;should&nbsp;have&nbsp;received&nbsp;a&nbsp;copy&nbsp;of&nbsp;the&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
080&nbsp;&nbsp;;;;&nbsp;along&nbsp;with&nbsp;this&nbsp;program;&nbsp;if&nbsp;not,&nbsp;write&nbsp;to&nbsp;the&nbsp;Free&nbsp;Software
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
081&nbsp;&nbsp;;;;&nbsp;Foundation,&nbsp;Inc.,&nbsp;51&nbsp;Franklin&nbsp;Street,&nbsp;Fifth&nbsp;Floor,&nbsp;Boston,&nbsp;MA&nbsp;&nbsp;02110-1301,&nbsp;USA.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
082&nbsp;&nbsp;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
083&nbsp;&nbsp;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
084&nbsp;&nbsp;
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
085&nbsp;&nbsp;(declare&nbsp;generate)
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
086&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
087&nbsp;&nbsp;(defn&nbsp;gen-cond-clause
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
088&nbsp;&nbsp;&nbsp;&nbsp;&quot;Generate&nbsp;a&nbsp;cond&nbsp;clause&nbsp;from&nbsp;this&nbsp;simplified&nbsp;parse&nbsp;tree&nbsp;fragment&nbsp;`p`;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
089&nbsp;&nbsp;&nbsp;&nbsp;returns&nbsp;`nil`&nbsp;if&nbsp;`p`&nbsp;does&nbsp;not&nbsp;represent&nbsp;a&nbsp;cond&nbsp;clause.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
090&nbsp;&nbsp;&nbsp;&nbsp;[p&nbsp;context]
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
091&nbsp;&nbsp;&nbsp;&nbsp;(when
</span><br/>
<span class="partial" title="11 out of 12 forms covered">
092&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(and&nbsp;(coll?&nbsp;p)&nbsp;(=&nbsp;:cond-clause&nbsp;(first&nbsp;p)))
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
093&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(make-beowulf-list
</span><br/>
<span class="partial" title="12 out of 13 forms covered">
094&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(list&nbsp;(if&nbsp;(=&nbsp;(nth&nbsp;p&nbsp;1)&nbsp;[:quoted-expr&nbsp;[:atom&nbsp;&quot;T&quot;]])
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
095&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#x27;T
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
096&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(generate&nbsp;(nth&nbsp;p&nbsp;1)&nbsp;context))
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
097&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(generate&nbsp;(nth&nbsp;p&nbsp;2)&nbsp;context)))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
098&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
099&nbsp;&nbsp;(defn&nbsp;gen-cond
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
100&nbsp;&nbsp;&nbsp;&nbsp;&quot;Generate&nbsp;a&nbsp;cond&nbsp;statement&nbsp;from&nbsp;this&nbsp;simplified&nbsp;parse&nbsp;tree&nbsp;fragment&nbsp;`p`;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
101&nbsp;&nbsp;&nbsp;&nbsp;returns&nbsp;`nil`&nbsp;if&nbsp;`p`&nbsp;does&nbsp;not&nbsp;represent&nbsp;a&nbsp;(MEXPR)&nbsp;cond&nbsp;statement.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
102&nbsp;&nbsp;&nbsp;&nbsp;[p&nbsp;context]
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
103&nbsp;&nbsp;&nbsp;&nbsp;(when
</span><br/>
<span class="partial" title="11 out of 12 forms covered">
104&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(and&nbsp;(coll?&nbsp;p)&nbsp;(=&nbsp;:cond&nbsp;(first&nbsp;p)))
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
105&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(make-beowulf-list
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
106&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cons
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
107&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#x27;COND
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
108&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map
</span><br/>
<span class="partial" title="8 out of 9 forms covered">
109&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#(generate&nbsp;%&nbsp;(if&nbsp;(=&nbsp;context&nbsp;:mexpr)&nbsp;:cond-mexpr&nbsp;context))
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
110&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(rest&nbsp;p))))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
111&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
112&nbsp;&nbsp;(defn&nbsp;gen-fn-call
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
113&nbsp;&nbsp;&nbsp;&nbsp;&quot;Generate&nbsp;a&nbsp;function&nbsp;call&nbsp;from&nbsp;this&nbsp;simplified&nbsp;parse&nbsp;tree&nbsp;fragment&nbsp;`p`;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
114&nbsp;&nbsp;&nbsp;&nbsp;returns&nbsp;`nil`&nbsp;if&nbsp;`p`&nbsp;does&nbsp;not&nbsp;represent&nbsp;a&nbsp;(MEXPR)&nbsp;function&nbsp;call.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
115&nbsp;&nbsp;&nbsp;&nbsp;[p&nbsp;context]
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
116&nbsp;&nbsp;&nbsp;&nbsp;(when
</span><br/>
<span class="partial" title="21 out of 23 forms covered">
117&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(and&nbsp;(coll?&nbsp;p)&nbsp;(=&nbsp;:fncall&nbsp;(first&nbsp;p))&nbsp;(=&nbsp;:mvar&nbsp;(first&nbsp;(second&nbsp;p))))
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
118&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(make-cons-cell
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
119&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(generate&nbsp;(second&nbsp;p)&nbsp;context)
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
120&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(generate&nbsp;(nth&nbsp;p&nbsp;2)&nbsp;context))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
121&nbsp;&nbsp;
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
122&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
123&nbsp;&nbsp;(defn&nbsp;gen-dot-terminated-list
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
124&nbsp;&nbsp;&nbsp;&nbsp;&quot;Generate&nbsp;a&nbsp;list,&nbsp;which&nbsp;may&nbsp;be&nbsp;dot-terminated,&nbsp;from&nbsp;this&nbsp;partial&nbsp;parse&nbsp;tree
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
125&nbsp;&nbsp;&nbsp;&nbsp;&#x27;p&#x27;.&nbsp;Note&nbsp;that&nbsp;the&nbsp;function&nbsp;acts&nbsp;recursively&nbsp;and&nbsp;progressively&nbsp;decapitates
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
126&nbsp;&nbsp;&nbsp;&nbsp;its&nbsp;argument,&nbsp;so&nbsp;that&nbsp;the&nbsp;argument&nbsp;will&nbsp;not&nbsp;always&nbsp;be&nbsp;a&nbsp;valid&nbsp;parse&nbsp;tree.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
127&nbsp;&nbsp;&nbsp;&nbsp;[p]
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
128&nbsp;&nbsp;&nbsp;&nbsp;(cond
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
129&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(empty?&nbsp;p)
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
130&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NIL
</span><br/>
<span class="partial" title="15 out of 16 forms covered">
131&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(and&nbsp;(coll?&nbsp;(first&nbsp;p))&nbsp;(=&nbsp;:dot-terminal&nbsp;(first&nbsp;(first&nbsp;p))))
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
132&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[dt&nbsp;(first&nbsp;p)]
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
133&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(make-cons-cell
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
134&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(generate&nbsp;(nth&nbsp;dt&nbsp;1))
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
135&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(generate&nbsp;(nth&nbsp;dt&nbsp;2))))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
136&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:else
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
137&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(make-cons-cell
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
138&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(generate&nbsp;(first&nbsp;p))
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
139&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(gen-dot-terminated-list&nbsp;(rest&nbsp;p)))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
140&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
141&nbsp;&nbsp;;;&nbsp;null[x]&nbsp;=&nbsp;[x&nbsp;=&nbsp;NIL&nbsp;-&gt;&nbsp;T;&nbsp;T&nbsp;-&gt;&nbsp;F]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
142&nbsp;&nbsp;;;&nbsp;[:defn&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
143&nbsp;&nbsp;;;&nbsp;&nbsp;[:mexpr&nbsp;[:fncall&nbsp;[:mvar&nbsp;&quot;null&quot;]&nbsp;[:bindings&nbsp;[:args&nbsp;[:mexpr&nbsp;[:mvar&nbsp;&quot;x&quot;]]]]]]&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
144&nbsp;&nbsp;;;&nbsp;&nbsp;&quot;=&quot;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
145&nbsp;&nbsp;;;&nbsp;&nbsp;[:mexpr&nbsp;[:cond&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
146&nbsp;&nbsp;;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[:cond-clause&nbsp;[:mexpr&nbsp;[:iexpr&nbsp;[:lhs&nbsp;[:mexpr&nbsp;[:mvar&nbsp;&quot;x&quot;]]]&nbsp;[:iop&nbsp;&quot;=&quot;]&nbsp;[:rhs&nbsp;[:mexpr&nbsp;[:mconst&nbsp;&quot;NIL&quot;]]]]]&nbsp;[:mexpr&nbsp;[:mconst&nbsp;&quot;T&quot;]]]&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
147&nbsp;&nbsp;;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[:cond-clause&nbsp;[:mexpr&nbsp;[:mconst&nbsp;&quot;T&quot;]]&nbsp;[:mexpr&nbsp;[:mconst&nbsp;&quot;F&quot;]]]]]]
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
148&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
149&nbsp;&nbsp;(defn&nbsp;generate-defn
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
150&nbsp;&nbsp;&nbsp;&nbsp;[tree&nbsp;context]
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
151&nbsp;&nbsp;&nbsp;&nbsp;(if&nbsp;(=&nbsp;:mexpr&nbsp;(first&nbsp;tree))
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
152&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(generate-defn&nbsp;(second&nbsp;tree)&nbsp;context)
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
153&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(make-beowulf-list
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
154&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(list&nbsp;&#x27;PUT
</span><br/>
<span class="covered" title="13 out of 13 forms covered">
155&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(list&nbsp;&#x27;QUOTE&nbsp;(generate&nbsp;(-&gt;&nbsp;tree&nbsp;second&nbsp;second&nbsp;second)&nbsp;context))
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
156&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(list&nbsp;&#x27;QUOTE&nbsp;&#x27;EXPR)
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
157&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(list&nbsp;&#x27;QUOTE
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
158&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cons&nbsp;&#x27;LAMBDA
</span><br/>
<span class="covered" title="12 out of 12 forms covered">
159&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(list&nbsp;(generate&nbsp;(nth&nbsp;(-&gt;&nbsp;tree&nbsp;second&nbsp;second)&nbsp;2)&nbsp;context)
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
160&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(generate&nbsp;(nth&nbsp;tree&nbsp;3)&nbsp;context))))))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
161&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
162&nbsp;&nbsp;(defn&nbsp;gen-iexpr
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
163&nbsp;&nbsp;&nbsp;&nbsp;[tree&nbsp;context]
</span><br/>
<span class="not-covered" title="0 out of 11 forms covered">
164&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[bundle&nbsp;(reduce&nbsp;#(assoc&nbsp;%1&nbsp;(first&nbsp;%2)&nbsp;%2)
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
165&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{}
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
166&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(rest&nbsp;tree))]
</span><br/>
<span class="not-covered" title="0 out of 8 forms covered">
167&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(list&nbsp;(generate&nbsp;(:iop&nbsp;bundle)&nbsp;context)
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
168&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(generate&nbsp;(:lhs&nbsp;bundle)&nbsp;context)
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
169&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(generate&nbsp;(:rhs&nbsp;bundle)&nbsp;context))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
170&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
171&nbsp;&nbsp;(defn&nbsp;generate-set
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
172&nbsp;&nbsp;&nbsp;&nbsp;&quot;Actually&nbsp;not&nbsp;sure&nbsp;what&nbsp;the&nbsp;mexpr&nbsp;representation&nbsp;of&nbsp;set&nbsp;looks&nbsp;like&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
173&nbsp;&nbsp;&nbsp;&nbsp;[tree&nbsp;context]
</span><br/>
<span class="not-covered" title="0 out of 7 forms covered">
174&nbsp;&nbsp;&nbsp;&nbsp;(throw&nbsp;(ex-info&nbsp;&quot;Not&nbsp;Yet&nbsp;Implemented&quot;&nbsp;{:feature&nbsp;&quot;generate-set&quot;})))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
175&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
176&nbsp;&nbsp;(defn&nbsp;generate-assign
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
177&nbsp;&nbsp;&nbsp;&nbsp;&quot;Generate&nbsp;an&nbsp;assignment&nbsp;statement&nbsp;based&nbsp;on&nbsp;this&nbsp;`tree`.&nbsp;If&nbsp;the&nbsp;thing&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
178&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;being&nbsp;assigned&nbsp;to&nbsp;is&nbsp;a&nbsp;function&nbsp;signature,&nbsp;then&nbsp;we&nbsp;have&nbsp;to&nbsp;do&nbsp;something&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
179&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;different&nbsp;to&nbsp;if&nbsp;it&#x27;s&nbsp;an&nbsp;atom.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
180&nbsp;&nbsp;&nbsp;&nbsp;[tree&nbsp;context]
</span><br/>
<span class="not-covered" title="0 out of 13 forms covered">
181&nbsp;&nbsp;&nbsp;&nbsp;(case&nbsp;(first&nbsp;(second&nbsp;tree))
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
182&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:fncall&nbsp;(generate-defn&nbsp;tree&nbsp;context)
</span><br/>
<span class="not-covered" title="0 out of 12 forms covered">
183&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:mexpr&nbsp;(map&nbsp;#(generate&nbsp;%&nbsp;context)&nbsp;(rest&nbsp;(second&nbsp;tree)))
</span><br/>
<span class="not-covered" title="0 out of 8 forms covered">
184&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:mvar&nbsp;:atom)&nbsp;(generate-set&nbsp;tree&nbsp;context)))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
185&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
186&nbsp;&nbsp;(defn&nbsp;strip-leading-zeros
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
187&nbsp;&nbsp;&nbsp;&nbsp;&quot;`read-string`&nbsp;interprets&nbsp;strings&nbsp;with&nbsp;leading&nbsp;zeros&nbsp;as&nbsp;octal;&nbsp;strip
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
188&nbsp;&nbsp;&nbsp;&nbsp;any&nbsp;from&nbsp;this&nbsp;string&nbsp;`s`.&nbsp;If&nbsp;what&#x27;s&nbsp;left&nbsp;is&nbsp;empty&nbsp;(i.e.&nbsp;there&nbsp;were
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
189&nbsp;&nbsp;&nbsp;&nbsp;only&nbsp;zeros,&nbsp;return&nbsp;`\&quot;0\&quot;`.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
190&nbsp;&nbsp;&nbsp;&nbsp;([s]
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
191&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(strip-leading-zeros&nbsp;s&nbsp;&quot;&quot;))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
192&nbsp;&nbsp;&nbsp;&nbsp;([s&nbsp;prefix]
</span><br/>
<span class="partial" title="1 out of 2 forms covered">
193&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
194&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(empty?&nbsp;s)&nbsp;&quot;0&quot;
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
195&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(case&nbsp;(first&nbsp;s)
</span><br/>
<span class="partial" title="12 out of 24 forms covered">
196&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(\+&nbsp;\-)&nbsp;(strip-leading-zeros&nbsp;(subs&nbsp;s&nbsp;1)&nbsp;(str&nbsp;(first&nbsp;s)&nbsp;prefix))
</span><br/>
<span class="not-covered" title="0 out of 7 forms covered">
197&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;0&quot;&nbsp;(strip-leading-zeros&nbsp;(subs&nbsp;s&nbsp;1)&nbsp;prefix)
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
198&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(str&nbsp;prefix&nbsp;s)))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
199&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
200&nbsp;&nbsp;(defn&nbsp;generate
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
201&nbsp;&nbsp;&nbsp;&nbsp;&quot;Generate&nbsp;lisp&nbsp;structure&nbsp;from&nbsp;this&nbsp;parse&nbsp;tree&nbsp;`p`.&nbsp;It&nbsp;is&nbsp;assumed&nbsp;that
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
202&nbsp;&nbsp;&nbsp;&nbsp;`p`&nbsp;has&nbsp;been&nbsp;simplified.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
203&nbsp;&nbsp;&nbsp;&nbsp;([p]
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
204&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(generate&nbsp;p&nbsp;:expr))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
205&nbsp;&nbsp;&nbsp;&nbsp;([p&nbsp;context]
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
206&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(try
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
207&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(expand-macros
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
208&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
209&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(coll?&nbsp;p)
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
210&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(case&nbsp;(first&nbsp;p)
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
211&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;LAMBDA&quot;
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
212&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:λexpr&nbsp;(make-cons-cell
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
213&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(generate&nbsp;(nth&nbsp;p&nbsp;1)&nbsp;context)
</span><br/>
<span class="covered" title="8 out of 8 forms covered">
214&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(make-cons-cell&nbsp;(generate&nbsp;(nth&nbsp;p&nbsp;2)&nbsp;context)
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
215&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(generate&nbsp;(nth&nbsp;p&nbsp;3)&nbsp;context)))
</span><br/>
<span class="covered" title="12 out of 12 forms covered">
216&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:args&nbsp;(make-beowulf-list&nbsp;(map&nbsp;#(generate&nbsp;%&nbsp;context)&nbsp;(rest&nbsp;p)))
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
217&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:atom&nbsp;(symbol&nbsp;(second&nbsp;p))
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
218&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:bindings&nbsp;(generate&nbsp;(second&nbsp;p)&nbsp;context)
</span><br/>
<span class="covered" title="12 out of 12 forms covered">
219&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:body&nbsp;(make-beowulf-list&nbsp;(map&nbsp;#(generate&nbsp;%&nbsp;context)&nbsp;(rest&nbsp;p)))
</span><br/>
<span class="covered" title="12 out of 12 forms covered">
220&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:coefficient&nbsp;:exponent)&nbsp;(generate&nbsp;(second&nbsp;p)&nbsp;context)
</span><br/>
<span class="partial" title="8 out of 9 forms covered">
221&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:cond&nbsp;(gen-cond&nbsp;p&nbsp;(if&nbsp;(=&nbsp;context&nbsp;:mexpr)&nbsp;:cond-mexpr&nbsp;context))
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
222&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:cond-clause&nbsp;(gen-cond-clause&nbsp;p&nbsp;context)
</span><br/>
<span class="covered" title="11 out of 11 forms covered">
223&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:decimal&nbsp;(read-string&nbsp;(apply&nbsp;str&nbsp;(map&nbsp;second&nbsp;(rest&nbsp;p))))
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
224&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:defn&nbsp;(generate-defn&nbsp;p&nbsp;context)
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
225&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:dotted-pair&nbsp;(make-cons-cell
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
226&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(generate&nbsp;(nth&nbsp;p&nbsp;1)&nbsp;context)
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
227&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(generate&nbsp;(nth&nbsp;p&nbsp;2)&nbsp;context))
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
228&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:fncall&nbsp;(gen-fn-call&nbsp;p&nbsp;context)
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
229&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:iexpr&nbsp;(gen-iexpr&nbsp;p&nbsp;context)
</span><br/>
<span class="covered" title="7 out of 7 forms covered">
230&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:integer&nbsp;(read-string&nbsp;(strip-leading-zeros&nbsp;(second&nbsp;p)))
</span><br/>
<span class="not-covered" title="0 out of 11 forms covered">
231&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:iop&nbsp;(case&nbsp;(second&nbsp;p)
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
232&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;&#x2F;&quot;&nbsp;&#x27;DIFFERENCE
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
233&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;=&quot;&nbsp;&#x27;EQUAL
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
234&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;&gt;&quot;&nbsp;&#x27;GREATERP
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
235&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;&lt;&quot;&nbsp;&#x27;LESSP
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
236&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;+&quot;&nbsp;&#x27;PLUS
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
237&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;*&quot;&nbsp;&#x27;TIMES
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
238&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;else
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
239&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(throw&nbsp;(ex-info&nbsp;&quot;Unrecognised&nbsp;infix&nbsp;operator&nbsp;symbol&quot;
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
240&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{:phase&nbsp;:generate
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
241&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:fragment&nbsp;p})))
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
242&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:list&nbsp;(gen-dot-terminated-list&nbsp;(rest&nbsp;p))
</span><br/>
<span class="not-covered" title="0 out of 12 forms covered">
243&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:lhs&nbsp;:rhs)&nbsp;(generate&nbsp;(second&nbsp;p)&nbsp;context)
</span><br/>
<span class="covered" title="11 out of 11 forms covered">
244&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:mexpr&nbsp;(generate&nbsp;(second&nbsp;p)&nbsp;(if&nbsp;(=&nbsp;context&nbsp;:cond-mexpr)&nbsp;context&nbsp;:mexpr))
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
245&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:mconst&nbsp;(if&nbsp;(=&nbsp;context&nbsp;:cond-mexpr)
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
246&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(case&nbsp;(second&nbsp;p)
</span><br/>
<span class="partial" title="5 out of 15 forms covered">
247&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(&quot;T&quot;&nbsp;&quot;F&quot;&nbsp;&quot;NIL&quot;)&nbsp;(symbol&nbsp;(second&nbsp;p))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
248&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;else
</span><br/>
<span class="not-covered" title="0 out of 8 forms covered">
249&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(list&nbsp;&#x27;QUOTE&nbsp;(symbol&nbsp;(second&nbsp;p))))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
250&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;else
</span><br/>
<span class="covered" title="8 out of 8 forms covered">
251&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(list&nbsp;&#x27;QUOTE&nbsp;(symbol&nbsp;(second&nbsp;p))))
</span><br/>
<span class="covered" title="7 out of 7 forms covered">
252&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:mvar&nbsp;(symbol&nbsp;(upper-case&nbsp;(second&nbsp;p)))
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
253&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:number&nbsp;(generate&nbsp;(second&nbsp;p)&nbsp;context)
</span><br/>
<span class="covered" title="9 out of 9 forms covered">
254&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:octal&nbsp;(let&nbsp;[n&nbsp;(read-string&nbsp;(strip-leading-zeros&nbsp;(second&nbsp;p)&nbsp;&quot;0&quot;))
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
255&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;scale&nbsp;(generate&nbsp;(nth&nbsp;p&nbsp;3)&nbsp;context)]
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
256&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(*&nbsp;n&nbsp;(expt&nbsp;8&nbsp;scale)))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
257&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
258&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;the&nbsp;quote&nbsp;read&nbsp;macro&nbsp;(which&nbsp;probably&nbsp;didn&#x27;t&nbsp;exist&nbsp;in&nbsp;Lisp&nbsp;1.5,&nbsp;but...)
</span><br/>
<span class="covered" title="11 out of 11 forms covered">
259&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:quoted-expr&nbsp;(make-beowulf-list&nbsp;(list&nbsp;&#x27;QUOTE&nbsp;(generate&nbsp;(second&nbsp;p)&nbsp;context)))
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
260&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:scale-factor&nbsp;(if
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
261&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(empty?&nbsp;(second&nbsp;p))&nbsp;0
</span><br/>
<span class="covered" title="7 out of 7 forms covered">
262&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(read-string&nbsp;(strip-leading-zeros&nbsp;(second&nbsp;p))))
</span><br/>
<span class="covered" title="7 out of 7 forms covered">
263&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:scientific&nbsp;(let&nbsp;[n&nbsp;(generate&nbsp;(second&nbsp;p)&nbsp;context)
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
264&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exponent&nbsp;(generate&nbsp;(nth&nbsp;p&nbsp;3)&nbsp;context)]
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
265&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(*&nbsp;n&nbsp;(expt&nbsp;10&nbsp;exponent)))
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
266&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:sexpr&nbsp;(generate&nbsp;(second&nbsp;p)&nbsp;:sexpr)
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
267&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:subr&nbsp;(symbol&nbsp;(second&nbsp;p))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
268&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
269&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;default
</span><br/>
<span class="not-covered" title="0 out of 9 forms covered">
270&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(throw&nbsp;(ex-info&nbsp;(str&nbsp;&quot;Unrecognised&nbsp;head:&nbsp;&quot;&nbsp;(first&nbsp;p))
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
271&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{:generating&nbsp;p})))
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
272&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
273&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(catch&nbsp;Throwable&nbsp;any
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
274&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(throw&nbsp;(ex-info&nbsp;&quot;Could&nbsp;not&nbsp;generate&quot;
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
275&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{:generating&nbsp;p}
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
276&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;any))))))
</span><br/>
</body>
</html>

View file

@ -0,0 +1,212 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" href="../../coverage.css"/> <title> beowulf/reader/macros.clj </title>
</head>
<body>
<span class="covered" title="1 out of 1 forms covered">
001&nbsp;&nbsp;(ns&nbsp;beowulf.reader.macros
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
002&nbsp;&nbsp;&nbsp;&nbsp;&quot;Can&nbsp;I&nbsp;implement&nbsp;reader&nbsp;macros?&nbsp;let&#x27;s&nbsp;see!
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
003&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
004&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;We&nbsp;don&#x27;t&nbsp;need&nbsp;(at&nbsp;least,&nbsp;in&nbsp;the&nbsp;Clojure&nbsp;reader)&nbsp;to&nbsp;rewrite&nbsp;forms&nbsp;like
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
005&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`&#x27;FOO`,&nbsp;because&nbsp;that&#x27;s&nbsp;handled&nbsp;by&nbsp;the&nbsp;parser.&nbsp;But&nbsp;we&nbsp;do&nbsp;need&nbsp;to&nbsp;rewrite
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
006&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;things&nbsp;which&nbsp;don&#x27;t&nbsp;evaluate&nbsp;their&nbsp;arguments,&nbsp;like&nbsp;`SETQ`,&nbsp;because&nbsp;(unless
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
007&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LABEL&nbsp;does&nbsp;it,&nbsp;which&nbsp;I&#x27;m&nbsp;not&nbsp;yet&nbsp;sure&nbsp;of)&nbsp;we&#x27;re&nbsp;not&nbsp;yet&nbsp;able&nbsp;to&nbsp;implement
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
008&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;things&nbsp;which&nbsp;don&#x27;t&nbsp;evaluate&nbsp;arguments.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
009&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
010&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TODO:&nbsp;at&nbsp;this&nbsp;stage,&nbsp;the&nbsp;following&nbsp;should&nbsp;probably&nbsp;also&nbsp;be&nbsp;read&nbsp;macros:
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
011&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DEFINE&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
012&nbsp;&nbsp;&nbsp;&nbsp;(:require&nbsp;[beowulf.cons-cell&nbsp;:refer&nbsp;[make-beowulf-list]]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
013&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[beowulf.host&nbsp;:refer&nbsp;[CONS&nbsp;LIST]]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
014&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[clojure.string&nbsp;:refer&nbsp;[join]]))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
015&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
016&nbsp;&nbsp;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
017&nbsp;&nbsp;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
018&nbsp;&nbsp;;;;&nbsp;We&nbsp;don&#x27;t&nbsp;need&nbsp;(at&nbsp;least,&nbsp;in&nbsp;the&nbsp;Clojure&nbsp;reader)&nbsp;to&nbsp;rewrite&nbsp;forms&nbsp;like
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
019&nbsp;&nbsp;;;;&nbsp;&quot;&#x27;FOO&quot;,&nbsp;because&nbsp;that&#x27;s&nbsp;handled&nbsp;by&nbsp;the&nbsp;parser.&nbsp;But&nbsp;we&nbsp;do&nbsp;need&nbsp;to&nbsp;rewrite
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
020&nbsp;&nbsp;;;;&nbsp;things&nbsp;which&nbsp;don&#x27;t&nbsp;evaluate&nbsp;their&nbsp;arguments,&nbsp;like&nbsp;`SETQ`,&nbsp;because&nbsp;(unless
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
021&nbsp;&nbsp;;;;&nbsp;LABEL&nbsp;does&nbsp;it,&nbsp;which&nbsp;I&#x27;m&nbsp;not&nbsp;yet&nbsp;sure&nbsp;of)&nbsp;we&#x27;re&nbsp;not&nbsp;yet&nbsp;able&nbsp;to&nbsp;implement
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
022&nbsp;&nbsp;;;;&nbsp;things&nbsp;which&nbsp;don&#x27;t&nbsp;evaluate&nbsp;arguments.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
023&nbsp;&nbsp;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
024&nbsp;&nbsp;;;;&nbsp;TODO:&nbsp;at&nbsp;this&nbsp;stage,&nbsp;the&nbsp;following&nbsp;should&nbsp;probably&nbsp;also&nbsp;be&nbsp;read&nbsp;macros:
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
025&nbsp;&nbsp;;;;&nbsp;DEFINE
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
026&nbsp;&nbsp;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
027&nbsp;&nbsp;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
028&nbsp;&nbsp;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
029&nbsp;&nbsp;;;;&nbsp;Copyright&nbsp;(C)&nbsp;2022-2023&nbsp;Simon&nbsp;Brooke
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
030&nbsp;&nbsp;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
031&nbsp;&nbsp;;;;&nbsp;This&nbsp;program&nbsp;is&nbsp;free&nbsp;software;&nbsp;you&nbsp;can&nbsp;redistribute&nbsp;it&nbsp;and&#x2F;or
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
032&nbsp;&nbsp;;;;&nbsp;modify&nbsp;it&nbsp;under&nbsp;the&nbsp;terms&nbsp;of&nbsp;the&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
033&nbsp;&nbsp;;;;&nbsp;as&nbsp;published&nbsp;by&nbsp;the&nbsp;Free&nbsp;Software&nbsp;Foundation;&nbsp;either&nbsp;version&nbsp;2
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
034&nbsp;&nbsp;;;;&nbsp;of&nbsp;the&nbsp;License,&nbsp;or&nbsp;(at&nbsp;your&nbsp;option)&nbsp;any&nbsp;later&nbsp;version.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
035&nbsp;&nbsp;;;;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
036&nbsp;&nbsp;;;;&nbsp;This&nbsp;program&nbsp;is&nbsp;distributed&nbsp;in&nbsp;the&nbsp;hope&nbsp;that&nbsp;it&nbsp;will&nbsp;be&nbsp;useful,
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
037&nbsp;&nbsp;;;;&nbsp;but&nbsp;WITHOUT&nbsp;ANY&nbsp;WARRANTY;&nbsp;without&nbsp;even&nbsp;the&nbsp;implied&nbsp;warranty&nbsp;of
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
038&nbsp;&nbsp;;;;&nbsp;MERCHANTABILITY&nbsp;or&nbsp;FITNESS&nbsp;FOR&nbsp;A&nbsp;PARTICULAR&nbsp;PURPOSE.&nbsp;&nbsp;See&nbsp;the
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
039&nbsp;&nbsp;;;;&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License&nbsp;for&nbsp;more&nbsp;details.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
040&nbsp;&nbsp;;;;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
041&nbsp;&nbsp;;;;&nbsp;You&nbsp;should&nbsp;have&nbsp;received&nbsp;a&nbsp;copy&nbsp;of&nbsp;the&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
042&nbsp;&nbsp;;;;&nbsp;along&nbsp;with&nbsp;this&nbsp;program;&nbsp;if&nbsp;not,&nbsp;write&nbsp;to&nbsp;the&nbsp;Free&nbsp;Software
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
043&nbsp;&nbsp;;;;&nbsp;Foundation,&nbsp;Inc.,&nbsp;51&nbsp;Franklin&nbsp;Street,&nbsp;Fifth&nbsp;Floor,&nbsp;Boston,&nbsp;MA&nbsp;&nbsp;02110-1301,&nbsp;USA.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
044&nbsp;&nbsp;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
045&nbsp;&nbsp;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
046&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
047&nbsp;&nbsp;(def&nbsp;^:dynamic&nbsp;*readmacros*
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
048&nbsp;&nbsp;&nbsp;&nbsp;{:car&nbsp;{&#x27;DEFUN&nbsp;(fn&nbsp;[f]
</span><br/>
<span class="covered" title="9 out of 9 forms covered">
049&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(LIST&nbsp;&#x27;SET&nbsp;(LIST&nbsp;&#x27;QUOTE&nbsp;(second&nbsp;f))
</span><br/>
<span class="covered" title="11 out of 11 forms covered">
050&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(LIST&nbsp;&#x27;QUOTE&nbsp;(CONS&nbsp;&#x27;LAMBDA&nbsp;(rest&nbsp;(rest&nbsp;f))))))
</span><br/>
<span class="covered" title="13 out of 13 forms covered">
051&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#x27;SETQ&nbsp;(fn&nbsp;[f]&nbsp;(LIST&nbsp;&#x27;SET&nbsp;(LIST&nbsp;&#x27;QUOTE&nbsp;(second&nbsp;f))&nbsp;(nth&nbsp;f&nbsp;2)))}})
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
052&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
053&nbsp;&nbsp;(defn&nbsp;expand-macros
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
054&nbsp;&nbsp;&nbsp;&nbsp;[form]
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
055&nbsp;&nbsp;&nbsp;&nbsp;(try
</span><br/>
<span class="covered" title="19 out of 19 forms covered">
056&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if-let&nbsp;[car&nbsp;(when&nbsp;(and&nbsp;(coll?&nbsp;form)&nbsp;(symbol?&nbsp;(first&nbsp;form)))&nbsp;
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
057&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(first&nbsp;form))]
</span><br/>
<span class="covered" title="10 out of 10 forms covered">
058&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if-let&nbsp;[macro&nbsp;(-&gt;&nbsp;*readmacros*&nbsp;:car&nbsp;car)]
</span><br/>
<span class="covered" title="8 out of 8 forms covered">
059&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(make-beowulf-list&nbsp;(apply&nbsp;macro&nbsp;(list&nbsp;form)))
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
060&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;form)
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
061&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;form)
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
062&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(catch&nbsp;Exception&nbsp;any
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
063&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(println&nbsp;(join&nbsp;&quot;\n&quot;
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
064&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[&quot;#&nbsp;ERROR&nbsp;while&nbsp;expanding&nbsp;macro:&quot;
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
065&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(str&nbsp;&quot;#&nbsp;Form:&nbsp;&quot;&nbsp;form)
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
066&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(str&nbsp;&quot;#&nbsp;Error&nbsp;class:&nbsp;&quot;&nbsp;(.getName&nbsp;(.getClass&nbsp;any)))
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
067&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(str&nbsp;&quot;#&nbsp;Message:&nbsp;&quot;&nbsp;(.getMessage&nbsp;any))]))
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
068&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;form)))
</span><br/>
</body>
</html>

View file

@ -0,0 +1,368 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" href="../../coverage.css"/> <title> beowulf/reader/parser.clj </title>
</head>
<body>
<span class="covered" title="1 out of 1 forms covered">
001&nbsp;&nbsp;(ns&nbsp;beowulf.reader.parser
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
002&nbsp;&nbsp;&nbsp;&nbsp;&quot;The&nbsp;actual&nbsp;parser,&nbsp;supporting&nbsp;both&nbsp;S-expression&nbsp;and&nbsp;M-expression&nbsp;syntax.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
003&nbsp;&nbsp;&nbsp;&nbsp;(:require&nbsp;[instaparse.core&nbsp;:as&nbsp;i]))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
004&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
005&nbsp;&nbsp;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
006&nbsp;&nbsp;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
007&nbsp;&nbsp;;;;&nbsp;Copyright&nbsp;(C)&nbsp;2022-2023&nbsp;Simon&nbsp;Brooke
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
008&nbsp;&nbsp;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
009&nbsp;&nbsp;;;;&nbsp;This&nbsp;program&nbsp;is&nbsp;free&nbsp;software;&nbsp;you&nbsp;can&nbsp;redistribute&nbsp;it&nbsp;and&#x2F;or
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
010&nbsp;&nbsp;;;;&nbsp;modify&nbsp;it&nbsp;under&nbsp;the&nbsp;terms&nbsp;of&nbsp;the&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
011&nbsp;&nbsp;;;;&nbsp;as&nbsp;published&nbsp;by&nbsp;the&nbsp;Free&nbsp;Software&nbsp;Foundation;&nbsp;either&nbsp;version&nbsp;2
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
012&nbsp;&nbsp;;;;&nbsp;of&nbsp;the&nbsp;License,&nbsp;or&nbsp;(at&nbsp;your&nbsp;option)&nbsp;any&nbsp;later&nbsp;version.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
013&nbsp;&nbsp;;;;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
014&nbsp;&nbsp;;;;&nbsp;This&nbsp;program&nbsp;is&nbsp;distributed&nbsp;in&nbsp;the&nbsp;hope&nbsp;that&nbsp;it&nbsp;will&nbsp;be&nbsp;useful,
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
015&nbsp;&nbsp;;;;&nbsp;but&nbsp;WITHOUT&nbsp;ANY&nbsp;WARRANTY;&nbsp;without&nbsp;even&nbsp;the&nbsp;implied&nbsp;warranty&nbsp;of
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
016&nbsp;&nbsp;;;;&nbsp;MERCHANTABILITY&nbsp;or&nbsp;FITNESS&nbsp;FOR&nbsp;A&nbsp;PARTICULAR&nbsp;PURPOSE.&nbsp;&nbsp;See&nbsp;the
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
017&nbsp;&nbsp;;;;&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License&nbsp;for&nbsp;more&nbsp;details.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
018&nbsp;&nbsp;;;;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
019&nbsp;&nbsp;;;;&nbsp;You&nbsp;should&nbsp;have&nbsp;received&nbsp;a&nbsp;copy&nbsp;of&nbsp;the&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
020&nbsp;&nbsp;;;;&nbsp;along&nbsp;with&nbsp;this&nbsp;program;&nbsp;if&nbsp;not,&nbsp;write&nbsp;to&nbsp;the&nbsp;Free&nbsp;Software
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
021&nbsp;&nbsp;;;;&nbsp;Foundation,&nbsp;Inc.,&nbsp;51&nbsp;Franklin&nbsp;Street,&nbsp;Fifth&nbsp;Floor,&nbsp;Boston,&nbsp;MA&nbsp;&nbsp;02110-1301,&nbsp;USA.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
022&nbsp;&nbsp;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
023&nbsp;&nbsp;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
024&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
025&nbsp;&nbsp;(def&nbsp;parse
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
026&nbsp;&nbsp;&nbsp;&nbsp;&quot;Parse&nbsp;a&nbsp;string&nbsp;presented&nbsp;as&nbsp;argument&nbsp;into&nbsp;a&nbsp;parse&nbsp;tree&nbsp;which&nbsp;can&nbsp;then
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
027&nbsp;&nbsp;&nbsp;&nbsp;be&nbsp;operated&nbsp;upon&nbsp;further.&quot;
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
028&nbsp;&nbsp;&nbsp;&nbsp;(i&#x2F;parser
</span><br/>
<span class="covered" title="13 out of 13 forms covered">
029&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(str
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
030&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;we&nbsp;tolerate&nbsp;whitespace&nbsp;and&nbsp;comments&nbsp;around&nbsp;legitimate&nbsp;input
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
031&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;raw&nbsp;:=&nbsp;expr&nbsp;|&nbsp;opt-comment&nbsp;expr&nbsp;opt-comment;&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
032&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;top&nbsp;level:&nbsp;we&nbsp;accept&nbsp;mexprs&nbsp;as&nbsp;well&nbsp;as&nbsp;sexprs.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
033&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;expr&nbsp;:=&nbsp;mexpr&nbsp;|&nbsp;sexpr&nbsp;;&quot;
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
034&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
035&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;comments.&nbsp;I&#x27;m&nbsp;pretty&nbsp;confident&nbsp;Lisp&nbsp;1.5&nbsp;did&nbsp;NOT&nbsp;have&nbsp;these.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
036&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;comment&nbsp;:=&nbsp;opt-space&nbsp;&lt;&#x27;;;&#x27;&gt;&nbsp;opt-space&nbsp;#&#x27;[^\\n\\r]*&#x27;;&quot;
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
037&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
038&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;there&#x27;s&nbsp;a&nbsp;notation&nbsp;comprising&nbsp;a&nbsp;left&nbsp;brace&nbsp;followed&nbsp;by&nbsp;mexprs
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
039&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;followed&nbsp;by&nbsp;a&nbsp;right&nbsp;brace&nbsp;which&nbsp;doesn&#x27;t&nbsp;seem&nbsp;to&nbsp;be&nbsp;documented&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
040&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;but&nbsp;I&nbsp;think&nbsp;must&nbsp;represent&nbsp;assembly&nbsp;code(?)
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
041&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
042&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;&quot;assembly&nbsp;:=&nbsp;lbrace&nbsp;exprs&nbsp;rbrace;&quot;
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
043&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
044&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;mexprs.&nbsp;I&#x27;m&nbsp;pretty&nbsp;clear&nbsp;that&nbsp;Lisp&nbsp;1.5&nbsp;could&nbsp;never&nbsp;read&nbsp;these,
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
045&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;but&nbsp;it&#x27;s&nbsp;a&nbsp;convenience.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
046&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
047&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;TODO:&nbsp;this&nbsp;works&nbsp;for&nbsp;now&nbsp;but&nbsp;in&nbsp;fact&nbsp;the&nbsp;Programmer&#x27;s&nbsp;Manual
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
048&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;gives&nbsp;a&nbsp;much&nbsp;simpler&nbsp;formulation&nbsp;of&nbsp;M-expression&nbsp;grammar&nbsp;on
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
049&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;page&nbsp;9,&nbsp;and&nbsp;of&nbsp;the&nbsp;S-expression&nbsp;grammar&nbsp;on&nbsp;page&nbsp;8.&nbsp;It&nbsp;would
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
050&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;be&nbsp;worth&nbsp;going&nbsp;back&nbsp;and&nbsp;redoing&nbsp;this&nbsp;from&nbsp;the&nbsp;book.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
051&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
052&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;exprs&nbsp;:=&nbsp;expr&nbsp;|&nbsp;exprs;&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
053&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;mexpr&nbsp;:=&nbsp;λexpr&nbsp;|&nbsp;fncall&nbsp;|&nbsp;defn&nbsp;|&nbsp;cond&nbsp;|&nbsp;mvar&nbsp;|&nbsp;mconst&nbsp;|&nbsp;iexpr&nbsp;|&nbsp;number&nbsp;|&nbsp;mexpr&nbsp;comment;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
054&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;λexpr&nbsp;:=&nbsp;λ&nbsp;lsqb&nbsp;bindings&nbsp;semi-colon&nbsp;opt-space&nbsp;body&nbsp;opt-space&nbsp;rsqb;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
055&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;λ&nbsp;:=&nbsp;&#x27;λ&#x27;&nbsp;|&nbsp;&#x27;lambda&#x27;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
056&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bindings&nbsp;:=&nbsp;lsqb&nbsp;args&nbsp;rsqb&nbsp;|&nbsp;lsqb&nbsp;rsqb;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
057&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;body&nbsp;:=&nbsp;(opt-space&nbsp;mexpr&nbsp;semi-colon)*&nbsp;opt-space&nbsp;mexpr;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
058&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fncall&nbsp;:=&nbsp;fn-name&nbsp;bindings;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
059&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lsqb&nbsp;:=&nbsp;&#x27;[&#x27;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
060&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rsqb&nbsp;:=&nbsp;&#x27;]&#x27;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
061&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lbrace&nbsp;:=&nbsp;&#x27;{&#x27;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
062&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rbrace&nbsp;:=&nbsp;&#x27;}&#x27;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
063&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;defn&nbsp;:=&nbsp;mexpr&nbsp;opt-space&nbsp;&#x27;=&#x27;&nbsp;opt-space&nbsp;mexpr;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
064&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cond&nbsp;:=&nbsp;lsqb&nbsp;(opt-space&nbsp;cond-clause&nbsp;semi-colon&nbsp;opt-space)*&nbsp;cond-clause&nbsp;rsqb;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
065&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cond-clause&nbsp;:=&nbsp;mexpr&nbsp;opt-space&nbsp;arrow&nbsp;opt-space&nbsp;mexpr&nbsp;opt-space;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
066&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;arrow&nbsp;:=&nbsp;&#x27;-&gt;&#x27;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
067&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;args&nbsp;:=&nbsp;arg&nbsp;|&nbsp;(opt-space&nbsp;arg&nbsp;semi-colon&nbsp;opt-space)*&nbsp;opt-space&nbsp;arg&nbsp;opt-space;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
068&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;arg&nbsp;:=&nbsp;mexpr;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
069&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fn-name&nbsp;:=&nbsp;mvar;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
070&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mvar&nbsp;:=&nbsp;#&#x27;[a-z][a-z0-9]*&#x27;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
071&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mconst&nbsp;:=&nbsp;#&#x27;[A-Z][A-Z0-9]*&#x27;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
072&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;semi-colon&nbsp;:=&nbsp;&#x27;;&#x27;;&quot;
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
073&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
074&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;Infix&nbsp;operators&nbsp;appear&nbsp;in&nbsp;mexprs,&nbsp;e.g.&nbsp;on&nbsp;page&nbsp;7.&nbsp;Ooops!
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
075&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;I&nbsp;do&nbsp;not&nbsp;know&nbsp;what&nbsp;infix&nbsp;operators&nbsp;are&nbsp;considered&nbsp;legal.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
076&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;In&nbsp;particular&nbsp;I&nbsp;do&nbsp;not&nbsp;know&nbsp;what&nbsp;symbol&nbsp;was&nbsp;used&nbsp;for
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
077&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;multiply
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
078&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;iexpr&nbsp;:=&nbsp;iexp&nbsp;iop&nbsp;iexp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
079&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iexp&nbsp;:=&nbsp;mexpr&nbsp;|&nbsp;number&nbsp;|&nbsp;opt-space&nbsp;iexp&nbsp;opt-space;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
080&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iop&nbsp;:=&nbsp;&#x27;&gt;&#x27;&nbsp;|&nbsp;&#x27;&lt;&#x27;&nbsp;|&nbsp;&#x27;+&#x27;&nbsp;|&nbsp;&#x27;-&#x27;&nbsp;|&nbsp;&#x27;*&#x27;&nbsp;&#x27;&#x2F;&#x27;&nbsp;|&nbsp;&#x27;=&#x27;&nbsp;;&quot;
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
081&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
082&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;comments.&nbsp;I&#x27;m&nbsp;pretty&nbsp;confident&nbsp;Lisp&nbsp;1.5&nbsp;did&nbsp;NOT&nbsp;have&nbsp;these.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
083&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;opt-comment&nbsp;:=&nbsp;opt-space&nbsp;|&nbsp;comment;&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
084&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;comment&nbsp;:=&nbsp;opt-space&nbsp;&lt;&#x27;;;&#x27;&gt;&nbsp;#&#x27;[^\\n\\r]*&#x27;&nbsp;opt-space;&quot;
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
085&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
086&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;sexprs.&nbsp;Note&nbsp;it&#x27;s&nbsp;not&nbsp;clear&nbsp;to&nbsp;me&nbsp;whether&nbsp;Lisp&nbsp;1.5&nbsp;had&nbsp;the&nbsp;quote&nbsp;macro,
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
087&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;but&nbsp;I&#x27;ve&nbsp;included&nbsp;it&nbsp;on&nbsp;the&nbsp;basis&nbsp;that&nbsp;it&nbsp;can&nbsp;do&nbsp;little&nbsp;harm.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
088&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;sexpr&nbsp;:=&nbsp;quoted-expr&nbsp;|&nbsp;atom&nbsp;|&nbsp;number&nbsp;|&nbsp;subr&nbsp;|&nbsp;dotted-pair&nbsp;|&nbsp;list&nbsp;|&nbsp;sexpr&nbsp;comment;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
089&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;list&nbsp;:=&nbsp;lpar&nbsp;sexpr&nbsp;rpar&nbsp;|&nbsp;lpar&nbsp;(sexpr&nbsp;sep)*&nbsp;rpar&nbsp;|&nbsp;lpar&nbsp;(sexpr&nbsp;sep)*&nbsp;dot-terminal&nbsp;|&nbsp;lbrace&nbsp;exprs&nbsp;rbrace;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
090&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;list&nbsp;:=&nbsp;lpar&nbsp;opt-space&nbsp;sexpr&nbsp;rpar&nbsp;|&nbsp;lpar&nbsp;opt-space&nbsp;(sexpr&nbsp;sep)*&nbsp;rpar&nbsp;|&nbsp;lpar&nbsp;opt-space&nbsp;(sexpr&nbsp;sep)*&nbsp;dot-terminal;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
091&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dotted-pair&nbsp;:=&nbsp;lpar&nbsp;dot-terminal&nbsp;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
092&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dot&nbsp;:=&nbsp;&#x27;.&#x27;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
093&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lpar&nbsp;:=&nbsp;&#x27;(&#x27;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
094&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rpar&nbsp;:=&nbsp;&#x27;)&#x27;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
095&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;quoted-expr&nbsp;:=&nbsp;quote&nbsp;sexpr;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
096&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;quote&nbsp;:=&nbsp;&#x27;\\&#x27;&#x27;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
097&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dot-terminal&nbsp;:=&nbsp;sexpr&nbsp;space&nbsp;dot&nbsp;space&nbsp;sexpr&nbsp;rpar;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
098&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;space&nbsp;:=&nbsp;#&#x27;\\p{javaWhitespace}+&#x27;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
099&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;opt-space&nbsp;:=&nbsp;#&#x27;\\p{javaWhitespace}*&#x27;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
100&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sep&nbsp;:=&nbsp;&#x27;,&#x27;&nbsp;|&nbsp;opt-space;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
101&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;atom&nbsp;:=&nbsp;#&#x27;[A-Z][A-Z0-9]*&#x27;;&quot;
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
102&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
103&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;we&nbsp;need&nbsp;a&nbsp;way&nbsp;of&nbsp;representing&nbsp;Clojure&nbsp;functions&nbsp;on&nbsp;the&nbsp;object&nbsp;list;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
104&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;subr&nbsp;objects&nbsp;aren&#x27;t&nbsp;expected&nbsp;to&nbsp;be&nbsp;normally&nbsp;entered&nbsp;on&nbsp;the&nbsp;REPL,&nbsp;but
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
105&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;must&nbsp;be&nbsp;on&nbsp;the&nbsp;object&nbsp;list&nbsp;or&nbsp;functions&nbsp;to&nbsp;which&nbsp;functions&nbsp;are&nbsp;passed
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
106&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;won&#x27;t&nbsp;be&nbsp;able&nbsp;to&nbsp;access&nbsp;them.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
107&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;subr&nbsp;:=&nbsp;#&#x27;[a-z][a-z.]*&#x2F;[A-Za-z][A-Za-z0-9]*&#x27;;&quot;
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
108&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
109&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;Lisp&nbsp;1.5&nbsp;supported&nbsp;octal&nbsp;as&nbsp;well&nbsp;as&nbsp;decimal&nbsp;and&nbsp;scientific&nbsp;notation
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
110&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;number&nbsp;:=&nbsp;integer&nbsp;|&nbsp;decimal&nbsp;|&nbsp;scientific&nbsp;|&nbsp;octal;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
111&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;integer&nbsp;:=&nbsp;#&#x27;-?[0-9]+&#x27;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
112&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;decimal&nbsp;:=&nbsp;integer&nbsp;dot&nbsp;integer;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
113&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;scientific&nbsp;:=&nbsp;coefficient&nbsp;e&nbsp;exponent;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
114&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;coefficient&nbsp;:=&nbsp;decimal&nbsp;|&nbsp;integer;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
115&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exponent&nbsp;:=&nbsp;integer;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
116&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e&nbsp;:=&nbsp;&#x27;E&#x27;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
117&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;octal&nbsp;:=&nbsp;#&#x27;[+-]?[0-7]+{1,12}&#x27;&nbsp;q&nbsp;scale-factor;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
118&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;q&nbsp;:=&nbsp;&#x27;Q&#x27;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
119&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;scale-factor&nbsp;:=&nbsp;#&#x27;[0-9]*&#x27;&quot;)))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
120&nbsp;&nbsp;
</span><br/>
</body>
</html>

View file

@ -0,0 +1,401 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" href="../../coverage.css"/> <title> beowulf/reader/simplify.clj </title>
</head>
<body>
<span class="covered" title="1 out of 1 forms covered">
001&nbsp;&nbsp;(ns&nbsp;beowulf.reader.simplify
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
002&nbsp;&nbsp;&nbsp;&nbsp;&quot;Simplify&nbsp;parse&nbsp;trees.&nbsp;Be&nbsp;aware&nbsp;that&nbsp;this&nbsp;is&nbsp;very&nbsp;tightly&nbsp;coupled
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
003&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;with&nbsp;the&nbsp;parser.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
004&nbsp;&nbsp;&nbsp;&nbsp;(:require&nbsp;[beowulf.oblist&nbsp;:refer&nbsp;[*options*]]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
005&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[instaparse.failure&nbsp;:as&nbsp;f])
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
006&nbsp;&nbsp;&nbsp;&nbsp;(:import&nbsp;[instaparse.gll&nbsp;Failure]))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
007&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
008&nbsp;&nbsp;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
009&nbsp;&nbsp;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
010&nbsp;&nbsp;;;;&nbsp;Copyright&nbsp;(C)&nbsp;2022-2023&nbsp;Simon&nbsp;Brooke
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
011&nbsp;&nbsp;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
012&nbsp;&nbsp;;;;&nbsp;This&nbsp;program&nbsp;is&nbsp;free&nbsp;software;&nbsp;you&nbsp;can&nbsp;redistribute&nbsp;it&nbsp;and&#x2F;or
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
013&nbsp;&nbsp;;;;&nbsp;modify&nbsp;it&nbsp;under&nbsp;the&nbsp;terms&nbsp;of&nbsp;the&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
014&nbsp;&nbsp;;;;&nbsp;as&nbsp;published&nbsp;by&nbsp;the&nbsp;Free&nbsp;Software&nbsp;Foundation;&nbsp;either&nbsp;version&nbsp;2
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
015&nbsp;&nbsp;;;;&nbsp;of&nbsp;the&nbsp;License,&nbsp;or&nbsp;(at&nbsp;your&nbsp;option)&nbsp;any&nbsp;later&nbsp;version.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
016&nbsp;&nbsp;;;;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
017&nbsp;&nbsp;;;;&nbsp;This&nbsp;program&nbsp;is&nbsp;distributed&nbsp;in&nbsp;the&nbsp;hope&nbsp;that&nbsp;it&nbsp;will&nbsp;be&nbsp;useful,
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
018&nbsp;&nbsp;;;;&nbsp;but&nbsp;WITHOUT&nbsp;ANY&nbsp;WARRANTY;&nbsp;without&nbsp;even&nbsp;the&nbsp;implied&nbsp;warranty&nbsp;of
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
019&nbsp;&nbsp;;;;&nbsp;MERCHANTABILITY&nbsp;or&nbsp;FITNESS&nbsp;FOR&nbsp;A&nbsp;PARTICULAR&nbsp;PURPOSE.&nbsp;&nbsp;See&nbsp;the
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
020&nbsp;&nbsp;;;;&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License&nbsp;for&nbsp;more&nbsp;details.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
021&nbsp;&nbsp;;;;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
022&nbsp;&nbsp;;;;&nbsp;You&nbsp;should&nbsp;have&nbsp;received&nbsp;a&nbsp;copy&nbsp;of&nbsp;the&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
023&nbsp;&nbsp;;;;&nbsp;along&nbsp;with&nbsp;this&nbsp;program;&nbsp;if&nbsp;not,&nbsp;write&nbsp;to&nbsp;the&nbsp;Free&nbsp;Software
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
024&nbsp;&nbsp;;;;&nbsp;Foundation,&nbsp;Inc.,&nbsp;51&nbsp;Franklin&nbsp;Street,&nbsp;Fifth&nbsp;Floor,&nbsp;Boston,&nbsp;MA&nbsp;&nbsp;02110-1301,&nbsp;USA.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
025&nbsp;&nbsp;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
026&nbsp;&nbsp;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
027&nbsp;&nbsp;
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
028&nbsp;&nbsp;(declare&nbsp;simplify-tree)
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
029&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
030&nbsp;&nbsp;(defn&nbsp;remove-optional-space
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
031&nbsp;&nbsp;&nbsp;&nbsp;[tree]
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
032&nbsp;&nbsp;&nbsp;&nbsp;(if&nbsp;(vector?&nbsp;tree)
</span><br/>
<span class="covered" title="7 out of 7 forms covered">
033&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if&nbsp;(=&nbsp;:opt-space&nbsp;(first&nbsp;tree))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
034&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nil
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
035&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[v&nbsp;(remove&nbsp;nil?
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
036&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map&nbsp;remove-optional-space&nbsp;tree))]
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
037&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if&nbsp;(seq&nbsp;v)
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
038&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(apply&nbsp;vector&nbsp;v)
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
039&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;v)))
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
040&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tree))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
041&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
042&nbsp;&nbsp;(defn&nbsp;remove-nesting
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
043&nbsp;&nbsp;&nbsp;&nbsp;[tree&nbsp;context]
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
044&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[tree&#x27;&nbsp;(remove-optional-space&nbsp;tree)]
</span><br/>
<span class="not-covered" title="0 out of 15 forms covered">
045&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if-let&nbsp;[key&nbsp;(when&nbsp;(and&nbsp;(vector?&nbsp;tree&#x27;)&nbsp;
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
046&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(keyword?&nbsp;(first&nbsp;tree&#x27;)))&nbsp;
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
047&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(first&nbsp;tree&#x27;))]
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
048&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(loop&nbsp;[r&nbsp;tree&#x27;]
</span><br/>
<span class="not-covered" title="0 out of 18 forms covered">
049&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if&nbsp;(and&nbsp;r&nbsp;(vector?&nbsp;r)&nbsp;(keyword?&nbsp;(first&nbsp;r)))
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
050&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if&nbsp;(=&nbsp;(first&nbsp;r)&nbsp;key)
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
051&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(recur&nbsp;(simplify-tree&nbsp;(second&nbsp;r)&nbsp;context))
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
052&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r)
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
053&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r))
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
054&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tree&#x27;)))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
055&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
056&nbsp;&nbsp;(defn&nbsp;simplify-tree
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
057&nbsp;&nbsp;&nbsp;&nbsp;&quot;Simplify&nbsp;this&nbsp;parse&nbsp;tree&nbsp;`p`.&nbsp;If&nbsp;`p`&nbsp;is&nbsp;an&nbsp;instaparse&nbsp;failure&nbsp;object,&nbsp;throw
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
058&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;an&nbsp;`ex-info`,&nbsp;with&nbsp;`p`&nbsp;as&nbsp;the&nbsp;value&nbsp;of&nbsp;its&nbsp;`:failure`&nbsp;key.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
059&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
060&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;**NOTE&nbsp;THAT**&nbsp;it&nbsp;is&nbsp;assumed&nbsp;that&nbsp;`remove-optional-space`&nbsp;has&nbsp;been&nbsp;run&nbsp;on&nbsp;the
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
061&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;parse&nbsp;tree&nbsp;**BEFORE**&nbsp;it&nbsp;is&nbsp;passed&nbsp;to&nbsp;`simplify-tree`.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
062&nbsp;&nbsp;&nbsp;&nbsp;([p]
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
063&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
064&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(instance?&nbsp;Failure&nbsp;p)
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
065&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(throw&nbsp;(ex-info
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
066&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(str&nbsp;&quot;Ic&nbsp;ne&nbsp;behæfd:&nbsp;&quot;&nbsp;(f&#x2F;pprint-failure&nbsp;p))
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
067&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{:cause&nbsp;:parse-failure
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
068&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:phase&nbsp;&nbsp;&nbsp;:simplify
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
069&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:failure&nbsp;p}))
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
070&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(simplify-tree&nbsp;p&nbsp;:expr)))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
071&nbsp;&nbsp;&nbsp;&nbsp;([p&nbsp;context]
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
072&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cond
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
073&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(string?&nbsp;p)&nbsp;p
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
074&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(coll?&nbsp;p)&nbsp;(apply
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
075&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vector
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
076&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(remove
</span><br/>
<span class="covered" title="8 out of 8 forms covered">
077&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#(when&nbsp;(coll?&nbsp;%)&nbsp;(empty?&nbsp;%))
</span><br/>
<span class="partial" title="16 out of 19 forms covered">
078&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(case&nbsp;(first&nbsp;p)
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
079&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:λexpr
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
080&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:args&nbsp;:bindings&nbsp;:body&nbsp;:cond&nbsp;:cond-clause&nbsp;:defn&nbsp;:dot-terminal&nbsp;
</span><br/>
<span class="partial" title="80 out of 96 forms covered">
081&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:fncall&nbsp;:lhs&nbsp;:quoted-expr&nbsp;:rhs&nbsp;)&nbsp;(map&nbsp;#(simplify-tree&nbsp;%&nbsp;context)&nbsp;p)
</span><br/>
<span class="partial" title="24 out of 30 forms covered">
082&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:arg&nbsp;:expr&nbsp;:coefficient&nbsp;:fn-name&nbsp;:number)&nbsp;(simplify-tree&nbsp;(second&nbsp;p)&nbsp;context)
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
083&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:arrow&nbsp;:dot&nbsp;:e&nbsp;:lpar&nbsp;:lsqb&nbsp;&nbsp;:opt-comment&nbsp;:opt-space&nbsp;:q&nbsp;:quote&nbsp;:rpar&nbsp;:rsqb
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
084&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:semi-colon&nbsp;:sep&nbsp;:space)&nbsp;nil
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
085&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:atom&nbsp;(if
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
086&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(=&nbsp;context&nbsp;:mexpr)
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
087&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[:quoted-expr&nbsp;p]
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
088&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p)
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
089&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:comment&nbsp;(when
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
090&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:strict&nbsp;*options*)
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
091&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(throw
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
092&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(ex-info&nbsp;&quot;Cannot&nbsp;parse&nbsp;comments&nbsp;in&nbsp;strict&nbsp;mode&quot;
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
093&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{:cause&nbsp;:strict})))
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
094&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:decimal&nbsp;:integer&nbsp;:mconst&nbsp;:octal&nbsp;:scientific)&nbsp;p
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
095&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:dotted-pair&nbsp;(if
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
096&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(=&nbsp;context&nbsp;:mexpr)
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
097&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[:fncall
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
098&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[:mvar&nbsp;&quot;cons&quot;]
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
099&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[:args
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
100&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(simplify-tree&nbsp;(nth&nbsp;p&nbsp;1)&nbsp;context)
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
101&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(simplify-tree&nbsp;(nth&nbsp;p&nbsp;2)&nbsp;context)]]
</span><br/>
<span class="not-covered" title="0 out of 8 forms covered">
102&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map&nbsp;#(simplify-tree&nbsp;%&nbsp;context)&nbsp;p))
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
103&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:iexp&nbsp;(simplify-tree&nbsp;(second&nbsp;p)&nbsp;context)
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
104&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:iexpr&nbsp;[:iexpr
</span><br/>
<span class="not-covered" title="0 out of 8 forms covered">
105&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[:lhs&nbsp;(simplify-tree&nbsp;(second&nbsp;p)&nbsp;context)]
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
106&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(simplify-tree&nbsp;(nth&nbsp;p&nbsp;2)&nbsp;context)&nbsp;;;&nbsp;really&nbsp;should&nbsp;be&nbsp;the&nbsp;operator
</span><br/>
<span class="not-covered" title="0 out of 8 forms covered">
107&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[:rhs&nbsp;(simplify-tree&nbsp;(nth&nbsp;p&nbsp;3)&nbsp;context)]]
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
108&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:mexpr&nbsp;(if
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
109&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:strict&nbsp;*options*)
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
110&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(throw
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
111&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(ex-info&nbsp;&quot;Cannot&nbsp;parse&nbsp;meta&nbsp;expressions&nbsp;in&nbsp;strict&nbsp;mode&quot;
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
112&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{:cause&nbsp;:strict}))
</span><br/>
<span class="covered" title="8 out of 8 forms covered">
113&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[:mexpr&nbsp;(simplify-tree&nbsp;(second&nbsp;p)&nbsp;:mexpr)])
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
114&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:list&nbsp;(if
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
115&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(=&nbsp;context&nbsp;:mexpr)
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
116&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[:fncall
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
117&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[:mvar&nbsp;&quot;list&quot;]
</span><br/>
<span class="not-covered" title="0 out of 11 forms covered">
118&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[:args&nbsp;(apply&nbsp;vector&nbsp;(map&nbsp;simplify-tree&nbsp;(rest&nbsp;p)))]]
</span><br/>
<span class="covered" title="8 out of 8 forms covered">
119&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map&nbsp;#(simplify-tree&nbsp;%&nbsp;context)&nbsp;p))
</span><br/>
<span class="covered" title="11 out of 11 forms covered">
120&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:raw&nbsp;(first&nbsp;(remove&nbsp;empty?&nbsp;(map&nbsp;simplify-tree&nbsp;(rest&nbsp;p))))
</span><br/>
<span class="covered" title="8 out of 8 forms covered">
121&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:sexpr&nbsp;[:sexpr&nbsp;(simplify-tree&nbsp;(second&nbsp;p)&nbsp;:sexpr)]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
122&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;default
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
123&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p)))
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
124&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:else&nbsp;p)))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
125&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
126&nbsp;&nbsp;(defn&nbsp;simplify
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
127&nbsp;&nbsp;&nbsp;&nbsp;&quot;Simplify&nbsp;this&nbsp;parse&nbsp;tree&nbsp;`p`.&nbsp;If&nbsp;`p`&nbsp;is&nbsp;an&nbsp;instaparse&nbsp;failure&nbsp;object,&nbsp;throw
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
128&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;an&nbsp;`ex-info`,&nbsp;with&nbsp;`p`&nbsp;as&nbsp;the&nbsp;value&nbsp;of&nbsp;its&nbsp;`:failure`&nbsp;key.&nbsp;Calls&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
129&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`remove-optional-space`&nbsp;before&nbsp;processing.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
130&nbsp;&nbsp;&nbsp;&nbsp;[p]
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
131&nbsp;&nbsp;&nbsp;&nbsp;(simplify-tree&nbsp;(remove-optional-space&nbsp;p)))
</span><br/>
</body>
</html>

View file

@ -16,88 +16,225 @@
</tr></thead> </tr></thead>
<tr> <tr>
<td><a href="beowulf/bootstrap.clj.html">beowulf.bootstrap</a></td><td class="with-bar"><div class="covered" <td><a href="beowulf/bootstrap.clj.html">beowulf.bootstrap</a></td><td class="with-bar"><div class="covered"
style="width:60.47808764940239%; style="width:63.9344262295082%;
float:left;"> 759 </div><div class="not-covered" float:left;"> 624 </div><div class="not-covered"
style="width:39.52191235059761%; style="width:36.0655737704918%;
float:left;"> 496 </div></td> float:left;"> 352 </div></td>
<td class="with-number">60.48 %</td> <td class="with-number">63.93 %</td>
<td class="with-bar"><div class="covered" <td class="with-bar"><div class="covered"
style="width:47.92626728110599%; style="width:59.48275862068966%;
float:left;"> 104 </div><div class="partial" float:left;"> 138 </div><div class="partial"
style="width:19.35483870967742%; style="width:8.189655172413794%;
float:left;"> 42 </div><div class="not-covered" float:left;"> 19 </div><div class="not-covered"
style="width:32.71889400921659%; style="width:32.327586206896555%;
float:left;"> 71 </div></td> float:left;"> 75 </div></td>
<td class="with-number">67.28 %</td> <td class="with-number">67.67 %</td>
<td class="with-number">414</td><td class="with-number">46</td><td class="with-number">217</td> <td class="with-number">422</td><td class="with-number">33</td><td class="with-number">232</td>
</tr> </tr>
<tr> <tr>
<td><a href="beowulf/cons_cell.clj.html">beowulf.cons-cell</a></td><td class="with-bar"><div class="covered" <td><a href="beowulf/cons_cell.clj.html">beowulf.cons-cell</a></td><td class="with-bar"><div class="covered"
style="width:56.82819383259912%; style="width:72.34927234927235%;
float:left;"> 129 </div><div class="not-covered" float:left;"> 348 </div><div class="not-covered"
style="width:43.17180616740088%; style="width:27.65072765072765%;
float:left;"> 98 </div></td> float:left;"> 133 </div></td>
<td class="with-number">56.83 %</td> <td class="with-number">72.35 %</td>
<td class="with-bar"><div class="covered" <td class="with-bar"><div class="covered"
style="width:57.35294117647059%; style="width:75.17241379310344%;
float:left;"> 39 </div><div class="partial" float:left;"> 109 </div><div class="partial"
style="width:4.411764705882353%; style="width:6.206896551724138%;
float:left;"> 3 </div><div class="not-covered" float:left;"> 9 </div><div class="not-covered"
style="width:38.23529411764706%; style="width:18.620689655172413%;
float:left;"> 26 </div></td> float:left;"> 27 </div></td>
<td class="with-number">61.76 %</td> <td class="with-number">81.38 %</td>
<td class="with-number">156</td><td class="with-number">15</td><td class="with-number">68</td> <td class="with-number">274</td><td class="with-number">23</td><td class="with-number">145</td>
</tr> </tr>
<tr> <tr>
<td><a href="beowulf/core.clj.html">beowulf.core</a></td><td class="with-bar"><div class="covered" <td><a href="beowulf/core.clj.html">beowulf.core</a></td><td class="with-bar"><div class="covered"
style="width:90.9090909090909%; style="width:69.47368421052632%;
float:left;"> 170 </div><div class="not-covered" float:left;"> 198 </div><div class="not-covered"
style="width:9.090909090909092%; style="width:30.526315789473685%;
float:left;"> 17 </div></td> float:left;"> 87 </div></td>
<td class="with-number">90.91 %</td> <td class="with-number">69.47 %</td>
<td class="with-bar"><div class="covered" <td class="with-bar"><div class="covered"
style="width:87.75510204081633%; style="width:72.46376811594203%;
float:left;"> 43 </div><div class="partial" float:left;"> 50 </div><div class="partial"
style="width:2.0408163265306123%; style="width:5.797101449275362%;
float:left;"> 1 </div><div class="not-covered" float:left;"> 4 </div><div class="not-covered"
style="width:10.204081632653061%; style="width:21.73913043478261%;
float:left;"> 5 </div></td> float:left;"> 15 </div></td>
<td class="with-number">89.80 %</td> <td class="with-number">78.26 %</td>
<td class="with-number">80</td><td class="with-number">3</td><td class="with-number">49</td> <td class="with-number">132</td><td class="with-number">6</td><td class="with-number">69</td>
</tr> </tr>
<tr> <tr>
<td><a href="beowulf/host.clj.html">beowulf.host</a></td><td class="with-bar"><div class="covered" <td><a href="beowulf/host.clj.html">beowulf.host</a></td><td class="with-bar"><div class="covered"
style="width:42.77384423157018%;
float:left;"> 1027 </div><div class="not-covered"
style="width:57.22615576842982%;
float:left;"> 1374 </div></td>
<td class="with-number">42.77 %</td>
<td class="with-bar"><div class="covered"
style="width:53.72549019607843%;
float:left;"> 137 </div><div class="partial"
style="width:14.509803921568627%;
float:left;"> 37 </div><div class="not-covered"
style="width:31.764705882352942%;
float:left;"> 81 </div></td>
<td class="with-number">68.24 %</td>
<td class="with-number">571</td><td class="with-number">66</td><td class="with-number">255</td>
</tr>
<tr>
<td><a href="beowulf/interop.clj.html">beowulf.interop</a></td><td class="with-bar"><div class="covered"
style="width:57.72357723577236%;
float:left;"> 142 </div><div class="not-covered"
style="width:42.27642276422764%;
float:left;"> 104 </div></td>
<td class="with-number">57.72 %</td>
<td class="with-bar"><div class="covered"
style="width:46.96969696969697%;
float:left;"> 31 </div><div class="partial"
style="width:9.090909090909092%;
float:left;"> 6 </div><div class="not-covered"
style="width:43.93939393939394%;
float:left;"> 29 </div></td>
<td class="with-number">56.06 %</td>
<td class="with-number">129</td><td class="with-number">11</td><td class="with-number">66</td>
</tr>
<tr>
<td><a href="beowulf/io.clj.html">beowulf.io</a></td><td class="with-bar"><div class="covered"
style="width:43.962848297213625%;
float:left;"> 142 </div><div class="not-covered"
style="width:56.037151702786375%;
float:left;"> 181 </div></td>
<td class="with-number">43.96 %</td>
<td class="with-bar"><div class="covered"
style="width:46.478873239436616%;
float:left;"> 33 </div><div class="partial"
style="width:8.450704225352112%;
float:left;"> 6 </div><div class="not-covered"
style="width:45.070422535211264%;
float:left;"> 32 </div></td>
<td class="with-number">54.93 %</td>
<td class="with-number">171</td><td class="with-number">12</td><td class="with-number">71</td>
</tr>
<tr>
<td><a href="beowulf/manual.clj.html">beowulf.manual</a></td><td class="with-bar"><div class="covered"
style="width:95.93088071348942%;
float:left;"> 1721 </div><div class="not-covered"
style="width:4.069119286510591%;
float:left;"> 73 </div></td>
<td class="with-number">95.93 %</td>
<td class="with-bar"><div class="covered"
style="width:94.60317460317461%;
float:left;"> 298 </div><div class="not-covered"
style="width:5.396825396825397%;
float:left;"> 17 </div></td>
<td class="with-number">94.60 %</td>
<td class="with-number">769</td><td class="with-number">4</td><td class="with-number">315</td>
</tr>
<tr>
<td><a href="beowulf/oblist.clj.html">beowulf.oblist</a></td><td class="with-bar"><div class="covered"
style="width:100.0%; style="width:100.0%;
float:left;"> 1 </div></td> float:left;"> 9 </div></td>
<td class="with-number">100.00 %</td> <td class="with-number">100.00 %</td>
<td class="with-bar"><div class="covered" <td class="with-bar"><div class="covered"
style="width:100.0%; style="width:100.0%;
float:left;"> 1 </div></td> float:left;"> 6 </div></td>
<td class="with-number">100.00 %</td> <td class="with-number">100.00 %</td>
<td class="with-number">5</td><td class="with-number">1</td><td class="with-number">1</td> <td class="with-number">45</td><td class="with-number">5</td><td class="with-number">6</td>
</tr> </tr>
<tr> <tr>
<td><a href="beowulf/read.clj.html">beowulf.read</a></td><td class="with-bar"><div class="covered" <td><a href="beowulf/read.clj.html">beowulf.read</a></td><td class="with-bar"><div class="covered"
style="width:81.8941504178273%; style="width:49.43181818181818%;
float:left;"> 588 </div><div class="not-covered" float:left;"> 87 </div><div class="not-covered"
style="width:18.105849582172702%; style="width:50.56818181818182%;
float:left;"> 130 </div></td> float:left;"> 89 </div></td>
<td class="with-number">81.89 %</td> <td class="with-number">49.43 %</td>
<td class="with-bar"><div class="covered" <td class="with-bar"><div class="covered"
style="width:73.80952380952381%; style="width:53.84615384615385%;
float:left;"> 93 </div><div class="partial" float:left;"> 21 </div><div class="partial"
style="width:7.6923076923076925%;
float:left;"> 3 </div><div class="not-covered"
style="width:38.46153846153846%;
float:left;"> 15 </div></td>
<td class="with-number">61.54 %</td>
<td class="with-number">108</td><td class="with-number">9</td><td class="with-number">39</td>
</tr>
<tr>
<td><a href="beowulf/reader/char_reader.clj.html">beowulf.reader.char-reader</a></td><td class="with-bar"><div class="covered"
style="width:100.0%;
float:left;"> 1 </div></td>
<td class="with-number">100.00 %</td>
<td class="with-bar"><div class="covered"
style="width:100.0%;
float:left;"> 1 </div></td>
<td class="with-number">100.00 %</td>
<td class="with-number">75</td><td class="with-number">4</td><td class="with-number">1</td>
</tr>
<tr>
<td><a href="beowulf/reader/generate.clj.html">beowulf.reader.generate</a></td><td class="with-bar"><div class="covered"
style="width:69.7872340425532%;
float:left;"> 492 </div><div class="not-covered"
style="width:30.21276595744681%;
float:left;"> 213 </div></td>
<td class="with-number">69.79 %</td>
<td class="with-bar"><div class="covered"
style="width:67.46031746031746%;
float:left;"> 85 </div><div class="partial"
style="width:7.936507936507937%; style="width:7.936507936507937%;
float:left;"> 10 </div><div class="not-covered" float:left;"> 10 </div><div class="not-covered"
style="width:18.253968253968253%; style="width:24.603174603174605%;
float:left;"> 23 </div></td> float:left;"> 31 </div></td>
<td class="with-number">81.75 %</td> <td class="with-number">75.40 %</td>
<td class="with-number">315</td><td class="with-number">31</td><td class="with-number">126</td> <td class="with-number">276</td><td class="with-number">21</td><td class="with-number">126</td>
</tr>
<tr>
<td><a href="beowulf/reader/macros.clj.html">beowulf.reader.macros</a></td><td class="with-bar"><div class="covered"
style="width:80.18867924528301%;
float:left;"> 85 </div><div class="not-covered"
style="width:19.81132075471698%;
float:left;"> 21 </div></td>
<td class="with-number">80.19 %</td>
<td class="with-bar"><div class="covered"
style="width:70.0%;
float:left;"> 14 </div><div class="not-covered"
style="width:30.0%;
float:left;"> 6 </div></td>
<td class="with-number">70.00 %</td>
<td class="with-number">68</td><td class="with-number">4</td><td class="with-number">20</td>
</tr>
<tr>
<td><a href="beowulf/reader/parser.clj.html">beowulf.reader.parser</a></td><td class="with-bar"><div class="covered"
style="width:100.0%;
float:left;"> 17 </div></td>
<td class="with-number">100.00 %</td>
<td class="with-bar"><div class="covered"
style="width:100.0%;
float:left;"> 4 </div></td>
<td class="with-number">100.00 %</td>
<td class="with-number">120</td><td class="with-number">14</td><td class="with-number">4</td>
</tr>
<tr>
<td><a href="beowulf/reader/simplify.clj.html">beowulf.reader.simplify</a></td><td class="with-bar"><div class="covered"
style="width:57.30337078651685%;
float:left;"> 255 </div><div class="not-covered"
style="width:42.69662921348315%;
float:left;"> 190 </div></td>
<td class="with-number">57.30 %</td>
<td class="with-bar"><div class="covered"
style="width:49.382716049382715%;
float:left;"> 40 </div><div class="partial"
style="width:3.7037037037037037%;
float:left;"> 3 </div><div class="not-covered"
style="width:46.91358024691358%;
float:left;"> 38 </div></td>
<td class="with-number">53.09 %</td>
<td class="with-number">131</td><td class="with-number">6</td><td class="with-number">81</td>
</tr> </tr>
<tr><td>Totals:</td> <tr><td>Totals:</td>
<td class="with-bar"></td> <td class="with-bar"></td>
<td class="with-number">68.97 %</td> <td class="with-number">64.63 %</td>
<td class="with-bar"></td> <td class="with-bar"></td>
<td class="with-number">72.89 %</td> <td class="with-number">74.41 %</td>
</tr> </tr>
</table> </table>
</body> </body>

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,12 +1,28 @@
body { body {
font-family: Helvetica, Arial, sans-serif; font-family: Helvetica, Arial, sans-serif;
font-size: 15px; font-size: 15px;
color: limegreen;
background-color: black;
}
a {
color: lime;
}
a:active, a:hover {
color: yellowgreen;
}
a:visited {
color: green;
} }
pre, code { pre, code {
font-family: Monaco, DejaVu Sans Mono, Consolas, monospace; font-family: Monaco, DejaVu Sans Mono, Consolas, monospace;
font-size: 9pt; font-size: 9pt;
margin: 15px 0; margin: 15px 0;
color: limegreen;
background-color: #111;
} }
h1 { h1 {
@ -21,9 +37,13 @@ h2 {
font-size: 25px; font-size: 25px;
} }
th, td {
vertical-align: top;
}
h5.license { h5.license {
margin: 9px 0 22px 0; margin: 9px 0 22px 0;
color: #555; color: lime;
font-weight: normal; font-weight: normal;
font-size: 12px; font-size: 12px;
font-style: italic; font-style: italic;
@ -43,7 +63,7 @@ h5.license {
left: 0; left: 0;
right: 0; right: 0;
height: 22px; height: 22px;
color: #f5f5f5; color: limegreen;
padding: 5px 7px; padding: 5px 7px;
} }
@ -52,8 +72,8 @@ h5.license {
right: 0; right: 0;
bottom: 0; bottom: 0;
overflow: auto; overflow: auto;
background: #fff; background: black;
color: #333; color: green;
padding: 0 18px; padding: 0 18px;
} }
@ -65,15 +85,15 @@ h5.license {
} }
.sidebar.primary { .sidebar.primary {
background: #e2e2e2; background: #080808;
border-right: solid 1px #cccccc; border-right: solid 1px forestgreen;
left: 0; left: 0;
width: 250px; width: 250px;
} }
.sidebar.secondary { .sidebar.secondary {
background: #f2f2f2; background: #111;
border-right: solid 1px #d7d7d7; border-right: solid 1px darkgreen;
left: 251px; left: 251px;
width: 200px; width: 200px;
} }
@ -91,8 +111,8 @@ h5.license {
} }
#header { #header {
background: #3f3f3f; background: #080808;
box-shadow: 0 0 8px rgba(0, 0, 0, 0.4); box-shadow: 0 0 8px rgba(192, 255, 192, 0.4);
z-index: 100; z-index: 100;
} }
@ -117,21 +137,13 @@ h5.license {
text-decoration: none; text-decoration: none;
} }
#header a {
color: #f5f5f5;
}
.sidebar a {
color: #333;
}
#header h2 { #header h2 {
float: right; float: right;
font-size: 9pt; font-size: 9pt;
font-weight: normal; font-weight: normal;
margin: 4px 3px; margin: 4px 3px;
padding: 0; padding: 0;
color: #bbb; color: #5f5;
} }
#header h2 a { #header h2 a {
@ -146,11 +158,11 @@ h5.license {
} }
.sidebar h3 a { .sidebar h3 a {
color: #444; color: #4f4;
} }
.sidebar h3.no-link { .sidebar h3.no-link {
color: #636363; color: green;
} }
.sidebar ul { .sidebar ul {
@ -175,7 +187,7 @@ h5.license {
.sidebar li .no-link { .sidebar li .no-link {
display: block; display: block;
color: #777; color: #7F7;
font-style: italic; font-style: italic;
} }
@ -217,8 +229,8 @@ h5.license {
} }
.sidebar li .tree .top { .sidebar li .tree .top {
border-left: 1px solid #aaa; border-left: 1px solid yellowgreen;
border-bottom: 1px solid #aaa; border-bottom: 1px solid yellowgreen;
height: 19px; height: 19px;
} }
@ -227,17 +239,17 @@ h5.license {
} }
.sidebar li.branch .tree .bottom { .sidebar li.branch .tree .bottom {
border-left: 1px solid #aaa; border-left: 1px solid yellowgreen;
} }
.sidebar.primary li.current a { .sidebar.primary li.current a {
border-left: 3px solid #a33; border-left: 3px solid goldenrod;
color: #a33; color: goldenrod;
} }
.sidebar.secondary li.current a { .sidebar.secondary li.current a {
border-left: 3px solid #33a; border-left: 3px solid yellow;
color: #33a; color: yellow;
} }
.namespace-index h2 { .namespace-index h2 {
@ -275,7 +287,7 @@ h5.license {
.public { .public {
margin: 0; margin: 0;
border-top: 1px solid #e0e0e0; border-top: 1px solid lime;
padding-top: 14px; padding-top: 14px;
padding-bottom: 6px; padding-bottom: 6px;
} }
@ -293,7 +305,7 @@ h5.license {
} }
.members h4 { .members h4 {
color: #555; color: lime;
font-weight: normal; font-weight: normal;
font-variant: small-caps; font-variant: small-caps;
margin: 0 0 5px 0; margin: 0 0 5px 0;
@ -304,7 +316,7 @@ h5.license {
padding-left: 12px; padding-left: 12px;
margin-top: 2px; margin-top: 2px;
margin-left: 7px; margin-left: 7px;
border-left: 1px solid #bbb; border-left: 1px solid #5f5;
} }
#content .members .inner h3 { #content .members .inner h3 {
@ -357,7 +369,7 @@ h4.dynamic {
} }
h4.added { h4.added {
color: #508820; color: #7acc32;
} }
h4.deprecated { h4.deprecated {
@ -397,7 +409,7 @@ h4.deprecated {
.type-sig { .type-sig {
clear: both; clear: both;
color: #088; color: goldenrod;
} }
.type-sig pre { .type-sig pre {
@ -407,8 +419,8 @@ h4.deprecated {
.usage code { .usage code {
display: block; display: block;
color: #008;
margin: 2px 0; margin: 2px 0;
color: limegreen;
} }
.usage code:first-child { .usage code:first-child {
@ -476,27 +488,27 @@ p {
} }
.markdown pre > code, .src-link a { .markdown pre > code, .src-link a {
border: 1px solid #e4e4e4; border: 1px solid lime;
border-radius: 2px; border-radius: 2px;
} }
.markdown code:not(.hljs), .src-link a { .markdown code:not(.hljs), .src-link a {
background: #f6f6f6; background: #111;
} }
pre.deps { pre.deps {
display: inline-block; display: inline-block;
margin: 0 10px; margin: 0 10px;
border: 1px solid #e4e4e4; border: 1px solid lime;
border-radius: 2px; border-radius: 2px;
padding: 10px; padding: 10px;
background-color: #f6f6f6; background-color: #111;
} }
.markdown hr { .markdown hr {
border-style: solid; border-style: solid;
border-top: none; border-top: none;
color: #ccc; color: goldenrod;
} }
.doc ul, .doc ol { .doc ul, .doc ol {
@ -509,12 +521,12 @@ pre.deps {
} }
.doc table td, .doc table th { .doc table td, .doc table th {
border: 1px solid #dddddd; border: 1px solid goldenrod;
padding: 4px 6px; padding: 4px 6px;
} }
.doc table th { .doc table th {
background: #f2f2f2; background: #111;
} }
.doc dl { .doc dl {
@ -525,7 +537,7 @@ pre.deps {
font-weight: bold; font-weight: bold;
margin: 0; margin: 0;
padding: 3px 0; padding: 3px 0;
border-bottom: 1px solid #ddd; border-bottom: 1px solid goldenrod;
} }
.doc dl dd { .doc dl dd {
@ -534,7 +546,7 @@ pre.deps {
} }
.doc abbr { .doc abbr {
border-bottom: 1px dotted #333; border-bottom: 1px dotted goldenrod;
font-variant: none; font-variant: none;
cursor: help; cursor: help;
} }
@ -547,5 +559,5 @@ pre.deps {
font-size: 70%; font-size: 70%;
padding: 1px 4px; padding: 1px 4px;
text-decoration: none; text-decoration: none;
color: #5555bb; color: lime5bb;
} }

View file

@ -0,0 +1,17 @@
<!DOCTYPE html PUBLIC ""
"">
<html><head><meta charset="UTF-8" /><title>Further Reading</title><link rel="icon" type="image/x-icon" href="../img/beowulf_logo_favicon.png" /><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</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="further_reading.html"><div class="inner"><span>Further Reading</span></div></a></li><li class="depth-1 "><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>Interpreting M-Expressions</span></div></a></li><li class="depth-1 "><a href="values.html"><div class="inner"><span>The properties of the system, and their values</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.interop.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>interop</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></ul></div><div class="document" id="content"><div class="doc"><div class="markdown"><h1><a href="#further-reading" name="further-reading"></a>Further Reading</h1>
<ol>
<li><a href="http://bitsavers.org/pdf/mit/computer_center/Coding_for_the_MIT-IBM_704_Computer_Oct57.pdf">CODING for the MIT-IBM 704 COMPUTER, October 1957</a> This paper is not about Lisp. But it is about the particular individual computer on which Lisp was first implemented, and it is written in part by members of the Lisp team. I have found it useful in understanding the software environment in which, and the constraints under which, Lisp was written.</li>
<li><a href="https://www.softwarepreservation.org/projects/LISP/MIT/AIM-001.pdf">MIT AI Memo 1, John McCarthy, September 1958</a> This is, as far as I can find, the earliest specification document of the Lisp project.</li>
<li><a href="https://bitsavers.org/pdf/mit/rle_lisp/LISP_I_Programmers_Manual_Mar60.pdf">Lisp 1 Programmers Manual, Phyllis Fox, March 1960</a></li>
<li><a href="https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=81">Lisp 1.5 Programmers Manual, Michael I. Levin, August 1962</a> This book is essential reading: it documents in some detail the first fully realised Lisp language system.</li>
<li><a href="https://dl.acm.org/doi/pdf/10.1145/800055.802047#page=3">Early LISP History (1956 - 1959), Herbert Stoyan, August 1984</a></li>
<li>
<p><a href="http://www.paulgraham.com/rootsoflisp.html">The Roots of Lisp, Paul Graham, 2001</a></p></li>
<li>
<p><a href="http://www.paulgraham.com/icad.html">The Revenge of the Nerds, Paul Graham, 2002</a> This is mainly about why to use Lisp as a language for modern commercial software, but has useful insights into where it comes from.</p>
<blockquote>
<p>So the short explanation of why this 1950s language is not obsolete is that it was not technology but math, and math doesnt get stale.</p>
</blockquote></li>
</ol></div></div></div></body></html>

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

BIN
docs/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
docs/img/beowulf_logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 KiB

BIN
docs/img/beowulf_logo.xcf Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

14
docs/index.html Normal file
View file

@ -0,0 +1,14 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Beowulf: Documentation</title>
<link rel="stylesheet" type="text/css" href="codox/css/default.css" />
</head>
<body>
<h1>Beowulf: Documentation</h1>
<ul>
<li><a href="codox/index.html">Primary documentaion</a></li>
<li><a href="cloverage/index.html">Test coverage</a></li>
</ul>
</body>
</html>

View file

@ -1,30 +1,37 @@
(defproject beowulf "0.3.0-SNAPSHOT" (defproject beowulf "0.3.0"
:aot :all
:cloverage {:output "docs/cloverage" :cloverage {:output "docs/cloverage"
:ns-exclude-regex [#"beowulf\.gendoc" #"beowulf\.scratch"]} :ns-exclude-regex [#"beowulf\.gendoc" #"beowulf\.scratch"]}
:codox {:metadata {:doc "**TODO**: write docs" :codox {:html {:transforms [[:head] [:append
[:link {:rel "icon"
:type "image/x-icon"
:href "../img/beowulf_logo_favicon.png"}]]]}
:metadata {:doc "**TODO**: write docs"
:doc/format :markdown} :doc/format :markdown}
:output-path "docs/codox" :output-path "docs/codox"
:source-uri "https://github.com/simon-brooke/beowulf/blob/master/{filepath}#L{line}"} :source-uri "https://github.com/simon-brooke/beowulf/blob/master/{filepath}#L{line}"
:description "An implementation of LISP 1.5 in Clojure" ;; :themes [:journeyman]
}
:description "LISP 1.5 is to all Lisp dialects as Beowulf is to English literature."
: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.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"]
[org.jline/jline "3.23.0"] ;; [org.jline/jline "3.23.0"]
[rhizome "0.2.9"] ;; not needed in production builds [rhizome "0.2.9"] ;; not needed in production builds
] ]
:main ^:skip-aot beowulf.core :main beowulf.core
: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 {:jar {:aot :all}
:omit-source true :uberjar {:aot :all}}
: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,6 +41,5 @@
["uberjar"] ["uberjar"]
["change" "version" "leiningen.release/bump-version"] ["change" "version" "leiningen.release/bump-version"]
["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

@ -0,0 +1,563 @@
body {
font-family: Helvetica, Arial, sans-serif;
font-size: 15px;
color: limegreen;
background-color: black;
}
a {
color: lime;
}
a:active, a:hover {
color: yellowgreen;
}
a:visited {
color: green;
}
pre, code {
font-family: Monaco, DejaVu Sans Mono, Consolas, monospace;
font-size: 9pt;
margin: 15px 0;
color: limegreen;
background-color: #111;
}
h1 {
font-weight: normal;
font-size: 29px;
margin: 10px 0 2px 0;
padding: 0;
}
h2 {
font-weight: normal;
font-size: 25px;
}
th, td {
vertical-align: top;
}
h5.license {
margin: 9px 0 22px 0;
color: lime;
font-weight: normal;
font-size: 12px;
font-style: italic;
}
.document h1, .namespace-index h1 {
font-size: 32px;
margin-top: 12px;
}
#header, #content, .sidebar {
position: fixed;
}
#header {
top: 0;
left: 0;
right: 0;
height: 22px;
color: limegreen;
padding: 5px 7px;
}
#content {
top: 32px;
right: 0;
bottom: 0;
overflow: auto;
background: black;
color: green;
padding: 0 18px;
}
.sidebar {
position: fixed;
top: 32px;
bottom: 0;
overflow: auto;
}
.sidebar.primary {
background: #080808;
border-right: solid 1px forestgreen;
left: 0;
width: 250px;
}
.sidebar.secondary {
background: #111;
border-right: solid 1px darkgreen;
left: 251px;
width: 200px;
}
#content.namespace-index, #content.document {
left: 251px;
}
#content.namespace-docs {
left: 452px;
}
#content.document {
padding-bottom: 10%;
}
#header {
background: #080808;
box-shadow: 0 0 8px rgba(192, 255, 192, 0.4);
z-index: 100;
}
#header h1 {
margin: 0;
padding: 0;
font-size: 18px;
font-weight: lighter;
text-shadow: -1px -1px 0px #333;
}
#header h1 .project-version {
font-weight: normal;
}
.project-version {
padding-left: 0.15em;
}
#header a, .sidebar a {
display: block;
text-decoration: none;
}
#header h2 {
float: right;
font-size: 9pt;
font-weight: normal;
margin: 4px 3px;
padding: 0;
color: #5f5;
}
#header h2 a {
display: inline;
}
.sidebar h3 {
margin: 0;
padding: 10px 13px 0 13px;
font-size: 19px;
font-weight: lighter;
}
.sidebar h3 a {
color: #4f4;
}
.sidebar h3.no-link {
color: green;
}
.sidebar ul {
padding: 7px 0 6px 0;
margin: 0;
}
.sidebar ul.index-link {
padding-bottom: 4px;
}
.sidebar li {
display: block;
vertical-align: middle;
}
.sidebar li a, .sidebar li .no-link {
border-left: 3px solid transparent;
padding: 0 10px;
white-space: nowrap;
}
.sidebar li .no-link {
display: block;
color: #7F7;
font-style: italic;
}
.sidebar li .inner {
display: inline-block;
padding-top: 7px;
height: 24px;
}
.sidebar li a, .sidebar li .tree {
height: 31px;
}
.depth-1 .inner { padding-left: 2px; }
.depth-2 .inner { padding-left: 6px; }
.depth-3 .inner { padding-left: 20px; }
.depth-4 .inner { padding-left: 34px; }
.depth-5 .inner { padding-left: 48px; }
.depth-6 .inner { padding-left: 62px; }
.sidebar li .tree {
display: block;
float: left;
position: relative;
top: -10px;
margin: 0 4px 0 0;
padding: 0;
}
.sidebar li.depth-1 .tree {
display: none;
}
.sidebar li .tree .top, .sidebar li .tree .bottom {
display: block;
margin: 0;
padding: 0;
width: 7px;
}
.sidebar li .tree .top {
border-left: 1px solid yellowgreen;
border-bottom: 1px solid yellowgreen;
height: 19px;
}
.sidebar li .tree .bottom {
height: 22px;
}
.sidebar li.branch .tree .bottom {
border-left: 1px solid yellowgreen;
}
.sidebar.primary li.current a {
border-left: 3px solid goldenrod;
color: goldenrod;
}
.sidebar.secondary li.current a {
border-left: 3px solid yellow;
color: yellow;
}
.namespace-index h2 {
margin: 30px 0 0 0;
}
.namespace-index h3 {
font-size: 16px;
font-weight: bold;
margin-bottom: 0;
}
.namespace-index .topics {
padding-left: 30px;
margin: 11px 0 0 0;
}
.namespace-index .topics li {
padding: 5px 0;
}
.namespace-docs h3 {
font-size: 18px;
font-weight: bold;
}
.public h3 {
margin: 0;
float: left;
}
.usage {
clear: both;
}
.public {
margin: 0;
border-top: 1px solid lime;
padding-top: 14px;
padding-bottom: 6px;
}
.public:last-child {
margin-bottom: 20%;
}
.members .public:last-child {
margin-bottom: 0;
}
.members {
margin: 15px 0;
}
.members h4 {
color: lime;
font-weight: normal;
font-variant: small-caps;
margin: 0 0 5px 0;
}
.members .inner {
padding-top: 5px;
padding-left: 12px;
margin-top: 2px;
margin-left: 7px;
border-left: 1px solid #5f5;
}
#content .members .inner h3 {
font-size: 12pt;
}
.members .public {
border-top: none;
margin-top: 0;
padding-top: 6px;
padding-bottom: 0;
}
.members .public:first-child {
padding-top: 0;
}
h4.type,
h4.dynamic,
h4.added,
h4.deprecated {
float: left;
margin: 3px 10px 15px 0;
font-size: 15px;
font-weight: bold;
font-variant: small-caps;
}
.public h4.type,
.public h4.dynamic,
.public h4.added,
.public h4.deprecated {
font-size: 13px;
font-weight: bold;
margin: 3px 0 0 10px;
}
.members h4.type,
.members h4.added,
.members h4.deprecated {
margin-top: 1px;
}
h4.type {
color: #717171;
}
h4.dynamic {
color: #9933aa;
}
h4.added {
color: #7acc32;
}
h4.deprecated {
color: #880000;
}
.namespace {
margin-bottom: 30px;
}
.namespace:last-child {
margin-bottom: 10%;
}
.index {
padding: 0;
font-size: 80%;
margin: 15px 0;
line-height: 16px;
}
.index * {
display: inline;
}
.index p {
padding-right: 3px;
}
.index li {
padding-right: 5px;
}
.index ul {
padding-left: 0;
}
.type-sig {
clear: both;
color: goldenrod;
}
.type-sig pre {
padding-top: 10px;
margin: 0;
}
.usage code {
display: block;
margin: 2px 0;
color: limegreen;
}
.usage code:first-child {
padding-top: 10px;
}
p {
margin: 15px 0;
}
.public p:first-child, .public pre.plaintext {
margin-top: 12px;
}
.doc {
margin: 0 0 26px 0;
clear: both;
}
.public .doc {
margin: 0;
}
.namespace-index .doc {
margin-bottom: 20px;
}
.namespace-index .namespace .doc {
margin-bottom: 10px;
}
.markdown p, .markdown li, .markdown dt, .markdown dd, .markdown td {
line-height: 22px;
}
.markdown li {
padding: 2px 0;
}
.markdown h2 {
font-weight: normal;
font-size: 25px;
margin: 30px 0 10px 0;
}
.markdown h3 {
font-weight: normal;
font-size: 20px;
margin: 30px 0 0 0;
}
.markdown h4 {
font-size: 15px;
margin: 22px 0 -4px 0;
}
.doc, .public, .namespace .index {
max-width: 680px;
overflow-x: visible;
}
.markdown pre > code {
display: block;
padding: 10px;
}
.markdown pre > code, .src-link a {
border: 1px solid lime;
border-radius: 2px;
}
.markdown code:not(.hljs), .src-link a {
background: #111;
}
pre.deps {
display: inline-block;
margin: 0 10px;
border: 1px solid lime;
border-radius: 2px;
padding: 10px;
background-color: #111;
}
.markdown hr {
border-style: solid;
border-top: none;
color: goldenrod;
}
.doc ul, .doc ol {
padding-left: 30px;
}
.doc table {
border-collapse: collapse;
margin: 0 10px;
}
.doc table td, .doc table th {
border: 1px solid goldenrod;
padding: 4px 6px;
}
.doc table th {
background: #111;
}
.doc dl {
margin: 0 10px 20px 10px;
}
.doc dl dt {
font-weight: bold;
margin: 0;
padding: 3px 0;
border-bottom: 1px solid goldenrod;
}
.doc dl dd {
padding: 5px 0;
margin: 0 0 5px 10px;
}
.doc abbr {
border-bottom: 1px dotted goldenrod;
font-variant: none;
cursor: help;
}
.src-link {
margin-bottom: 15px;
}
.src-link a {
font-size: 70%;
padding: 1px 4px;
text-decoration: none;
color: lime5bb;
}

View file

@ -0,0 +1,97 @@
/*
github.com style (c) Vasily Polovnyov <vast@whiteants.net>
*/
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
color: #333;
background: #f8f8f8;
}
.hljs-comment,
.hljs-quote {
color: #998;
font-style: italic;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-subst {
color: #333;
font-weight: bold;
}
.hljs-number,
.hljs-literal,
.hljs-variable,
.hljs-template-variable,
.hljs-tag .hljs-attr {
color: #008080;
}
.hljs-string,
.hljs-doctag {
color: #d14;
}
.hljs-title,
.hljs-section,
.hljs-selector-id {
color: #900;
font-weight: bold;
}
.hljs-subst {
font-weight: normal;
}
.hljs-type,
.hljs-class .hljs-title {
color: #458;
font-weight: bold;
}
.hljs-tag,
.hljs-name,
.hljs-attribute {
color: #000080;
font-weight: normal;
}
.hljs-regexp,
.hljs-link {
color: #009926;
}
.hljs-symbol,
.hljs-bullet {
color: #990073;
}
.hljs-built_in,
.hljs-builtin-name {
color: #0086b3;
}
.hljs-meta {
color: #999;
font-weight: bold;
}
.hljs-deletion {
background: #fdd;
}
.hljs-addition {
background: #dfd;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}

View file

@ -0,0 +1 @@
{:resources ["css/default.css" "css/highlight.css"]}

View file

@ -12,7 +12,7 @@
32767 32767
EXPR EXPR
(LAMBDA (LAMBDA
(X Y) (COND ((NULL X) Y) ((QUOTE T) (CONS (CAR X) (APPEND (CDR X) Y)))))) (X Y) (COND ((NULL X) Y) (T (CONS (CAR X) (APPEND (CDR X) Y))))))
(APPLY 32767 SUBR (BEOWULF BOOTSTRAP APPLY)) (APPLY 32767 SUBR (BEOWULF BOOTSTRAP APPLY))
(ASSOC (ASSOC
32767 32767
@ -20,9 +20,9 @@
(LAMBDA (LAMBDA
(X L) (X L)
(COND (COND
((NULL L) (QUOTE NIL)) ((NULL L) NIL)
((AND (CONSP (CAR L)) (EQ (CAAR L) X)) (CAR L)) ((AND (CONSP (CAR L)) (EQ (CAAR L) X)) (CAR L))
((QUOTE T) (ASSOC X (CDR L))))) (T (ASSOC X (CDR L)))))
SUBR (BEOWULF HOST ASSOC)) SUBR (BEOWULF HOST ASSOC))
(ATOM 32767 SUBR (BEOWULF HOST ATOM)) (ATOM 32767 SUBR (BEOWULF HOST ATOM))
(CAR 32767 SUBR (BEOWULF HOST CAR)) (CAR 32767 SUBR (BEOWULF HOST CAR))
@ -63,14 +63,14 @@
(LAMBDA (LAMBDA
(X) (X)
(COND (COND
((NULL X) (QUOTE NIL)) ((NULL X) NIL)
((ATOM X) X) ((QUOTE T) (CONS (COPY (CAR X)) (COPY (CDR X))))))) ((ATOM X) X) (T (CONS (COPY (CAR X)) (COPY (CDR X)))))))
(DEFINE 32767 SUBR (BEOWULF HOST DEFINE)) (DEFINE 32767 SUBR (BEOWULF HOST DEFINE))
(DIFFERENCE 32767 SUBR (BEOWULF HOST DIFFERENCE)) (DIFFERENCE 32767 SUBR (BEOWULF HOST DIFFERENCE))
(DIVIDE (DIVIDE
32767 32767
EXPR EXPR
(LAMBDA (X Y) (CONS (QUOTIENT X Y) (CONS (REMAINDER X Y) (QUOTE NIL))))) (LAMBDA (X Y) (CONS (QUOTIENT X Y) (CONS (REMAINDER X Y) NIL))))
(DOC 32767 SUBR (BEOWULF HOST DOC)) (DOC 32767 SUBR (BEOWULF HOST DOC))
(EFFACE (EFFACE
32767 32767
@ -78,8 +78,8 @@
(LAMBDA (LAMBDA
(X L) (X L)
(COND (COND
((NULL L) (QUOTE NIL)) ((NULL L) NIL)
((EQUAL X (CAR L)) (CDR L)) ((QUOTE T) (RPLACD L (EFFACE X (CDR L))))))) ((EQUAL X (CAR L)) (CDR L)) (T (RPLACD L (EFFACE X (CDR L)))))))
(ERROR 32767 SUBR (BEOWULF HOST ERROR)) (ERROR 32767 SUBR (BEOWULF HOST ERROR))
(EQ 32767 SUBR (BEOWULF HOST EQ)) (EQ 32767 SUBR (BEOWULF HOST EQ))
(EQUAL 32767 SUBR (BEOWULF HOST EQUAL)) (EQUAL 32767 SUBR (BEOWULF HOST EQUAL))
@ -91,12 +91,12 @@
(GENSYM 32767 SUBR (BEOWULF HOST GENSYM)) (GENSYM 32767 SUBR (BEOWULF HOST GENSYM))
(GET (GET
32767 32767
EXPR ;; EXPR
(LAMBDA ;; (LAMBDA
(X Y) ;; (X Y)
(COND ;; (COND
((NULL X) (QUOTE NIL)) ;; ((NULL X) NIL)
((EQ (CAR X) Y) (CAR (CDR X))) ((QUOTE T) (GET (CDR X) Y)))) ;; ((EQ (CAR X) Y) (CAR (CDR X))) (T (GET (CDR X) Y))))
SUBR (BEOWULF HOST GET)) SUBR (BEOWULF HOST GET))
(GREATERP 32767 SUBR (BEOWULF HOST GREATERP)) (GREATERP 32767 SUBR (BEOWULF HOST GREATERP))
(INTEROP 32767 SUBR (BEOWULF INTEROP INTEROP)) (INTEROP 32767 SUBR (BEOWULF INTEROP INTEROP))
@ -106,15 +106,15 @@
(LAMBDA (LAMBDA
(X Y) (X Y)
(COND (COND
((NULL X) (QUOTE NIL)) ((NULL X) NIL)
((MEMBER (CAR X) Y) (CONS (CAR X) (INTERSECTION (CDR X) Y))) ((MEMBER (CAR X) Y) (CONS (CAR X) (INTERSECTION (CDR X) Y)))
((QUOTE T) (INTERSECTION (CDR X) Y))))) (T (INTERSECTION (CDR X) Y)))))
(LENGTH (LENGTH
32767 32767
EXPR EXPR
(LAMBDA (LAMBDA
(L) (L)
(COND ((EQ NIL L) 0) ((CONSP (CDR L)) (ADD1 (LENGTH (CDR L)))) (T 0)))) (COND ((EQ NIL L) 0) ((CONSP (CDR L)) (ADD1 (LENGTH (CDR L)))) (T 1))))
(LESSP 32767 SUBR (BEOWULF HOST LESSP)) (LESSP 32767 SUBR (BEOWULF HOST LESSP))
(MAPLIST (MAPLIST
32767 32767
@ -122,7 +122,7 @@
(LAMBDA (LAMBDA
(L F) (L F)
(COND (COND
((NULL L) NIL) ((QUOTE T) (CONS (F (CAR L)) (MAPLIST (CDR L) F)))))) ((NULL L) NIL) (T (CONS (F (CAR L)) (MAPLIST (CDR L) F))))))
(MEMBER (MEMBER
32767 32767
EXPR EXPR
@ -130,14 +130,15 @@
(A X) (A X)
(COND (COND
((NULL X) (QUOTE F)) ((NULL X) (QUOTE F))
((EQ A (CAR X)) (QUOTE T)) ((QUOTE T) (MEMBER A (CDR X)))))) ((EQ A (CAR X)) T) (T (MEMBER A (CDR X))))))
(MINUSP 32767 EXPR (LAMBDA (X) (LESSP X 0))) (MINUSP 32767 EXPR (LAMBDA (X) (LESSP X 0)))
(NOT 32767 EXPR (LAMBDA (X) (COND (X (QUOTE NIL)) ((QUOTE T) (QUOTE T))))) (NOT 32767 EXPR (LAMBDA (X) (COND (X NIL) (T T))))
(NULL (NULL
32767 EXPR (LAMBDA (X) (COND ((EQUAL X NIL) (QUOTE T)) (T (QUOTE F))))) 32767 EXPR (LAMBDA (X) (COND ((EQUAL X NIL) T) (T (QUOTE F)))))
(NUMBERP 32767 SUBR (BEOWULF HOST NUMBERP)) (NUMBERP 32767 SUBR (BEOWULF HOST NUMBERP))
(OBLIST 32767 SUBR (BEOWULF HOST OBLIST)) (OBLIST 32767 SUBR (BEOWULF HOST OBLIST))
(ONEP 32767 EXPR (LAMBDA (X) (EQ X 1))) (ONEP 32767 EXPR (LAMBDA (X) (EQ X 1)))
(OR 32767 SUBR (BEOWULF HOST OR))
(PAIR (PAIR
32767 32767
EXPR EXPR
@ -155,11 +156,12 @@
(X Y A) (X Y A)
(COND (COND
((NULL X) A) ((NULL X) A)
((QUOTE T) (CONS (CONS (CAR X) (CAR Y)) (PAIRLIS (CDR X) (CDR Y) A))))) (T (CONS (CONS (CAR X) (CAR Y)) (PAIRLIS (CDR X) (CDR Y) A)))))
SUBR (BEOWULF HOST PAIRLIS)) SUBR (BEOWULF HOST PAIRLIS))
(PLUS 32767 SUBR (BEOWULF HOST PLUS)) (PLUS 32767 SUBR (BEOWULF HOST PLUS))
(PRETTY 32767) (PRETTY 32767)
(PRINT 32767) (PRINT 32767)
(PROG 32767 FSUBR (BEOWULF HOST PROG))
(PROP (PROP
32767 32767
EXPR EXPR
@ -167,7 +169,7 @@
(X Y U) (X Y U)
(COND (COND
((NULL X) (U)) ((NULL X) (U))
((EQ (CAR X) Y) (CDR X)) ((QUOTE T) (PROP (CDR X) Y U))))) ((EQ (CAR X) Y) (CDR X)) (T (PROP (CDR X) Y U)))))
(QUOTE 32767 EXPR (LAMBDA (X) X)) (QUOTE 32767 EXPR (LAMBDA (X) X))
(QUOTIENT 32767 SUBR (BEOWULF HOST QUOTIENT)) (QUOTIENT 32767 SUBR (BEOWULF HOST QUOTIENT))
(RANGE (RANGE
@ -176,7 +178,7 @@
(LAMBDA (LAMBDA
(N M) (N M)
(COND (COND
((LESSP M N) (QUOTE NIL)) ((QUOTE T) (CONS N (RANGE (ADD1 N) M)))))) ((LESSP M N) NIL) (T (CONS N (RANGE (ADD1 N) M))))))
(READ 32767 SUBR (BEOWULF READ READ)) (READ 32767 SUBR (BEOWULF READ READ))
(REMAINDER 32767 SUBR (BEOWULF HOST REMAINDER)) (REMAINDER 32767 SUBR (BEOWULF HOST REMAINDER))
(REPEAT (REPEAT
@ -185,6 +187,11 @@
(LAMBDA (N X) (COND ((EQ N 0) NIL) (T (CONS X (REPEAT (SUB1 N) X)))))) (LAMBDA (N X) (COND ((EQ N 0) NIL) (T (CONS X (REPEAT (SUB1 N) X))))))
(RPLACA 32767 SUBR (BEOWULF HOST RPLACA)) (RPLACA 32767 SUBR (BEOWULF HOST RPLACA))
(RPLACD 32767 SUBR (BEOWULF HOST RPLACD)) (RPLACD 32767 SUBR (BEOWULF HOST RPLACD))
(SEARCH 32767 EXPR
(LAMBDA (X P F U)
(COND ((NULL X) (U X))
((P X) (F X))
((QUOTE T) (SEARCH (CDR X) P F U)))))
(SET 32767 SUBR (BEOWULF HOST SET)) (SET 32767 SUBR (BEOWULF HOST SET))
(SUB1 32767 EXPR (LAMBDA (N) (DIFFERENCE N 1)) SUBR (BEOWULF HOST SUB1)) (SUB1 32767 EXPR (LAMBDA (N) (DIFFERENCE N 1)) SUBR (BEOWULF HOST SUB1))
(SUB2 (SUB2
@ -193,9 +200,19 @@
(LAMBDA (LAMBDA
(A Z) (A Z)
(COND (COND
((NULL A) Z) ((EQ (CAAR A) Z) (CDAR A)) ((QUOTE T) (SUB2 (CDAR A) Z))))) ((NULL A) Z) ((EQ (CAAR A) Z) (CDAR A)) (T (SUB2 (CDAR A) Z)))))
(SUBLIS (SUBLIS
32767 EXPR (LAMBDA (A Y) (COND ((ATOM Y) (SUB2 A Y)) ((QUOTE T) (CONS))))) 32767 EXPR
(LAMBDA (X Y)
(COND ((NULL X) Y)
((NULL Y) Y)
((QUOTE T) (SEARCH X
(LAMBDA (J) (EQUAL Y (CAAR J)))
(LAMBDA (J) (CDAR J))
(LAMBDA (J) (COND ((ATOM Y) Y)
((QUOTE T) (CONS
(SUBLIS X (CAR Y))
(SUBLIS X (CDR Y)))))))))))
(SUBST (SUBST
32767 32767
EXPR EXPR
@ -204,7 +221,7 @@
(COND (COND
((EQUAL Y Z) X) ((EQUAL Y Z) X)
((ATOM Z) Z) ((ATOM Z) Z)
((QUOTE T) (CONS (SUBST X Y (CAR Z)) (SUBST X Y (CDR Z))))))) (T (CONS (SUBST X Y (CAR Z)) (SUBST X Y (CDR Z)))))))
(SYSIN 32767 SUBR (BEOWULF IO SYSIN)) (SYSIN 32767 SUBR (BEOWULF IO SYSIN))
(SYSOUT 32767 SUBR (BEOWULF IO SYSOUT)) (SYSOUT 32767 SUBR (BEOWULF IO SYSOUT))
(TERPRI 32767) (TERPRI 32767)

View file

@ -0,0 +1 @@
not[x] = [x = F -> T; x = NIL -> T; T -> F]

View file

@ -0,0 +1,5 @@
# page 63
search[x; p; f; u] = [null[x] -> u[x];
p[x] -> f[x];
T -> search[cdr[x]; p; f; u]]

View file

@ -7,4 +7,19 @@ sub2[a; z] = [null[a] -> z;
T -> sub2[cdar[a]; z]] T -> sub2[cdar[a]; z]]
sublis[a; y] = [atom[y] -> sub2[a; y]; sublis[a; y] = [atom[y] -> sub2[a; y];
T -> cons[]] T -> cons[sublis[a; car[y]];
sublis[a; cdr[y]]]]
;; this is the version from page 61
sublis[x;y] = [null[x] -> y;
null[y] -> y;
T -> search[x;
λ[[j]; equal[y; caar[j]]];
λ[[j]; cdar[j]];
λ[[j]; [atom[y] -> y;
T -> cons[sublis[x; car[y]];
sublis[x; cdr[y]]]]]]]
;; the test for this is:
;; (SUBLIS '((X . SHAKESPEARE) (Y . (THE TEMPEST))) '(X WROTE Y))

View file

@ -9,7 +9,8 @@
ALLUPPERCASE are Lisp 1.5 functions (although written in Clojure) and that ALLUPPERCASE are Lisp 1.5 functions (although written in Clojure) and that
therefore all arguments must be numbers, symbols or `beowulf.cons_cell.ConsCell` therefore all arguments must be numbers, symbols or `beowulf.cons_cell.ConsCell`
objects." objects."
(:require [beowulf.cons-cell :refer [make-beowulf-list make-cons-cell T]] (:require [beowulf.cons-cell :refer [F make-beowulf-list make-cons-cell
pretty-print T]]
[beowulf.host :refer [ASSOC ATOM CAAR CADAR CADDR CADR CAR CDR GET [beowulf.host :refer [ASSOC ATOM CAAR CADAR CADDR CADR CAR CDR GET
LIST NUMBERP PAIRLIS traced?]] LIST NUMBERP PAIRLIS traced?]]
[beowulf.oblist :refer [*options* NIL oblist]]) [beowulf.oblist :refer [*options* NIL oblist]])
@ -36,20 +37,169 @@
;;; ;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(declare APPLY EVAL) (declare APPLY EVAL prog-eval)
(defn try-resolve-subroutine ;;;; The PROGram feature ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
"Attempt to resolve this `subr` with these `arg`."
[subr args] (def find-target
(when (and subr (not= subr NIL)) (memoize
(try @(resolve subr) (fn [target body]
(catch Throwable any (loop [body' body]
(throw (ex-info "Failed to resolve subroutine" (cond
{:phase :apply (= body' NIL) (throw (ex-info (str "Mislar GO miercels: `" target "`")
:function subr {:phase :lisp
:args args :function 'PROG
:type :beowulf} :type :lisp
any)))))) :code :A6
:target target}))
(= (.getCar body') target) body'
:else (recur (.getCdr body')))))))
(defn- prog-cond
"Like `EVCON`, q.v. except using `prog-eval` instead of `EVAL` and not
throwing an error if no clause matches."
[clauses vars env depth]
(loop [clauses' clauses]
(if-not (= clauses' NIL)
(let [test (prog-eval (CAAR clauses') vars env depth)]
(if (not (#{NIL F} test))
(prog-eval (CADAR clauses') vars env depth)
(recur (.getCdr clauses'))))
NIL)))
(defn- merge-vars [vars env]
(reduce
#(make-cons-cell
(make-cons-cell %2 (@vars %2))
env)
env
(keys @vars)))
(defn prog-eval
"Like `EVAL`, q.v., except handling symbols, and expressions starting
`GO`, `RETURN`, `SET` and `SETQ` specially."
[expr vars env depth]
(cond
(number? expr) expr
(symbol? expr) (@vars expr)
(instance? ConsCell expr) (case (.getCar expr)
COND (prog-cond (.getCdr expr)
vars env depth)
GO (make-cons-cell
'*PROGGO* (.getCar (.getCdr expr)))
RETURN (make-cons-cell
'*PROGRETURN*
(prog-eval (.getCar (.getCdr expr))
vars env depth))
SET (let [v (CADDR expr)]
(swap! vars
assoc
(prog-eval (CADR expr)
vars env depth)
(prog-eval (CADDR expr)
vars env depth))
v)
SETQ (let [v (CADDR expr)]
(swap! vars
assoc
(CADR expr)
(prog-eval v
vars env depth))
v)
;; else
(beowulf.bootstrap/EVAL expr
(merge-vars vars env)
depth))))
(defn PROG
"The accursed `PROG` feature. See page 71 of the manual.
Lisp 1.5 introduced `PROG`, and most Lisps have been stuck with it ever
since. It introduces imperative programming into what should be a pure
functional language, and consequently it's going to be a pig to implement.
Broadly, `PROG` is a variadic pseudo function called as a `FEXPR` (or
possibly an `FSUBR`, although I'm not presently sure that would even work.)
The arguments, which are unevaluated, are a list of forms, the first of
which is expected to be a list of symbols which will be treated as names
of variables within the program, and the rest of which (the 'program body')
are either lists or symbols. Lists are treated as Lisp expressions which
may be evaulated in turn. Symbols are treated as targets for the `GO`
statement.
**GO:**
A `GO` statement takes the form of `(GO target)`, where
`target` should be one of the symbols which occur at top level among that
particular invocation of `PROG`s arguments. A `GO` statement may occur at
top level in a PROG, or in a clause of a `COND` statement in a `PROG`, but
not in a function called from the `PROG` statement. When a `GO` statement
is evaluated, execution should transfer immediately to the expression which
is the argument list immediately following the symbol which is its target.
If the target is not found, an error with the code `A6` should be thrown.
**RETURN:**
A `RETURN` statement takes the form `(RETURN value)`, where
`value` is any value. Following the evaluation of a `RETURN` statement,
the `PROG` should immediately exit without executing any further
expressions, returning the value.
**SET and SETQ:**
In addition to the above, if a `SET` or `SETQ` expression is encountered
in any expression within the `PROG` body, it should affect not the global
object list but instead only the local variables of the program.
**COND:**
In **strict** mode, when in normal execution, a `COND` statement none of
whose clauses match should not return `NIL` but should throw an error with
the code `A3`... *except* that inside a `PROG` body, it should not do so.
*sigh*.
**Flow of control:**
Apart from the exceptions specified above, expressions in the program body
are evaluated sequentially. If execution reaches the end of the program
body, `NIL` is returned.
Got all that?
Good."
[program env depth]
(let [trace (traced? 'PROG)
vars (atom (reduce merge (map #(assoc {} % NIL) (.getCar program))))
body (.getCdr program)
targets (set (filter symbol? body))]
(when trace (do
(println "Program:")
(pretty-print program))) ;; for debugging
(loop [cursor body]
(let [step (.getCar cursor)]
(when trace (do (println "Executing step: " step)
(println " with vars: " @vars)))
(cond (= cursor NIL) NIL
(symbol? step) (recur (.getCdr cursor))
:else (let [v (prog-eval (.getCar cursor) vars env depth)]
(when trace (println " --> " v))
(if (instance? ConsCell v)
(case (.getCar v)
*PROGGO* (let [target (.getCdr v)]
(if (targets target)
(recur (find-target target body))
(throw (ex-info (str "Uncynlic GO miercels `"
target "`")
{:phase :lisp
:function 'PROG
:args program
:type :lisp
:code :A6
:target target
:targets targets}))))
*PROGRETURN* (.getCdr v)
;; else
(recur (.getCdr cursor)))
(recur (.getCdr cursor)))))))))
;;;; Tracing execution ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defn- trace-call (defn- trace-call
"Show a trace of a call to the function named by this `function-symbol` "Show a trace of a call to the function named by this `function-symbol`
@ -78,21 +228,46 @@
(first (remove #(= % NIL) (map #(GET s %) (first (remove #(= % NIL) (map #(GET s %)
indicators)))))) indicators))))))
;;;; APPLY ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defn try-resolve-subroutine
"Attempt to resolve this `subr` with these `args`."
[subr args]
(when (and subr (not= subr NIL))
(try @(resolve subr)
(catch Throwable any
(throw (ex-info "þegnung (SUBR) ne āfand"
{:phase :apply
:function subr
:args args
:type :beowulf}
any))))))
(defn- apply-symbolic (defn- apply-symbolic
"Apply this `funtion-symbol` to these `args` in this `environment` and "Apply this `funtion-symbol` to these `args` in this `environment` and
return the result." return the result."
[^Symbol function-symbol args ^ConsCell environment depth] [^Symbol function-symbol args ^ConsCell environment depth]
(trace-call function-symbol args depth) (trace-call function-symbol args depth)
(let [lisp-fn ;; (try (let [lisp-fn (value function-symbol '(EXPR FEXPR))
(value function-symbol '(EXPR FEXPR)) args' (cond (= NIL args) args
;; (catch Exception any (when (traced? function-symbol) (empty? args) NIL
;; (println any)))) (instance? ConsCell args) args
:else (make-beowulf-list args))
subr (value function-symbol '(SUBR FSUBR)) subr (value function-symbol '(SUBR FSUBR))
host-fn (try-resolve-subroutine subr args) host-fn (try-resolve-subroutine subr args')
result (cond (and lisp-fn result (cond (and lisp-fn
(not= lisp-fn NIL)) (APPLY lisp-fn args environment depth) (not= lisp-fn NIL)) (APPLY lisp-fn args' environment depth)
host-fn (apply host-fn (when (instance? ConsCell args) args)) host-fn (try
:else (ex-info "No function found" (apply host-fn (when (instance? ConsCell args') args'))
(catch Exception any
(throw (ex-info (str "Uncynlic þegnung: "
(.getMessage any))
{:phase :apply
:function function-symbol
:args args
:type :beowulf}
any))))
:else (ex-info "þegnung ne āfand"
{:phase :apply {:phase :apply
:function function-symbol :function function-symbol
:args args :args args
@ -112,7 +287,7 @@
(let [result (cond (let [result (cond
(= NIL function) (if (:strict *options*) (= NIL function) (if (:strict *options*)
NIL NIL
(throw (ex-info "NIL is not a function" (throw (ex-info "NIL sí ne þegnung"
{:phase :apply {:phase :apply
:function "NIL" :function "NIL"
:args args :args args
@ -132,7 +307,7 @@
LAMBDA (EVAL LAMBDA (EVAL
(CADDR function) (CADDR function)
(PAIRLIS (CADR function) args environment) depth) (PAIRLIS (CADR function) args environment) depth)
(throw (ex-info "Unrecognised value in function position" (throw (ex-info "Ungecnáwen wyrþan sí þegnung-weard"
{:phase :apply {:phase :apply
:function function :function function
:args args :args args
@ -140,18 +315,31 @@
(trace-response 'APPLY result depth) (trace-response 'APPLY result depth)
result)) result))
;;;; EVAL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defn- EVCON (defn- EVCON
"Inner guts of primitive COND. All `clauses` are assumed to be "Inner guts of primitive COND. All `clauses` are assumed to be
`beowulf.cons-cell/ConsCell` objects. Note that tests in Lisp 1.5 `beowulf.cons-cell/ConsCell` objects. Note that tests in Lisp 1.5
often return `F`, not `NIL`, on failure. often return `F`, not `NIL`, on failure. If no clause matches,
then, strictly, we throw an error with code `:A3`.
See page 13 of the Lisp 1.5 Programmers Manual." See pages 13 and 71 of the Lisp 1.5 Programmers Manual."
[clauses env depth] [clauses env depth]
(let [test (EVAL (CAAR clauses) env depth)] (loop [clauses' clauses]
(if (if-not (= clauses' NIL)
(and (not= test NIL) (not= test 'F)) (let [test (EVAL (CAAR clauses') env depth)]
(EVAL (CADAR clauses) env depth) (if (not (#{NIL F} test))
(EVCON (CDR clauses) env depth)))) ;; (and (not= test NIL) (not= test F))
(EVAL (CADAR clauses') env depth)
(recur (.getCdr clauses'))))
(if (:strict *options*)
(throw (ex-info "Ne ġefōg dǣl in COND"
{:phase :eval
:function 'COND
:args (list clauses)
:type :lisp
:code :A3}))
NIL))))
(defn- EVLIS (defn- EVLIS
"Map `EVAL` across this list of `args` in the context of this "Map `EVAL` across this list of `args` in the context of this
@ -167,18 +355,18 @@
(defn- eval-symbolic (defn- eval-symbolic
[expr env depth] [expr env depth]
(let [v (value expr (list 'APVAL)) (let [v (ASSOC expr env)
indent (apply str (repeat depth "-"))] indent (apply str (repeat depth "-"))]
(when (traced? 'EVAL) (when (traced? 'EVAL)
(println (str indent ": EVAL: deep binding (" expr " . " (or v "nil") ")"))) (println (str indent ": EVAL: sceald bindele: " (or v "nil"))))
(if (and v (not= v NIL)) (if (instance? ConsCell v)
v (.getCdr v)
(let [v' (ASSOC expr env)] (let [v' (value expr (list 'APVAL))]
(when (traced? 'EVAL) (when (traced? 'EVAL)
(println (str indent ": EVAL: shallow binding: " (or v' "nil")))) (println (str indent ": EVAL: deóp bindele: (" expr " . " (or v' "nil") ")")))
(if (and v' (not= v' NIL)) (if v'
(.getCdr v') v'
(throw (ex-info "No binding for symbol found" (throw (ex-info "Ne tácen-bindele āfand"
{:phase :eval {:phase :eval
:function 'EVAL :function 'EVAL
:args (list expr env depth) :args (list expr env depth)
@ -197,10 +385,12 @@
(let [expr' (if (and (coll? expr) (not (instance? ConsCell expr))) (let [expr' (if (and (coll? expr) (not (instance? ConsCell expr)))
(make-beowulf-list expr) (make-beowulf-list expr)
expr)] expr)]
(EVAL expr' @oblist 0))) (EVAL expr' NIL 0)))
([expr env depth] ([expr env depth]
(trace-call 'EVAL (list expr env depth) depth) (trace-call 'EVAL (list expr env depth) depth)
(let [result (cond (let [result (cond
(= NIL expr) NIL ;; it was probably a mistake to make Lisp
;; NIL distinct from Clojure nil
(= (NUMBERP expr) T) expr (= (NUMBERP expr) T) expr
(symbol? expr) (eval-symbolic expr env depth) (symbol? expr) (eval-symbolic expr env depth)
(string? expr) (if (:strict *options*) (string? expr) (if (:strict *options*)
@ -212,9 +402,10 @@
:expr expr})) :expr expr}))
(symbol expr)) (symbol expr))
(= (ATOM (CAR expr)) T) (case (CAR expr) (= (ATOM (CAR expr)) T) (case (CAR expr)
QUOTE (CADR expr)
FUNCTION (LIST 'FUNARG (CADR expr))
COND (EVCON (CDR expr) env depth) COND (EVCON (CDR expr) env depth)
FUNCTION (LIST 'FUNARG (CADR expr))
PROG (PROG (CDR expr) env depth)
QUOTE (CADR expr)
;; else ;; else
(APPLY (APPLY
(CAR expr) (CAR expr)

View file

@ -77,7 +77,7 @@
(set! (. this CAR) value) (set! (. this CAR) value)
this) this)
(throw (ex-info (throw (ex-info
(str "Invalid value in RPLACA: `" value "` (" (type value) ")") (str "Uncynlic miercels in RPLACA: `" value "` (" (type value) ")")
{:cause :bad-value {:cause :bad-value
:detail :rplaca})))) :detail :rplaca}))))
@ -92,7 +92,7 @@
(set! (. this CDR) value) (set! (. this CDR) value)
this) this)
(throw (ex-info (throw (ex-info
(str "Invalid value in RPLACD: `" value "` (" (type value) ")") (str "Uncynlic miercels in RPLACD: `" value "` (" (type value) ")")
{:cause :bad-value {:cause :bad-value
:detail :rplaca})))) :detail :rplaca}))))
@ -248,7 +248,7 @@
(try (try
(ConsCell. car cdr (gensym "c")) (ConsCell. car cdr (gensym "c"))
(catch Exception any (catch Exception any
(throw (ex-info "Cound not construct cons cell" {:car car (throw (ex-info "Ne meahte cræfte cons cell" {:car car
:cdr cdr} any))))) :cdr cdr} any)))))
(defn make-beowulf-list (defn make-beowulf-list
@ -269,6 +269,6 @@
:else :else
NIL) NIL)
(catch Exception any (catch Exception any
(throw (ex-info "Could not construct Beowulf list" (throw (ex-info "Ne meahte cræfte Beowulf líste"
{:content x} {:content x}
any))))) any)))))

View file

@ -30,7 +30,10 @@
;;; ;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(def stop-word "STOP") (def stop-word
"The word which, if submitted an an input line, will cause Beowulf to quit.
Question: should this be `forlǣte`?"
"STOP")
(def cli-options (def cli-options
[["-f FILEPATH" "--file-path FILEPATH" [["-f FILEPATH" "--file-path FILEPATH"
@ -43,12 +46,12 @@
["-h" "--help"] ["-h" "--help"]
["-p PROMPT" "--prompt PROMPT" "Set the REPL prompt to PROMPT" ["-p PROMPT" "--prompt PROMPT" "Set the REPL prompt to PROMPT"
:default "Sprecan::"] :default "Sprecan::"]
["-r INITFILE" "--read INITFILE" "Read Lisp system from file INITFILE" ["-r SYSOUTFILE" "--read SYSOUTFILE" "Read Lisp system from file SYSOUTFILE"
:default default-sysout :default default-sysout
:validate [#(and :validate [#(and
(.exists (io/file %)) (.exists (io/file %))
(.canRead (io/file %))) (.canRead (io/file %)))
"Could not find initfile"]] "Could not find sysout file"]]
["-s" "--strict" "Strictly interpret the Lisp 1.5 language, without extensions."] ["-s" "--strict" "Strictly interpret the Lisp 1.5 language, without extensions."]
["-t" "--time" "Time evaluations."]]) ["-t" "--time" "Time evaluations."]])
@ -124,6 +127,6 @@
:quit nil :quit nil
;; default ;; default
(do (do
(println "ERROR: " (.getMessage e)) (println "STÆFLEAHTER: " (.getMessage e))
(pprint data))) (pprint data)))
(println e)))))))) (println e))))))))

View file

@ -60,7 +60,6 @@
(when (keyword? key) (when (keyword? key)
(key (get-metadata-for-function function))))) (key (get-metadata-for-function function)))))
(defn- get-metadata-for-entry [entry key] (defn- get-metadata-for-entry [entry key]
(let [fn ((host-functions) (symbol (first entry)))] (let [fn ((host-functions) (symbol (first entry)))]
(get-metadata-for-function fn key))) (get-metadata-for-function fn key)))
@ -69,13 +68,25 @@
"Try to work out what this `entry` from the oblist actually "Try to work out what this `entry` from the oblist actually
represents." represents."
[entry] [entry]
(cond (let [interpretation {'APVAL "Lisp variable"
(= (second entry) 'LAMBDA) "Lisp function" 'EXPR "Lisp lambda function"
(= (second entry) 'LABEL) "Labeled form" 'FEXPR "Lisp nlambda function"
((host-functions) (first entry)) (if (fn? (eval (symbol ((host-functions) (first entry))))) 'SUBR "Host lambda function"
"Host function" 'FSUBR "Host nlambda function"}]
"Host variable") (s/join ", "
:else "Lisp variable")) (remove nil?
(map
#(when (some #{%} entry) (interpretation %))
(keys interpretation))))))
;; (cond
;; (= (nth entry 2) 'EXPR) "Lisp function"
;; (= (nth entry 2) 'FEXPR) "Labeled form"
;; ((host-functions) (first entry)) (try (if (fn? (eval (symbol ((host-functions) (first entry)))))
;; "Host function"
;; "Host variable")
;; (catch Exception _
;; "?Host macro?"))
;; :else "Lisp variable"))
(defn- format-clj-signature (defn- format-clj-signature
"Format the signature of the Clojure function represented by `symbol` for "Format the signature of the Clojure function represented by `symbol` for
@ -102,17 +113,18 @@
(defn infer-implementation (defn infer-implementation
[entry] [entry]
(case (second entry) (or (:implementation (index (keyword (first entry)))) "?"))
LAMBDA (format "%s-fn" (second entry)) ;; (case (second entry)
LABEL (format "%s-fn" (second entry)) ;; LAMBDA (format "%s-fn" (second entry))
(or (:implementation (index (keyword (first entry)))) (str 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]
(let [k (keyword (first entry))] (let [k (keyword (first entry))]
(cond (cond
(= (count entry) 1) (if-let [doc (get-metadata-for-entry entry :doc)] (some #{'SUBR 'FSUBR} entry) (if-let [doc (get-metadata-for-entry entry :doc)]
(s/replace doc "\n" " ") (s/replace doc "\n" " ")
"?") "?")
(k index) (str "see manual pages " (format-page-references k)) (k index) (str "see manual pages " (format-page-references k))

View file

@ -2,7 +2,8 @@
"provides Lisp 1.5 functions which can't be (or can't efficiently "provides Lisp 1.5 functions which can't be (or can't efficiently
be) implemented in Lisp 1.5, which therefore need to be implemented in the be) implemented in Lisp 1.5, which therefore need to be implemented in the
host language, in this case Clojure." host language, in this case Clojure."
(:require [beowulf.cons-cell :refer [F make-beowulf-list make-cons-cell T]] ;; note hyphen - this is Clojure... (:require [beowulf.cons-cell :refer [F make-beowulf-list make-cons-cell
pretty-print T]] ;; note hyphen - this is Clojure...
[beowulf.gendoc :refer [open-doc]] [beowulf.gendoc :refer [open-doc]]
[beowulf.oblist :refer [*options* NIL oblist]] [beowulf.oblist :refer [*options* NIL oblist]]
[clojure.set :refer [union]] [clojure.set :refer [union]]
@ -40,7 +41,7 @@
this `symbol`." this `symbol`."
[symbol] [symbol]
(when (:strict *options*) (when (:strict *options*)
(throw (ex-info (format "%s is not available in Lisp 1.5" symbol) (throw (ex-info (format "%s ne āfand innan Lisp 1.5" symbol)
{:type :strict {:type :strict
:phase :host :phase :host
:function symbol}))) :function symbol})))
@ -57,41 +58,30 @@
"Return the item indicated by the first pointer of a pair. NIL is treated "Return the item indicated by the first pointer of a pair. NIL is treated
specially: the CAR of NIL is NIL." specially: the CAR of NIL is NIL."
[x] [x]
(if (cond
(= x NIL) NIL (= x NIL) NIL
(try (instance? ConsCell x) (or (.getCar x) NIL)
(or (.getCar x) NIL) :else (throw (ex-info
(catch Exception any (str "Ne can tace CAR of `" x "` (" (.getName (.getClass x)) ")")
(throw (ex-info
(str "Cannot take CAR of `" x "` (" (.getName (.getClass x)) ")")
{:phase :host {:phase :host
:function 'CAR :function 'CAR
:args (list x) :args (list x)
:type :beowulf} :type :beowulf}))))
;; startlingly, Lisp 1.5 did not flag an error when you took the
;; CAR of something that wasn't cons cell. The result, as the
;; manual says (page 56), could be garbage.
any))))))
(defn CDR (defn CDR
"Return the item indicated by the second pointer of a pair. NIL is treated "Return the item indicated by the second pointer of a pair. NIL is treated
specially: the CDR of NIL is NIL." specially: the CDR of NIL is NIL."
[x] [x]
(if (cond
(= x NIL) NIL (= x NIL) NIL
(try (instance? ConsCell x) (or (.getCdr x) NIL)
(.getCdr x) :else (throw (ex-info
(catch Exception any (str "Ne can tace CDR of `" x "` (" (.getName (.getClass x)) ")")
(throw (ex-info
(str "Cannot take CDR of `" x "` (" (.getName (.getClass x)) ")")
{:phase :host {:phase :host
:function 'CDR :function 'CDR
:args (list x) :args (list x)
:type :beowulf} :type :beowulf}))))
;; startlingly, Lisp 1.5 did not flag an error when you took the
;; CAR of something that wasn't cons cell. The result, as the
;; manual says (page 56), could be garbage.
any))))))
(defn uaf (defn uaf
"Universal access function; `l` is expected to be an arbitrary LISP list, `path` "Universal access function; `l` is expected to be an arbitrary LISP list, `path`
@ -175,14 +165,14 @@
:type :beowulf} :type :beowulf}
any)))) any))))
(throw (ex-info (throw (ex-info
(str "Invalid value in RPLACA: `" value "` (" (type value) ")") (str "Un-ġefōg þing in RPLACA: `" value "` (" (type value) ")")
{:cause :bad-value {:cause :bad-value
:phase :host :phase :host
:function :rplaca :function :rplaca
:args (list cell value) :args (list cell value)
:type :beowulf}))) :type :beowulf})))
(throw (ex-info (throw (ex-info
(str "Invalid cell in RPLACA: `" cell "` (" (type cell) ")") (str "Uncynlic miercels in RPLACA: `" cell "` (" (type cell) ")")
{:cause :bad-cell {:cause :bad-cell
:phase :host :phase :host
:function :rplaca :function :rplaca
@ -215,14 +205,14 @@
:type :beowulf} :type :beowulf}
any)))) any))))
(throw (ex-info (throw (ex-info
(str "Invalid value in RPLACD: `" value "` (" (type value) ")") (str "Un-ġefōg þing in RPLACD: `" value "` (" (type value) ")")
{:cause :bad-value {:cause :bad-value
:phase :host :phase :host
:function :rplacd :function :rplacd
:args (list cell value) :args (list cell value)
:type :beowulf}))) :type :beowulf})))
(throw (ex-info (throw (ex-info
(str "Invalid cell in RPLACD: `" cell "` (" (type cell) ")") (str "Uncynlic miercels in RPLACD: `" cell "` (" (type cell) ")")
{:cause :bad-cell {:cause :bad-cell
:phase :host :phase :host
:detail :rplacd :detail :rplacd
@ -288,10 +278,13 @@
In `beowulf.host` principally because I don't yet feel confident to define In `beowulf.host` principally because I don't yet feel confident to define
varargs functions in Lisp." varargs functions in Lisp."
[& args] [& args]
;; (println "AND: " args " type: " (type args) " seq? " (seq? args))
;; (println " filtered: " (seq (filter #{F NIL} args)))
(cond (= NIL args) T (cond (= NIL args) T
(not (#{NIL F} (.getCar args))) (AND (.getCdr args)) (seq? args) (if (seq (filter #{F NIL} args)) F T)
:else T)) :else T))
(defn OR (defn OR
"`T` if and only if at least one of my `args` evaluates to something other "`T` if and only if at least one of my `args` evaluates to something other
than either `F` or `NIL`, else `F`. than either `F` or `NIL`, else `F`.
@ -299,9 +292,12 @@
In `beowulf.host` principally because I don't yet feel confident to define In `beowulf.host` principally because I don't yet feel confident to define
varargs functions in Lisp." varargs functions in Lisp."
[& args] [& args]
;; (println "OR: " args " type: " (type args) " seq? " (seq? args))
;; (println " filtered: " (seq (remove #{F NIL} args)))
(cond (= NIL args) F (cond (= NIL args) F
(not (#{NIL F} (.getCar args))) T (seq? args) (if (seq (remove #{F NIL} args)) T F)
:else (OR (.getCdr args)))) :else F))
;;;; Operations on lists ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; Operations on lists ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
@ -414,7 +410,7 @@
(defn ERROR (defn ERROR
"Throw an error" "Throw an error"
[& args] [& args]
(throw (ex-info "LISP ERROR" {:args args (throw (ex-info "LISP STÆFLEAHTER" {:args args
:phase :eval :phase :eval
:function 'ERROR :function 'ERROR
:type :lisp :type :lisp
@ -477,19 +473,26 @@
first argument is always an atom. Since it's `ASSOC` and `EVAL` which I first argument is always an atom. Since it's `ASSOC` and `EVAL` which I
need to make work, I'm going to assume that page 59 is wrong." need to make work, I'm going to assume that page 59 is wrong."
[symbol indicator] [symbol indicator]
(let [binding (ASSOC symbol @oblist)] (let [binding (ASSOC symbol @oblist)
(cond val (cond
(= binding NIL) NIL (= binding NIL) NIL
(= magic-marker (CADR binding)) (loop [b binding] (= magic-marker
(cond (= b NIL) NIL (CADR binding)) (loop [b binding]
(= (CAR b) indicator) (CADR b) ;; (println "GET loop, seeking " indicator ":")
:else (recur (CDR b)))) ;; (pretty-print b)
(if (instance? ConsCell b)
(if (= (CAR b) indicator)
(CADR b) ;; <- this is what we should actually be returning
(recur (CDR b)))
NIL))
:else (throw :else (throw
(ex-info "Misformatted property list (missing magic marker)" (ex-info "Misformatted property list (missing magic marker)"
{:phase :host {:phase :host
:function :get :function :get
:args (list symbol indicator) :args (list symbol indicator)
:type :beowulf}))))) :type :beowulf})))]
;; (println "<< GET returning: " val)
val))
(defn DEFLIST (defn DEFLIST
"For each pair in this association list `a-list`, set the property with this "For each pair in this association list `a-list`, set the property with this
@ -565,4 +568,4 @@
argument was, or was not, a cons cell." argument was, or was not, a cons cell."
[o] [o]
(when (lax? 'CONSP) (when (lax? 'CONSP)
(if (instance? o ConsCell) 'T 'F))) (if (instance? ConsCell o) 'T 'F)))

View file

@ -100,16 +100,16 @@
(catch java.lang.ClassNotFoundException _ nil)) q-name (catch java.lang.ClassNotFoundException _ nil)) q-name
:else (throw :else (throw
(ex-info (ex-info
(str "INTEROP: unknown function `" fn-symbol "`") (str "INTEROP: ungecnáwen þegnung `" fn-symbol "`")
{:cause :interop {:cause :interop
:detail :not-found :detail :not-found
:name fn-symbol :name fn-symbol
:also-tried l-name}))) :also-tried l-name})))
args' (to-clojure args)] args' (to-clojure args)]
(print (str "INTEROP: evaluating `" (cons f args') "`")) ;; (print (str "INTEROP: eahtiende `" (cons f args') "`"))
(flush) (flush)
(let [result (eval (conj args' f))] ;; this has the potential to blow up the world (let [result (eval (conj args' f))] ;; this has the potential to blow up the world
(println (str "; returning `" result "`")) ;; (println (str "; ágiefende `" result "`"))
(cond (cond
(instance? beowulf.cons_cell.ConsCell result) result (instance? beowulf.cons_cell.ConsCell result) result
(coll? result) (make-beowulf-list result) (coll? result) (make-beowulf-list result)
@ -118,12 +118,12 @@
(number? result) result (number? result) result
:else (throw :else (throw
(ex-info (ex-info
(str "INTEROP: Cannot return `" result "` to Lisp 1.5.") (str "INTEROP: Ne can eahtiende `" result "` to Lisp 1.5.")
{:cause :interop {:cause :interop
:detail :not-representable :detail :not-representable
:result result}))))) :result result})))))
(throw (throw
(ex-info (ex-info
(str "INTEROP not allowed in strict mode.") (str "INTEROP ne āfand innan Lisp 1.5.")
{:cause :interop {:cause :interop
:detail :strict})))) :detail :strict}))))

View file

@ -46,7 +46,7 @@
;;; ;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(def ^:constant default-sysout "resources/lisp1.5.lsp") (def ^:constant default-sysout "lisp1.5.lsp")
(defn- full-path (defn- full-path
[fp] [fp]
@ -105,12 +105,15 @@
(pretty-print output) (pretty-print output)
))))) )))))
(defn- resolve-subr (defn resolve-subr
"If this oblist `entry` references a subroutine, attempt to fix up that "If this oblist `entry` references a subroutine, attempt to fix up that
reference." reference."
[entry] ([entry]
(or (resolve-subr entry 'SUBR)
(resolve-subr entry 'FSUBR)))
([entry prop]
(cond (= entry NIL) NIL (cond (= entry NIL) NIL
(= (CAR entry) 'SUBR) (try (= (CAR entry) prop) (try
(make-cons-cell (make-cons-cell
(CAR entry) (CAR entry)
(make-cons-cell (make-cons-cell
@ -118,11 +121,11 @@
(CADR entry)) (CADR entry))
(CDDR entry))) (CDDR entry)))
(catch Exception _ (catch Exception _
(print "Warning: failed to resolve " (print "Warnung: ne can āfinde "
(CADR entry)) (CADR entry))
(CDDR entry))) (CDDR entry)))
:else (make-cons-cell :else (make-cons-cell
(CAR entry) (resolve-subr (CDR entry))))) (CAR entry) (resolve-subr (CDR entry))))))
(defn- resolve-subroutines (defn- resolve-subroutines
@ -151,18 +154,18 @@
**NOTE THAT** this is an extension function, not available in strct mode." **NOTE THAT** this is an extension function, not available in strct mode."
([] ([]
(SYSIN (or (:read *options*) default-sysout))) (SYSIN (or (:read *options*) (str "resources/" default-sysout))))
([filename] ([filename]
(let [fp (file (full-path (str filename))) (let [fp (file (full-path (str filename)))
file (when (and (.exists fp) (.canRead fp)) fp) file (when (and (.exists fp) (.canRead fp)) fp)
res (try (resource filename) res (try (resource filename)
(catch Throwable _ nil)) (catch Throwable _ nil))
content (try (READ (slurp (or file res))) content (try (READ (slurp (or file res)))
(catch Throwable any (catch Throwable _
(throw (ex-info "Could not read from file" (throw (ex-info "Ne can ārǣde"
{:context "SYSIN" {:context "SYSIN"
:filepath fp} :filename filename
any))))] :filepath fp}))))]
(swap! oblist (swap! oblist
#(when (or % (seq content)) #(when (or % (seq content))
(resolve-subroutines content)))))) (resolve-subroutines content))))))

View file

@ -13,7 +13,7 @@
Both these extensions can be disabled by using the `--strict` command line Both these extensions can be disabled by using the `--strict` command line
switch." switch."
(: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 [simplify]] [beowulf.reader.simplify :refer [simplify]]
@ -79,7 +79,7 @@
parse-tree (parse source)] parse-tree (parse source)]
(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 "Ne can forstande " (assoc parse-tree :source source))))
(generate (simplify parse-tree))))) (generate (simplify parse-tree)))))
(defn read-from-console (defn read-from-console
@ -99,7 +99,7 @@
the final Lisp reader. `input` should be either a string representation of a LISP 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." expression, or else an input stream. A single form will be read."
([] ([]
(gsp (read-chars))) (gsp (read-from-console)))
([input] ([input]
(cond (cond
(empty? input) (READ) (empty? input) (READ)

View file

@ -15,9 +15,14 @@
rather than the strings which were supplied to `READ`); rather than the strings which were supplied to `READ`);
4. <Tab> offers potential auto-completions taken from the value of `(OBLIST)`, ideally the 4. <Tab> offers potential auto-completions taken from the value of `(OBLIST)`, ideally the
current value, not the value at the time the session started; current value, not the value at the time the session started;
5. <Back-arrow> and <Forward-arrow> offer movement and editing within the line." 5. <Back-arrow> and <Forward-arrow> offer movement and editing within the line.
(:import [org.jline.reader LineReader LineReaderBuilder]
[org.jline.terminal TerminalBuilder])) TODO: There are multiple problems with JLine; a better solution might be
to start from here:
https://stackoverflow.com/questions/7931988/how-to-manipulate-control-characters"
;; (:import [org.jline.reader LineReader LineReaderBuilder]
;; [org.jline.terminal TerminalBuilder])
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; ;;;
@ -44,27 +49,27 @@
;; looks as though you'd need a DPhil in JLine to write it, and I don't have ;; looks as though you'd need a DPhil in JLine to write it, and I don't have
;; the time. ;; the time.
(def get-reader ;; (def get-reader
"Return a reader, first constructing it if necessary. ;; "Return a reader, first constructing it if necessary.
**NOTE THAT** this is not settled API. The existence and call signature of ;; **NOTE THAT** this is not settled API. The existence and call signature of
this function is not guaranteed in future versions." ;; this function is not guaranteed in future versions."
(memoize (fn [] ;; (memoize (fn []
(let [term (.build (.system (TerminalBuilder/builder) true))] ;; (let [term (.build (.system (TerminalBuilder/builder) true))]
(.build (.terminal (LineReaderBuilder/builder) term)))))) ;; (.build (.terminal (LineReaderBuilder/builder) term))))))
(defn read-chars ;; (defn read-chars
"A drop-in replacement for `clojure.core/read-line`, except that line editing ;; "A drop-in replacement for `clojure.core/read-line`, except that line editing
and history should be enabled. ;; and history should be enabled.
**NOTE THAT** this does not work yet, but it is in the API because I hope ;; **NOTE THAT** this does not work yet, but it is in the API because I hope
that it will work later!" ;; that it will work later!"
[] ;; []
(let [eddie (get-reader)] ;; (let [eddie (get-reader)]
(loop [s (.readLine eddie)] ;; (loop [s (.readLine eddie)]
(if (and (= (count (re-seq #"\(" s)) ;; (if (and (= (count (re-seq #"\(" s))
(count (re-seq #"\)" s))) ;; (count (re-seq #"\)" s)))
(= (count (re-seq #"\[]" s)) ;; (= (count (re-seq #"\[]" s))
(count (re-seq #"\]" s)))) ;; (count (re-seq #"\]" s))))
s ;; s
(recur (str s " " (.readLine eddie))))))) ;; (recur (str s " " (.readLine eddie)))))))

View file

@ -59,7 +59,8 @@
[beowulf.reader.macros :refer [expand-macros]] [beowulf.reader.macros :refer [expand-macros]]
[beowulf.oblist :refer [NIL]] [beowulf.oblist :refer [NIL]]
[clojure.math.numeric-tower :refer [expt]] [clojure.math.numeric-tower :refer [expt]]
[clojure.string :refer [upper-case]])) [clojure.string :refer [upper-case]]
[clojure.tools.trace :refer [deftrace]]))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; ;;;
@ -86,37 +87,37 @@
(defn gen-cond-clause (defn gen-cond-clause
"Generate a cond clause from this simplified parse tree fragment `p`; "Generate a cond clause from this simplified parse tree fragment `p`;
returns `nil` if `p` does not represent a cond clause." returns `nil` if `p` does not represent a cond clause."
[p] [p context]
(when (when
(and (coll? p) (= :cond-clause (first p))) (and (coll? p) (= :cond-clause (first p)))
(make-beowulf-list (make-beowulf-list
(list (if (= (nth p 1) [:quoted-expr [:atom "T"]]) (list (if (= (nth p 1) [:quoted-expr [:atom "T"]])
'T 'T
(generate (nth p 1))) (generate (nth p 1) context))
(generate (nth p 2)))))) (generate (nth p 2) context)))))
(defn gen-cond (defn gen-cond
"Generate a cond statement from this simplified parse tree fragment `p`; "Generate a cond statement from this simplified parse tree fragment `p`;
returns `nil` if `p` does not represent a (MEXPR) cond statement." returns `nil` if `p` does not represent a (MEXPR) cond statement."
[p] [p context]
(when (when
(and (coll? p) (= :cond (first p))) (and (coll? p) (= :cond (first p)))
(make-beowulf-list (make-beowulf-list
(cons (cons
'COND 'COND
(map (map
generate #(generate % (if (= context :mexpr) :cond-mexpr context))
(rest p)))))) (rest p))))))
(defn gen-fn-call (defn gen-fn-call
"Generate a function call from this simplified parse tree fragment `p`; "Generate a function call from this simplified parse tree fragment `p`;
returns `nil` if `p` does not represent a (MEXPR) function call." returns `nil` if `p` does not represent a (MEXPR) function call."
[p] [p context]
(when (when
(and (coll? p) (= :fncall (first p)) (= :mvar (first (second p)))) (and (coll? p) (= :fncall (first p)) (= :mvar (first (second p))))
(make-cons-cell (make-cons-cell
(generate (second p)) (generate (second p) context)
(generate (nth p 2))))) (generate (nth p 2) context))))
(defn gen-dot-terminated-list (defn gen-dot-terminated-list
@ -137,38 +138,50 @@
(generate (first p)) (generate (first p))
(gen-dot-terminated-list (rest p))))) (gen-dot-terminated-list (rest p)))))
;; null[x] = [x = NIL -> T; T -> F]
;; [:defn
;; [:mexpr [:fncall [:mvar "null"] [:bindings [:args [:mexpr [:mvar "x"]]]]]]
;; "="
;; [:mexpr [:cond
;; [:cond-clause [:mexpr [:iexpr [:lhs [:mexpr [:mvar "x"]]] [:iop "="] [:rhs [:mexpr [:mconst "NIL"]]]]] [:mexpr [:mconst "T"]]]
;; [:cond-clause [:mexpr [:mconst "T"]] [:mexpr [:mconst "F"]]]]]]
(defn generate-defn (defn generate-defn
[tree] [tree context]
(if (= :mexpr (first tree))
(generate-defn (second tree) context)
(make-beowulf-list (make-beowulf-list
(list 'SET (list 'PUT
(list 'QUOTE (generate (-> tree second second))) (list 'QUOTE (generate (-> tree second second second) context))
(list 'QUOTE 'EXPR)
(list 'QUOTE (list 'QUOTE
(cons 'LAMBDA (cons 'LAMBDA
(cons (generate (nth (second tree) 2)) (list (generate (nth (-> tree second second) 2) context)
(map generate (-> tree rest rest rest)))))))) (generate (nth tree 3) context))))))))
(defn gen-iexpr (defn gen-iexpr
[tree] [tree context]
(let [bundle (reduce #(assoc %1 (first %2) %2) (let [bundle (reduce #(assoc %1 (first %2) %2)
{} {}
(rest tree))] (rest tree))]
(list (generate (:iop bundle)) (list (generate (:iop bundle) context)
(generate (:lhs bundle)) (generate (:lhs bundle) context)
(generate (:rhs bundle))))) (generate (:rhs bundle) context))))
(defn generate-set (defn generate-set
"Actually not sure what the mexpr representation of set looks like" "Actually not sure what the mexpr representation of set looks like"
[tree] [tree context]
(throw (ex-info "Not Yet Implemented" {:feature "generate-set"}))) (throw (ex-info "Not Yet Implemented" {:feature "generate-set"})))
(defn generate-assign (defn generate-assign
"Generate an assignment statement based on this `tree`. If the thing "Generate an assignment statement based on this `tree`. If the thing
being assigned to is a function signature, then we have to do something being assigned to is a function signature, then we have to do something
different to if it's an atom." different to if it's an atom."
[tree] [tree context]
(case (first (second tree)) (case (first (second tree))
:fncall (generate-defn tree) :fncall (generate-defn tree context)
(:mvar :atom) (generate-set tree))) :mexpr (map #(generate % context) (rest (second tree)))
(:mvar :atom) (generate-set tree context)))
(defn strip-leading-zeros (defn strip-leading-zeros
"`read-string` interprets strings with leading zeros as octal; strip "`read-string` interprets strings with leading zeros as octal; strip
@ -187,7 +200,9 @@
(defn generate (defn generate
"Generate lisp structure from this parse tree `p`. It is assumed that "Generate lisp structure from this parse tree `p`. It is assumed that
`p` has been simplified." `p` has been simplified."
[p] ([p]
(generate p :expr))
([p context]
(try (try
(expand-macros (expand-macros
(if (if
@ -195,23 +210,23 @@
(case (first p) (case (first p)
"LAMBDA" "LAMBDA"
:λexpr (make-cons-cell :λexpr (make-cons-cell
(generate (nth p 1)) (generate (nth p 1) context)
(make-cons-cell (generate (nth p 2)) (make-cons-cell (generate (nth p 2) context)
(generate (nth p 3)))) (generate (nth p 3) context)))
:args (make-beowulf-list (map generate (rest p))) :args (make-beowulf-list (map #(generate % context) (rest p)))
:atom (symbol (second p)) :atom (symbol (second p))
:bindings (generate (second p)) :bindings (generate (second p) context)
:body (make-beowulf-list (map generate (rest p))) :body (make-beowulf-list (map #(generate % context) (rest p)))
(:coefficient :exponent) (generate (second p)) (:coefficient :exponent) (generate (second p) context)
:cond (gen-cond p) :cond (gen-cond p (if (= context :mexpr) :cond-mexpr context))
:cond-clause (gen-cond-clause p) :cond-clause (gen-cond-clause p context)
:decimal (read-string (apply str (map second (rest p)))) :decimal (read-string (apply str (map second (rest p))))
:defn (generate-assign p) :defn (generate-defn p context)
:dotted-pair (make-cons-cell :dotted-pair (make-cons-cell
(generate (nth p 1)) (generate (nth p 1) context)
(generate (nth p 2))) (generate (nth p 2) context))
:fncall (gen-fn-call p) :fncall (gen-fn-call p context)
:iexpr (gen-iexpr p) :iexpr (gen-iexpr p context)
:integer (read-string (strip-leading-zeros (second p))) :integer (read-string (strip-leading-zeros (second p)))
:iop (case (second p) :iop (case (second p)
"/" 'DIFFERENCE "/" 'DIFFERENCE
@ -225,24 +240,30 @@
{:phase :generate {:phase :generate
:fragment p}))) :fragment p})))
:list (gen-dot-terminated-list (rest p)) :list (gen-dot-terminated-list (rest p))
(:lhs :rhs) (generate (second p)) (:lhs :rhs) (generate (second p) context)
:mexpr (generate (second p)) :mexpr (generate (second p) (if (= context :cond-mexpr) context :mexpr))
:mconst (make-beowulf-list :mconst (if (= context :cond-mexpr)
(list 'QUOTE (symbol (upper-case (second p))))) (case (second p)
("T" "F" "NIL") (symbol (second p))
;; else
(list 'QUOTE (symbol (second p))))
;; else
(list 'QUOTE (symbol (second p))))
:mvar (symbol (upper-case (second p))) :mvar (symbol (upper-case (second p)))
:number (generate (second p)) :number (generate (second p) context)
:octal (let [n (read-string (strip-leading-zeros (second p) "0")) :octal (let [n (read-string (strip-leading-zeros (second p) "0"))
scale (generate (nth p 3))] scale (generate (nth p 3) context)]
(* n (expt 8 scale))) (* n (expt 8 scale)))
;; the quote read macro (which probably didn't exist in Lisp 1.5, but...) ;; the quote read macro (which probably didn't exist in Lisp 1.5, but...)
:quoted-expr (make-beowulf-list (list 'QUOTE (generate (second p)))) :quoted-expr (make-beowulf-list (list 'QUOTE (generate (second p) context)))
:scale-factor (if :scale-factor (if
(empty? (second p)) 0 (empty? (second p)) 0
(read-string (strip-leading-zeros (second p)))) (read-string (strip-leading-zeros (second p))))
:scientific (let [n (generate (second p)) :scientific (let [n (generate (second p) context)
exponent (generate (nth p 3))] exponent (generate (nth p 3) context)]
(* n (expt 10 exponent))) (* n (expt 10 exponent)))
:sexpr (generate (second p) :sexpr)
:subr (symbol (second p)) :subr (symbol (second p))
;; default ;; default
@ -252,4 +273,4 @@
(catch Throwable any (catch Throwable any
(throw (ex-info "Could not generate" (throw (ex-info "Could not generate"
{:generating p} {:generating p}
any))))) any))))))

View file

@ -51,10 +51,10 @@
"exprs := expr | exprs;" "exprs := expr | exprs;"
"mexpr := λexpr | fncall | defn | cond | mvar | mconst | iexpr | number | mexpr comment; "mexpr := λexpr | fncall | defn | cond | mvar | mconst | iexpr | number | mexpr comment;
λexpr := λ lsqb bindings semi-colon body rsqb; λexpr := λ lsqb bindings semi-colon opt-space body opt-space rsqb;
λ := '; λ := ' | 'lambda';
bindings := lsqb args rsqb | lsqb rsqb; bindings := lsqb args rsqb | lsqb rsqb;
body := (mexpr semi-colon opt-space)* mexpr; body := (opt-space mexpr semi-colon)* opt-space mexpr;
fncall := fn-name bindings; fncall := fn-name bindings;
lsqb := '['; lsqb := '[';
rsqb := ']'; rsqb := ']';
@ -65,7 +65,7 @@
cond-clause := mexpr opt-space arrow opt-space mexpr opt-space; cond-clause := mexpr opt-space arrow opt-space mexpr opt-space;
arrow := '->'; arrow := '->';
args := arg | (opt-space arg semi-colon opt-space)* opt-space arg opt-space; args := arg | (opt-space arg semi-colon opt-space)* opt-space arg opt-space;
arg := mexpr | sexpr; arg := mexpr;
fn-name := mvar; fn-name := mvar;
mvar := #'[a-z][a-z0-9]*'; mvar := #'[a-z][a-z0-9]*';
mconst := #'[A-Z][A-Z0-9]*'; mconst := #'[A-Z][A-Z0-9]*';

View file

@ -110,7 +110,7 @@
(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-tree (second p) :mexpr)) [:mexpr (simplify-tree (second p) :mexpr)])
:list (if :list (if
(= context :mexpr) (= context :mexpr)
[:fncall [:fncall
@ -118,7 +118,7 @@
[:args (apply vector (map simplify-tree (rest p)))]] [:args (apply vector (map simplify-tree (rest p)))]]
(map #(simplify-tree % context) p)) (map #(simplify-tree % context) p))
:raw (first (remove empty? (map simplify-tree (rest p)))) :raw (first (remove empty? (map simplify-tree (rest p))))
:sexpr (simplify-tree (second p) :sexpr) :sexpr [:sexpr (simplify-tree (second p) :sexpr)]
;;default ;;default
p))) p)))
:else p))) :else p)))

View file

@ -1,20 +1,27 @@
(ns beowulf.bootstrap-test (ns beowulf.bootstrap-test
(:require [clojure.test :refer [deftest testing is]] (:require [beowulf.bootstrap :refer [EVAL]]
[beowulf.cons-cell :refer [make-cons-cell T F]] [beowulf.cons-cell :refer [F make-cons-cell T]]
[beowulf.host :refer [ASSOC ATOM ATOM? CAR CAAAAR CADR [beowulf.host :refer [ASSOC ATOM ATOM? CAAAAR CADDDR CADDR CADR
CADDR CADDDR CDR EQ EQUAL CAR CDR EQ EQUAL PAIRLIS]]
PAIRLIS]]
[beowulf.oblist :refer [NIL]] [beowulf.oblist :refer [NIL]]
[beowulf.read :refer [gsp]])) [beowulf.read :refer [gsp READ]]
[clojure.test :refer [deftest is testing]]))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; ;;;
;;; This file is primarily tests of the functions in `beowulf.eval` - which ;;; This file is primarily tests of the functions in `beowulf.bootstrap` - which
;;; are Clojure functions, but aim to provide sufficient functionality that ;;; are Clojure functions, but aim to provide sufficient functionality that
;;; Beowulf can get up to the level of running its own code. ;;; Beowulf can get up to the level of running its own code.
;;; ;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defn- reps
"'Read eval print string', or 'read eval print single'.
Reads and evaluates one input string, and returns the
output string."
[input]
(with-out-str (print (EVAL (READ input)))))
(deftest atom-tests (deftest atom-tests
(testing "ATOM" (testing "ATOM"
(let [expected T (let [expected T
@ -63,12 +70,12 @@
(is (= actual expected) "A is CAR of (A B C D)")) (is (= actual expected) "A is CAR of (A B C D)"))
(is (thrown-with-msg? (is (thrown-with-msg?
Exception Exception
#"Cannot take CAR of `.*" #"Ne can tace CAR of `.*"
(CAR 'T)) (CAR 'T))
"Can't take the CAR of an atom") "Can't take the CAR of an atom")
(is (thrown-with-msg? (is (thrown-with-msg?
Exception Exception
#"Cannot take CAR of `.*" #"Ne can tace CAR of `.*"
(CAR 7)) (CAR 7))
"Can't take the CAR of a number")) "Can't take the CAR of a number"))
(testing "CDR" (testing "CDR"
@ -82,12 +89,12 @@
(is (= (CAR actual) expected) "the CAR of that cons-cell is B")) (is (= (CAR actual) expected) "the CAR of that cons-cell is B"))
(is (thrown-with-msg? (is (thrown-with-msg?
Exception Exception
#"Cannot take CDR of `.*" #"Ne can tace CDR of `.*"
(CDR 'T)) (CDR 'T))
"Can't take the CDR of an atom") "Can't take the CDR of an atom")
(is (thrown-with-msg? (is (thrown-with-msg?
Exception Exception
#"Cannot take CDR of `.*" #"Ne can tace CDR of `.*"
(CDR 7)) (CDR 7))
"Can't take the CDR of a number")) "Can't take the CDR of a number"))
(let [s (gsp "((((1 . 2) 3)(4 5) 6)(7 (8 9) (10 11 12) 13) 14 (15 16) 17)")] (let [s (gsp "((((1 . 2) 3)(4 5) 6)(7 (8 9) (10 11 12) 13) 14 (15 16) 17)")]
@ -196,13 +203,3 @@
'D 'D
(gsp "((A . (M N)) (B . (CAR X)) (C . (QUOTE M)) (C . (CDR X)))")))] (gsp "((A . (M N)) (B . (CAR X)) (C . (QUOTE M)) (C . (CDR X)))")))]
(is (= actual expected))))) (is (= actual expected)))))
;; TODO: need to reimplement this in lisp_test
;; (deftest sublis-tests
;; (testing "sublis"
;; (let [expected "(SHAKESPEARE WROTE (THE TEMPEST))"
;; actual (print-str
;; (SUBLIS
;; (gsp "((X . SHAKESPEARE) (Y . (THE TEMPEST)))")
;; (gsp "(X WROTE Y)")))]
;; (is (= actual expected)))))

View file

@ -15,12 +15,12 @@
(is (= actual expected))) (is (= actual expected)))
(is (thrown-with-msg? (is (thrown-with-msg?
Exception Exception
#"Invalid value in RPLACA.*" #"Un-ġefōg þing in RPLACA.*"
(RPLACA (make-beowulf-list '(A B C D E)) "F")) (RPLACA (make-beowulf-list '(A B C D E)) "F"))
"You can't represent a string in Lisp 1.5") "You can't represent a string in Lisp 1.5")
(is (thrown-with-msg? (is (thrown-with-msg?
Exception Exception
#"Invalid cell in RPLACA.*" #"Uncynlic miercels in RPLACA.*"
(RPLACA '(A B C D E) 'F)) (RPLACA '(A B C D E) 'F))
"You can't RPLACA into anything which isn't a MutableSequence.") "You can't RPLACA into anything which isn't a MutableSequence.")
) )

View file

@ -74,8 +74,8 @@
(is (= actual expected)))) (is (= actual expected))))
(testing "divide by zero" (testing "divide by zero"
(let [input "(DIVIDE 22 0)"] (let [input "(DIVIDE 22 0)"]
(is (thrown-with-msg? ArithmeticException (is (thrown-with-msg? clojure.lang.ExceptionInfo
#"Divide by zero" #"Uncynlic þegnung: Divide by zero"
(reps input))))) (reps input)))))
;; TODO: need to write tests for GET but I don't really ;; TODO: need to write tests for GET but I don't really
@ -146,5 +146,23 @@
actual (reps "(MEMBER 'BERTRAM '(ALBERT BELINDA CHARLIE DORIS ELFREDA FRED))")] actual (reps "(MEMBER 'BERTRAM '(ALBERT BELINDA CHARLIE DORIS ELFREDA FRED))")]
(is (= actual expected))))) (is (= actual expected)))))
;; This is failing, and although yes, it does matter, I have not yet tracked the reason.
;; (deftest sublis-tests
;; (testing "sublis"
;; (let [expected "(SHAKESPEARE WROTE (THE TEMPEST))"
;; actual (reps
;; "(SUBLIS
;; '((X . SHAKESPEARE) (Y . (THE TEMPEST)))
;; '(X WROTE Y))")]
;; (is (= actual expected)))))
(deftest prog-tests
(testing "PROG"
(let [expected "5"
actual (reps "(PROG (X)
(SETQ X 1)
START
(SETQ X (ADD1 X))
(COND ((EQ X 5) (RETURN X))
(T (GO START))))")]
(is (= actual expected)))))

View file

@ -68,10 +68,10 @@
(deftest conditional-tests (deftest conditional-tests
(testing "Conditional expressions" (testing "Conditional expressions"
(let [expected "(COND ((ATOM X) X) ((QUOTE T) (FF (CAR X))))" (let [expected "(COND ((ATOM X) X) (T (FF (CAR X))))"
actual (print-str (gsp "[atom[x]->x; T->ff[car[x]]]"))] actual (print-str (gsp "[atom[x]->x; T->ff[car[x]]]"))]
(is (= actual expected))) (is (= actual expected)))
(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) (T (FF (CAR X))))))"
actual (print-str actual (print-str
(generate (generate
(simplify-tree (simplify-tree
@ -88,6 +88,6 @@
(deftest assignment-tests (deftest assignment-tests
(testing "Function assignment" (testing "Function assignment"
(let [expected "(SET (QUOTE FF) (QUOTE (LAMBDA (X) (COND ((ATOM X) X) ((QUOTE T) (FF (CAR X)))))))" (let [expected "(PUT (QUOTE FF) (QUOTE EXPR) (QUOTE (LAMBDA (X) (COND ((ATOM X) X) (T (FF (CAR X)))))))"
actual (print-str (gsp "ff[x]=[atom[x] -> x; T -> ff[car[x]]]"))] actual (print-str (gsp "ff[x]=[atom[x] -> x; T -> ff[car[x]]]"))]
(is (= actual expected))))) (is (= actual expected)))))