Merge remote-tracking branch 'origin/master'

This commit is contained in:
Simon Brooke 2019-08-20 18:47:20 +01:00
commit 1b63aa6e1a
33 changed files with 4292 additions and 102 deletions

View file

@ -7,10 +7,66 @@ LISP 1.5 is to all Lisp dialects as Beowulf is to Emglish literature.
A work-in-progress towards an implementation of Lisp 1.5 in Clojure. The
objective is to build a complete and accurate implementation of Lisp 1.5
as described in the manual, with, in so far as is possible, exactly the
same bahaviour; the only intended deviation is that the parser reads
'mexprs' (meta language expressions) as well as sexprs.
same bahaviour - except as documented below.
## BUT WHY?!!?!
### Status
Boots to REPL, but few functions yet available.
### Architectural plan
Not everything documented in this section is yet built. It indicates the
direction of travel and intended destination, not the current state.
#### resources/lisp1.5.lsp
The objective is to have within `resources/lisp1.5.lsp`, all those functions
defined in the Lisp 1.5 Programmer's Manual which can be implemented in Lisp.
This means that, while Beowulf is hosted on Clojure, all that would be
required to rehost Lisp 1.5 on a different platform would be to reimplement
* bootstrap.clj
* host.clj
* read.clj
The objective this is to make it fairly easy to implement Lisp 1.5 on top of
any of the many [Make A Lisp](https://github.com/kanaka/mal)
implementations.
#### beowulf/boostrap.clj
This file is essentially Lisp as defined in Chapter 1 (pages 1-14) of the
Lisp 1.5 Programmer's Manual; that is to say, a very simple Lisp language,
which should, I believe, be sufficient in conjunction with the functions
provided by `beowulf.host`, be sufficient to bootstrap the full Lisp 1.5
interpreter.
In addition it contains the function `INTEROP`, which allows host language
functions to be called from Lisp.
#### beowulf/host.clj
This file 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
host language, in this case Clojure.
#### beowulf/read.clj
This file provides the reader required for boostrapping. It's not a bad
reader - it provides feedback on errors found in the input - but it isn't
the real Lisp reader.
Intended deviations from the behaviour of the real Lisp reader are as follows:
1. It reads the meta-expression language `MEXPR` in addition to the
symbolic expression language `SEXPR`, which I do not believe the Lisp 1.5
reader ever did;
2. It treats everything between a semi-colon and an end of line as a comment,
as most modern Lisps do; but I do not believe Lisp 1.5 had this feature.
### BUT WHY?!!?!
Because.
@ -23,9 +79,24 @@ for modern machines.
Because I'm barking mad, and this is therapy.
### Commentary
What's surprised me in working on this is how much more polished Lisp 1.5 is
than legend had led me to believe. The language is remarkably close to
[Portable Standard Lisp](http://www.softwarepreservation.org/projects/LISP/standard_lisp_family/#Portable_Standard_LISP_)
which is in my opinion one of the best and most usable early Lisp
implementations. I'm convinced you could still use Lisp 1.5 for interesting
and useful software (which isn't to say that some modern Lisps aren't better,
but this is software which is almost sixty years old).
## Installation
Download from http://example.com/FIXME.
At present, clone the source and build it using
`lein uberjar`.
You will require to have [Leiningen](https://leiningen.org/) installed.
## Usage
@ -41,6 +112,17 @@ The `Lisp 1.5 Programmer's Manual` is still
[in print, ISBN 13 978-0-262-13011-0](https://mitpress.mit.edu/books/lisp-15-programmers-manual); but it's also
[available online](http://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf).
## Other Lisp 1.5 resources
The main resource I'm aware of is the Software Preservation Society's site,
[here](http://www.softwarepreservation.org/projects/LISP/lisp1.5). It has lots
of fascinating stuff including full assembler listings for various obsolete
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
reconstructed from the manual.
I'm not at this time aware of any other working Lisp 1.5 implementations.
## License
Copyright © 2019 Simon Brooke. Licensed under the GNU General Public License,

1
_config.yml Normal file
View file

@ -0,0 +1 @@
theme: jekyll-theme-slate

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,476 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" href="../coverage.css"/> <title> beowulf/cons_cell.clj </title>
</head>
<body>
<span class="covered" title="1 out of 1 forms covered">
001&nbsp;&nbsp;(ns&nbsp;beowulf.cons-cell
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
002&nbsp;&nbsp;&nbsp;&nbsp;&quot;The&nbsp;fundamental&nbsp;cons&nbsp;cell&nbsp;on&nbsp;which&nbsp;all&nbsp;Lisp&nbsp;structures&nbsp;are&nbsp;built.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
003&nbsp;&nbsp;&nbsp;&nbsp;Lisp&nbsp;1.5&nbsp;lists&nbsp;do&nbsp;not&nbsp;necessarily&nbsp;have&nbsp;a&nbsp;sequence&nbsp;as&nbsp;their&nbsp;CDR,&nbsp;so
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
004&nbsp;&nbsp;&nbsp;&nbsp;cannot&nbsp;be&nbsp;implemented&nbsp;on&nbsp;top&nbsp;of&nbsp;Clojure&nbsp;lists.&quot;)
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
005&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
006&nbsp;&nbsp;(def&nbsp;NIL
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
007&nbsp;&nbsp;&nbsp;&nbsp;&quot;The&nbsp;canonical&nbsp;empty&nbsp;list&nbsp;symbol.&quot;
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
008&nbsp;&nbsp;&nbsp;&nbsp;(symbol&nbsp;&quot;NIL&quot;))
</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;(def&nbsp;T
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
011&nbsp;&nbsp;&nbsp;&nbsp;&quot;The&nbsp;canonical&nbsp;true&nbsp;value.&quot;
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
012&nbsp;&nbsp;&nbsp;&nbsp;(symbol&nbsp;&quot;T&quot;))&nbsp;;;&nbsp;true.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
013&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
014&nbsp;&nbsp;(def&nbsp;F
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
015&nbsp;&nbsp;&nbsp;&nbsp;&quot;The&nbsp;canonical&nbsp;false&nbsp;value&nbsp;-&nbsp;different&nbsp;from&nbsp;`NIL`,&nbsp;which&nbsp;is&nbsp;not&nbsp;canonically
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
016&nbsp;&nbsp;&nbsp;&nbsp;false&nbsp;in&nbsp;Lisp&nbsp;1.5.&quot;
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
017&nbsp;&nbsp;&nbsp;&nbsp;(symbol&nbsp;&quot;F&quot;))&nbsp;;;&nbsp;false&nbsp;as&nbsp;distinct&nbsp;from&nbsp;nil
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
018&nbsp;&nbsp;
</span><br/>
<span class="partial" title="5 out of 8 forms covered">
019&nbsp;&nbsp;(deftype&nbsp;ConsCell&nbsp;[CAR&nbsp;CDR]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
020&nbsp;&nbsp;&nbsp;&nbsp;clojure.lang.ISeq
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
021&nbsp;&nbsp;&nbsp;&nbsp;(cons&nbsp;[this&nbsp;x]&nbsp;(ConsCell.&nbsp;x&nbsp;this))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
022&nbsp;&nbsp;&nbsp;&nbsp;(first&nbsp;[this]&nbsp;(.CAR&nbsp;this))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
023&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;next&nbsp;and&nbsp;more&nbsp;must&nbsp;return&nbsp;ISeq:
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
024&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;https:&#x2F;&#x2F;github.com&#x2F;clojure&#x2F;clojure&#x2F;blob&#x2F;master&#x2F;src&#x2F;jvm&#x2F;clojure&#x2F;lang&#x2F;ISeq.java
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
025&nbsp;&nbsp;&nbsp;&nbsp;(more&nbsp;[this]&nbsp;(if
</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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(seq?&nbsp;(.CDR&nbsp;this))
</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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(.CDR&nbsp;this)
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
028&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;clojure.lang.PersistentList&#x2F;EMPTY))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
029&nbsp;&nbsp;&nbsp;&nbsp;(next&nbsp;[this]&nbsp;(if
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
030&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(seq?&nbsp;(.CDR&nbsp;this))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
031&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(.CDR&nbsp;this)
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
032&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nil&nbsp;;;&nbsp;next&nbsp;returns&nbsp;nil&nbsp;when&nbsp;empty
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
033&nbsp;&nbsp;&nbsp;&nbsp;&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">
034&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
035&nbsp;&nbsp;&nbsp;&nbsp;clojure.lang.Seqable
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
036&nbsp;&nbsp;&nbsp;&nbsp;(seq&nbsp;[this]&nbsp;this)
</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;for&nbsp;some&nbsp;reason&nbsp;this&nbsp;marker&nbsp;protocol&nbsp;is&nbsp;needed&nbsp;otherwise&nbsp;compiler&nbsp;complains
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
039&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;that&nbsp;`nth&nbsp;not&nbsp;supported&nbsp;on&nbsp;ConsCell`
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
040&nbsp;&nbsp;&nbsp;&nbsp;clojure.lang.Sequential
</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;clojure.lang.IPersistentCollection
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
043&nbsp;&nbsp;&nbsp;&nbsp;(count&nbsp;[this]&nbsp;(if
</span><br/>
<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;&nbsp;&nbsp;&nbsp;&nbsp;(coll?&nbsp;(.CDR&nbsp;this))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
045&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(inc&nbsp;(.count&nbsp;(.CDR&nbsp;this)))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
046&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
047&nbsp;&nbsp;&nbsp;&nbsp;(empty&nbsp;[this]&nbsp;false)&nbsp;;;&nbsp;a&nbsp;cons&nbsp;cell&nbsp;is&nbsp;by&nbsp;definition&nbsp;not&nbsp;empty.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
048&nbsp;&nbsp;&nbsp;&nbsp;(equiv&nbsp;[this&nbsp;other]&nbsp;(if
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
049&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(seq?&nbsp;other)
</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;(and
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
051&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if
</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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(and
</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;(seq?&nbsp;(first&nbsp;this))
</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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(seq?&nbsp;(first&nbsp;other)))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
055&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(.equiv&nbsp;(first&nbsp;this)&nbsp;(first&nbsp;other))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
056&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(=&nbsp;(first&nbsp;this)&nbsp;(first&nbsp;other)))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
057&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
058&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(and
</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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(seq?&nbsp;(rest&nbsp;this))
</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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(seq?&nbsp;(rest&nbsp;other)))
</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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(.equiv&nbsp;(rest&nbsp;this)&nbsp;(rest&nbsp;other))
</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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(=&nbsp;(rest&nbsp;this)&nbsp;(rest&nbsp;other))))
</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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;false)))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
064&nbsp;&nbsp;
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
065&nbsp;&nbsp;(defn-&nbsp;to-string
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
066&nbsp;&nbsp;&nbsp;&nbsp;&quot;Printing&nbsp;ConsCells&nbsp;gave&nbsp;me&nbsp;a&nbsp;*lot*&nbsp;of&nbsp;trouble.&nbsp;This&nbsp;is&nbsp;an&nbsp;internal&nbsp;function
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
067&nbsp;&nbsp;&nbsp;&nbsp;used&nbsp;by&nbsp;the&nbsp;print-method&nbsp;override&nbsp;(below)&nbsp;in&nbsp;order&nbsp;that&nbsp;the&nbsp;standard&nbsp;Clojure
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
068&nbsp;&nbsp;&nbsp;&nbsp;`print`&nbsp;and&nbsp;`str`&nbsp;functions&nbsp;will&nbsp;print&nbsp;ConsCells&nbsp;correctly.&nbsp;The&nbsp;argument
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
069&nbsp;&nbsp;&nbsp;&nbsp;`cell`&nbsp;must,&nbsp;obviously,&nbsp;be&nbsp;an&nbsp;instance&nbsp;of&nbsp;`ConsCell`.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
070&nbsp;&nbsp;&nbsp;&nbsp;[cell]
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
071&nbsp;&nbsp;&nbsp;&nbsp;(loop&nbsp;[c&nbsp;cell
</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;n&nbsp;0
</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;s&nbsp;&quot;(&quot;]
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
074&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
075&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(instance?&nbsp;beowulf.cons_cell.ConsCell&nbsp;c)
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
076&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[car&nbsp;(.CAR&nbsp;c)
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
077&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cdr&nbsp;(.CDR&nbsp;c)
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
078&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cons?&nbsp;(instance?&nbsp;beowulf.cons_cell.ConsCell&nbsp;cdr)
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
079&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ss&nbsp;(str
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
080&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
081&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(to-string&nbsp;car)
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
082&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cond
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
083&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cons?
</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;&quot;&nbsp;&quot;
</span><br/>
<span class="partial" title="10 out of 11 forms covered">
085&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(or&nbsp;(nil?&nbsp;cdr)&nbsp;(=&nbsp;cdr&nbsp;&#x27;NIL))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
086&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;)&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
087&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="7 out of 7 forms covered">
088&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;.&nbsp;&quot;&nbsp;(to-string&nbsp;cdr)&nbsp;&quot;)&quot;)))]
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
089&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
090&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cons?
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
091&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(recur&nbsp;cdr&nbsp;(inc&nbsp;n)&nbsp;ss)
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
092&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ss))
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
093&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(str&nbsp;c))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
094&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
095&nbsp;&nbsp;(defn&nbsp;pretty-print
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
096&nbsp;&nbsp;&nbsp;&nbsp;&quot;This&nbsp;isn&#x27;t&nbsp;the&nbsp;world&#x27;s&nbsp;best&nbsp;pretty&nbsp;printer&nbsp;but&nbsp;it&nbsp;sort&nbsp;of&nbsp;works.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
097&nbsp;&nbsp;&nbsp;&nbsp;([^beowulf.cons_cell.ConsCell&nbsp;cell]
</span><br/>
<span class="not-covered" title="0 out of 7 forms covered">
098&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(println&nbsp;(pretty-print&nbsp;cell&nbsp;80&nbsp;0)))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
099&nbsp;&nbsp;&nbsp;&nbsp;([^beowulf.cons_cell.ConsCell&nbsp;cell&nbsp;width&nbsp;level]
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
100&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(loop&nbsp;[c&nbsp;cell
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
101&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;n&nbsp;(inc&nbsp;level)
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
102&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s&nbsp;&quot;(&quot;]
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
103&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
104&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(instance?&nbsp;beowulf.cons_cell.ConsCell&nbsp;c)
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
105&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[car&nbsp;(.CAR&nbsp;c)
</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;cdr&nbsp;(.CDR&nbsp;c)
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
107&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cons?&nbsp;(instance?&nbsp;beowulf.cons_cell.ConsCell&nbsp;cdr)
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
108&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print-width&nbsp;(count&nbsp;(print-str&nbsp;c))
</span><br/>
<span class="not-covered" title="0 out of 7 forms covered">
109&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;indent&nbsp;(apply&nbsp;str&nbsp;(repeat&nbsp;n&nbsp;&quot;&nbsp;&nbsp;&quot;))
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
110&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ss&nbsp;(str
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
111&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
112&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(pretty-print&nbsp;car&nbsp;width&nbsp;n)
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
113&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cond
</span><br/>
<span class="not-covered" title="0 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;&nbsp;cons?
</span><br/>
<span class="not-covered" title="0 out of 2 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;(if
</span><br/>
<span class="not-covered" title="0 out of 9 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;(&lt;&nbsp;(+&nbsp;(count&nbsp;indent)&nbsp;print-width)&nbsp;width)
</span><br/>
<span class="not-tracked" title="0 out of 0 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;&quot;&nbsp;&quot;
</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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(str&nbsp;&quot;\n&quot;&nbsp;indent))
</span><br/>
<span class="not-covered" title="0 out of 11 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;(or&nbsp;(nil?&nbsp;cdr)&nbsp;(=&nbsp;cdr&nbsp;&#x27;NIL))
</span><br/>
<span class="not-tracked" title="0 out of 0 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;&quot;)&quot;
</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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:else
</span><br/>
<span class="not-covered" title="0 out of 9 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;(str&nbsp;&quot;&nbsp;.&nbsp;&quot;&nbsp;(pretty-print&nbsp;cdr&nbsp;width&nbsp;n)&nbsp;&quot;)&quot;)))]
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
123&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if
</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;cons?
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
125&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(recur&nbsp;cdr&nbsp;n&nbsp;ss)
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
126&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ss))
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
127&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(str&nbsp;c)))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
128&nbsp;&nbsp;
</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="2 out of 2 forms covered">
131&nbsp;&nbsp;(defmethod&nbsp;clojure.core&#x2F;print-method
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
132&nbsp;&nbsp;&nbsp;&nbsp;;;;&nbsp;I&nbsp;have&nbsp;not&nbsp;worked&nbsp;out&nbsp;how&nbsp;to&nbsp;document&nbsp;defmethod&nbsp;without&nbsp;blowing&nbsp;up&nbsp;the&nbsp;world.
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
133&nbsp;&nbsp;&nbsp;&nbsp;beowulf.cons_cell.ConsCell
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
134&nbsp;&nbsp;&nbsp;&nbsp;[this&nbsp;writer]
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
135&nbsp;&nbsp;&nbsp;&nbsp;(.write&nbsp;writer&nbsp;(to-string&nbsp;this)))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
136&nbsp;&nbsp;
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
137&nbsp;&nbsp;
</span><br/>
<span class="covered" title="17 out of 17 forms covered">
138&nbsp;&nbsp;(defmacro&nbsp;make-cons-cell
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
139&nbsp;&nbsp;&nbsp;&nbsp;&quot;Construct&nbsp;a&nbsp;new&nbsp;instance&nbsp;of&nbsp;cons&nbsp;cell&nbsp;with&nbsp;this&nbsp;`car`&nbsp;and&nbsp;`cdr`.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
140&nbsp;&nbsp;&nbsp;&nbsp;[car&nbsp;cdr]
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
141&nbsp;&nbsp;&nbsp;&nbsp;`(ConsCell.&nbsp;~car&nbsp;~cdr))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
142&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
143&nbsp;&nbsp;(defn&nbsp;make-beowulf-list
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
144&nbsp;&nbsp;&nbsp;&nbsp;&quot;Construct&nbsp;a&nbsp;linked&nbsp;list&nbsp;of&nbsp;cons&nbsp;cells&nbsp;with&nbsp;the&nbsp;same&nbsp;content&nbsp;as&nbsp;the
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
145&nbsp;&nbsp;&nbsp;&nbsp;sequence&nbsp;`x`.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
146&nbsp;&nbsp;&nbsp;&nbsp;[x]
</span><br/>
<span class="partial" title="2 out of 3 forms covered">
147&nbsp;&nbsp;&nbsp;&nbsp;(cond
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
148&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(empty?&nbsp;x)&nbsp;NIL
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
149&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(coll?&nbsp;x)&nbsp;(ConsCell.
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
150&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
151&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(seq?&nbsp;(first&nbsp;x))
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
152&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(make-beowulf-list&nbsp;(first&nbsp;x))
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
153&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(first&nbsp;x))
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
154&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(make-beowulf-list&nbsp;(rest&nbsp;x)))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
155&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:else
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
156&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NIL))
</span><br/>
</body>
</html>

View file

@ -0,0 +1,248 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" href="../coverage.css"/> <title> beowulf/core.clj </title>
</head>
<body>
<span class="covered" title="1 out of 1 forms covered">
001&nbsp;&nbsp;(ns&nbsp;beowulf.core
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
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 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*]]
</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.read&nbsp;:refer&nbsp;[READ]]
</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.java.io&nbsp;:as&nbsp;io]
</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;[clojure.pprint&nbsp;:refer&nbsp;[pprint]]
</span><br/>
<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]]
</span><br/>
<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]])
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
009&nbsp;&nbsp;&nbsp;&nbsp;(:gen-class))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
010&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 class="not-tracked" title="0 out of 0 forms covered">
014&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:default&nbsp;&quot;Sprecan::&quot;]
</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 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;%)))
</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;&quot;Could&nbsp;not&nbsp;find&nbsp;initfile&quot;]]
</span><br/>
<span class="covered" title="4 out of 4 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;]
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
021&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[&quot;-t&quot;&nbsp;&quot;--trace&quot;&nbsp;&quot;Trace&nbsp;Lisp&nbsp;evaluation.&quot;]])
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
022&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 class="covered" title="2 out of 2 forms covered">
028&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(flush)
</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 class="not-tracked" title="0 out of 0 forms covered">
035&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(catch
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
036&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Exception
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
037&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
038&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">
039&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(println&nbsp;(.getMessage&nbsp;e))
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
040&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">
041&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">
042&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">
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 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.
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
045&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">
046&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 3 forms covered">
047&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">
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 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
</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 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))
</span><br/>
<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)
</span><br/>
<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))))
</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 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)]
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
074&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">
075&nbsp;&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">
076&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">
077&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">
078&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 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))
</span><br/>
<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))))))))
</span><br/>
</body>
</html>

View file

@ -0,0 +1,23 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" href="../coverage.css"/> <title> beowulf/host.clj </title>
</head>
<body>
<span class="covered" title="1 out of 1 forms covered">
001&nbsp;&nbsp;(ns&nbsp;beowulf.host
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
002&nbsp;&nbsp;&nbsp;&nbsp;&quot;provides&nbsp;Lisp&nbsp;1.5&nbsp;functions&nbsp;which&nbsp;can&#x27;t&nbsp;be&nbsp;(or&nbsp;can&#x27;t&nbsp;efficiently
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
003&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;be)&nbsp;implemented&nbsp;in&nbsp;Lisp&nbsp;1.5,&nbsp;which&nbsp;therefore&nbsp;need&nbsp;to&nbsp;be&nbsp;implemented&nbsp;in&nbsp;the
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
004&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;host&nbsp;language,&nbsp;in&nbsp;this&nbsp;case&nbsp;Clojure.&quot;)
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
005&nbsp;&nbsp;
</span><br/>
</body>
</html>

View file

@ -0,0 +1,953 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" href="../coverage.css"/> <title> beowulf/read.clj </title>
</head>
<body>
<span class="covered" title="1 out of 1 forms covered">
001&nbsp;&nbsp;(ns&nbsp;beowulf.read
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
002&nbsp;&nbsp;&nbsp;&nbsp;&quot;This&nbsp;provides&nbsp;the&nbsp;reader&nbsp;required&nbsp;for&nbsp;boostrapping.&nbsp;It&#x27;s&nbsp;not&nbsp;a&nbsp;bad
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
003&nbsp;&nbsp;&nbsp;&nbsp;reader&nbsp;-&nbsp;it&nbsp;provides&nbsp;feedback&nbsp;on&nbsp;errors&nbsp;found&nbsp;in&nbsp;the&nbsp;input&nbsp;-&nbsp;but&nbsp;it&nbsp;isn&#x27;t
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
004&nbsp;&nbsp;&nbsp;&nbsp;the&nbsp;real&nbsp;Lisp&nbsp;reader.
</span><br/>
<span class="blank" 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;&nbsp;&nbsp;Intended&nbsp;deviations&nbsp;from&nbsp;the&nbsp;behaviour&nbsp;of&nbsp;the&nbsp;real&nbsp;Lisp&nbsp;reader&nbsp;are&nbsp;as&nbsp;follows:
</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;&nbsp;1.&nbsp;It&nbsp;reads&nbsp;the&nbsp;meta-expression&nbsp;language&nbsp;`MEXPR`&nbsp;in&nbsp;addition&nbsp;to&nbsp;the
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
009&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;symbolic&nbsp;expression&nbsp;language&nbsp;`SEXPR`,&nbsp;which&nbsp;I&nbsp;do&nbsp;not&nbsp;believe&nbsp;the&nbsp;Lisp&nbsp;1.5
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
010&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reader&nbsp;ever&nbsp;did;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
011&nbsp;&nbsp;&nbsp;&nbsp;2.&nbsp;It&nbsp;treats&nbsp;everything&nbsp;between&nbsp;a&nbsp;semi-colon&nbsp;and&nbsp;an&nbsp;end&nbsp;of&nbsp;line&nbsp;as&nbsp;a&nbsp;comment,
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
012&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;as&nbsp;most&nbsp;modern&nbsp;Lisps&nbsp;do;&nbsp;but&nbsp;I&nbsp;do&nbsp;not&nbsp;believe&nbsp;Lisp&nbsp;1.5&nbsp;had&nbsp;this&nbsp;feature.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
013&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
014&nbsp;&nbsp;&nbsp;&nbsp;Both&nbsp;these&nbsp;extensions&nbsp;can&nbsp;be&nbsp;disabled&nbsp;by&nbsp;using&nbsp;the&nbsp;`--strict`&nbsp;command&nbsp;line
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
015&nbsp;&nbsp;&nbsp;&nbsp;switch.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
016&nbsp;&nbsp;&nbsp;&nbsp;(:require&nbsp;[beowulf.bootstrap&nbsp;:refer&nbsp;[*options*]]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
017&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">
018&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[clojure.string&nbsp;:refer&nbsp;[starts-with?&nbsp;upper-case]]
</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;[instaparse.core&nbsp;:as&nbsp;i]
</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.cons-cell&nbsp;:refer&nbsp;[make-beowulf-list&nbsp;make-cons-cell&nbsp;NIL]]))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
021&nbsp;&nbsp;
</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="not-tracked" title="0 out of 0 forms covered">
024&nbsp;&nbsp;;;;&nbsp;This&nbsp;file&nbsp;provides&nbsp;the&nbsp;reader&nbsp;required&nbsp;for&nbsp;boostrapping.&nbsp;It&#x27;s&nbsp;not&nbsp;a&nbsp;bad
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
025&nbsp;&nbsp;;;;&nbsp;reader&nbsp;-&nbsp;it&nbsp;provides&nbsp;feedback&nbsp;on&nbsp;errors&nbsp;found&nbsp;in&nbsp;the&nbsp;input&nbsp;-&nbsp;but&nbsp;it&nbsp;isn&#x27;t
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
026&nbsp;&nbsp;;;;&nbsp;the&nbsp;real&nbsp;Lisp&nbsp;reader.
</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="blank" title="0 out of 0 forms covered">
029&nbsp;&nbsp;
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
030&nbsp;&nbsp;(declare&nbsp;generate)
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
031&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
032&nbsp;&nbsp;(def&nbsp;parse
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
033&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">
034&nbsp;&nbsp;&nbsp;&nbsp;be&nbsp;operated&nbsp;upon&nbsp;further.&quot;
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
035&nbsp;&nbsp;&nbsp;&nbsp;(i&#x2F;parser
</span><br/>
<span class="covered" title="7 out of 7 forms covered">
036&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(str
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
037&nbsp;&nbsp;&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">
038&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;expr&nbsp;:=&nbsp;mexpr&nbsp;|&nbsp;sexpr;&quot;
</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;&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">
041&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;but&nbsp;it&#x27;s&nbsp;a&nbsp;convenience.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
042&nbsp;&nbsp;&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;mexpr&nbsp;comment;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
043&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;λexpr&nbsp;:=&nbsp;λ&nbsp;lsqb&nbsp;bindings&nbsp;semi-colon&nbsp;body&nbsp;rsqb;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
044&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;λ&nbsp;:=&nbsp;&#x27;λ&#x27;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
045&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bindings&nbsp;:=&nbsp;lsqb&nbsp;args&nbsp;rsqb;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
046&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;body&nbsp;:=&nbsp;(expr&nbsp;semi-colon&nbsp;opt-space)*&nbsp;expr;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
047&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fncall&nbsp;:=&nbsp;fn-name&nbsp;lsqb&nbsp;args&nbsp;rsqb;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
048&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">
049&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">
050&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">
051&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cond&nbsp;:=&nbsp;lsqb&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">
052&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cond-clause&nbsp;:=&nbsp;expr&nbsp;opt-space&nbsp;arrow&nbsp;opt-space&nbsp;expr;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
053&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">
054&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;args&nbsp;:=&nbsp;(expr&nbsp;semi-colon&nbsp;opt-space)*&nbsp;expr;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
055&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">
056&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mvar&nbsp;:=&nbsp;#&#x27;[a-z]+&#x27;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
057&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">
058&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
059&nbsp;&nbsp;&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">
060&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;comment&nbsp;:=&nbsp;opt-space&nbsp;&lt;&#x27;;;&#x27;&gt;&nbsp;#&#x27;[^\\n\\r]*&#x27;;&quot;
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
061&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
062&nbsp;&nbsp;&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">
063&nbsp;&nbsp;&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">
064&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;sexpr&nbsp;:=&nbsp;quoted-expr&nbsp;|&nbsp;atom&nbsp;|&nbsp;number&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">
065&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;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
066&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">
067&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">
068&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">
069&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">
070&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">
071&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">
072&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">
073&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">
074&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">
075&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">
076&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">
077&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
078&nbsp;&nbsp;&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">
079&nbsp;&nbsp;&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">
080&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;integer&nbsp;:=&nbsp;#&#x27;-?[1-9][0-9]*&#x27;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
081&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;decimal&nbsp;:=&nbsp;#&#x27;-?[1-9][0-9]*\\.?[0-9]*&#x27;&nbsp;|&nbsp;#&#x27;0.[0-9]*&#x27;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
082&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">
083&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;coefficient&nbsp;:=&nbsp;decimal;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
084&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">
085&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">
086&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">
087&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">
088&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">
089&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
090&nbsp;&nbsp;(defn&nbsp;simplify
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
091&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">
092&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.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
093&nbsp;&nbsp;&nbsp;&nbsp;([p]
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
094&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
095&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(instance?&nbsp;instaparse.gll.Failure&nbsp;p)
</span><br/>
<span class="not-covered" title="0 out of 9 forms covered">
096&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(throw&nbsp;(ex-info&nbsp;&quot;Ic&nbsp;ne&nbsp;behæfd&quot;&nbsp;{:cause&nbsp;:parse-failure&nbsp;:failure&nbsp;p}))
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
097&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(simplify&nbsp;p&nbsp;:sexpr)))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
098&nbsp;&nbsp;&nbsp;&nbsp;([p&nbsp;context]
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
099&nbsp;&nbsp;&nbsp;&nbsp;(if
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
100&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(coll?&nbsp;p)
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
101&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(apply
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
102&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vector
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
103&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(remove
</span><br/>
<span class="covered" title="7 out of 7 forms covered">
104&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#(if&nbsp;(coll?&nbsp;%)&nbsp;(empty?&nbsp;%))
</span><br/>
<span class="partial" title="17 out of 18 forms covered">
105&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(case&nbsp;(first&nbsp;p)
</span><br/>
<span class="partial" title="30 out of 36 forms covered">
106&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:arg&nbsp;:expr&nbsp;:coefficient&nbsp;:fn-name&nbsp;:number&nbsp;:sexpr)&nbsp;(simplify&nbsp;(second&nbsp;p)&nbsp;context)
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
107&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">
108&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;:dot-terminal
</span><br/>
<span class="partial" title="80 out of 88 forms covered">
109&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:fncall&nbsp;:octal&nbsp;:quoted-expr&nbsp;:scientific)&nbsp;(map&nbsp;#(simplify&nbsp;%&nbsp;context)&nbsp;p)
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
110&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:arrow&nbsp;:dot&nbsp;:e&nbsp;:lpar&nbsp;:lsqb&nbsp;:opt-space&nbsp;:q&nbsp;:quote&nbsp;:rpar&nbsp;:rsqb
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
111&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">
112&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:atom&nbsp;(if
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
113&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="covered" title="3 out of 3 forms covered">
114&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">
115&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 1 forms covered">
116&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:comment&nbsp;(if
</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;(:strict&nbsp;*options*)
</span><br/>
<span class="not-covered" title="0 out of 1 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;(throw
</span><br/>
<span class="not-covered" title="0 out of 3 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;(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">
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;{:cause&nbsp;:strict})))
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
121&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 4 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;context&nbsp;:mexpr)
</span><br/>
<span class="not-covered" title="0 out of 2 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;[:fncall
</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;[:mvar&nbsp;&quot;cons&quot;]
</span><br/>
<span class="not-covered" title="0 out of 2 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;[:args
</span><br/>
<span class="not-covered" title="0 out of 7 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;(simplify&nbsp;(nth&nbsp;p&nbsp;1)&nbsp;context)
</span><br/>
<span class="not-covered" title="0 out of 7 forms covered">
127&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&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&nbsp;(nth&nbsp;p&nbsp;2)&nbsp;context)]]
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
128&nbsp;&nbsp;&nbsp;&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&nbsp;p))
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
129&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">
130&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">
131&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">
132&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">
133&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&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="6 out of 6 forms covered">
134&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(simplify&nbsp;(second&nbsp;p)&nbsp;:mexpr))
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
135&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:list&nbsp;(if
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
136&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">
137&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">
138&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">
139&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&nbsp;(rest&nbsp;p)))]]
</span><br/>
<span class="covered" title="8 out of 8 forms covered">
140&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map&nbsp;#(simplify&nbsp;%&nbsp;context)&nbsp;p))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
141&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">
142&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">
143&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p)))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
144&nbsp;&nbsp;
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
145&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
146&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">
147&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">
148&nbsp;&nbsp;;;&nbsp;than&nbsp;reliable.&nbsp;Any&nbsp;typos&nbsp;are&nbsp;mine.&nbsp;Quote&nbsp;starts&nbsp;[[
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
149&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
150&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">
151&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">
152&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">
153&nbsp;&nbsp;;;&nbsp;LISP&nbsp;functions&nbsp;have&nbsp;S-expressions&nbsp;as&nbsp;arguments.&nbsp;In&nbsp;particular,&nbsp;the&nbsp;argument&nbsp;&quot;fn&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
154&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">
155&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">
156&nbsp;&nbsp;;;&nbsp;S-expressions.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
157&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
158&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">
159&nbsp;&nbsp;;;&nbsp;meta-language&nbsp;into&nbsp;S-expressions.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
160&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">
161&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;is
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
162&nbsp;&nbsp;;;&nbsp;&nbsp;&nbsp;&nbsp;translated&nbsp;to&nbsp;CAR.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
163&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">
164&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">
165&nbsp;&nbsp;;;&nbsp;&nbsp;&nbsp;&nbsp;of&nbsp;ε.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
166&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">
167&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">
168&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
169&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">
170&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">
171&nbsp;&nbsp;;;&nbsp;&nbsp;&nbsp;&nbsp;Thus&nbsp;the&nbsp;translation&nbsp;of&nbsp;varl&nbsp;is&nbsp;VAR1.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
172&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">
173&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">
174&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">
175&nbsp;&nbsp;;;&nbsp;&nbsp;&nbsp;&nbsp;into&nbsp;(QUOTE&nbsp;X).
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
176&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">
177&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">
178&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">
179&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
180&nbsp;&nbsp;;;&nbsp;##&nbsp;Examples
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
181&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
182&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;S-expressions
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
183&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;X
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
184&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;CAR
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
185&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;(CAR&nbsp;X)
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
186&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;(QUOTE&nbsp;T)
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
187&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;(FF&nbsp;(CAR&nbsp;X))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
188&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;(COND&nbsp;((ATOM&nbsp;X)&nbsp;X)
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
189&nbsp;&nbsp;;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&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">
190&nbsp;&nbsp;;;&nbsp;label[ff;λ[[x];[atom[x]-&gt;x;&nbsp;T-&gt;ff[car[x]]]]]&nbsp;(LABEL&nbsp;FF&nbsp;(LAMBDA&nbsp;(X)&nbsp;(COND
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
191&nbsp;&nbsp;;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;((ATOM&nbsp;X)&nbsp;X)
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
192&nbsp;&nbsp;;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&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="blank" title="0 out of 0 forms covered">
193&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
194&nbsp;&nbsp;;;&nbsp;]]&nbsp;quote&nbsp;ends
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
195&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
196&nbsp;&nbsp;(defn&nbsp;gen-cond-clause
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
197&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">
198&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">
199&nbsp;&nbsp;&nbsp;&nbsp;[p]
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
200&nbsp;&nbsp;&nbsp;&nbsp;(if
</span><br/>
<span class="partial" title="12 out of 13 forms covered">
201&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(and&nbsp;(coll?&nbsp;p)(=&nbsp;:cond-clause&nbsp;(first&nbsp;p)))
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
202&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(make-beowulf-list
</span><br/>
<span class="covered" title="8 out of 8 forms covered">
203&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(list&nbsp;(generate&nbsp;(nth&nbsp;p&nbsp;1))
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
204&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))))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
205&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
206&nbsp;&nbsp;(defn&nbsp;gen-cond
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
207&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">
208&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">
209&nbsp;&nbsp;&nbsp;&nbsp;[p]
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
210&nbsp;&nbsp;&nbsp;&nbsp;(if
</span><br/>
<span class="partial" title="12 out of 13 forms covered">
211&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(and&nbsp;(coll?&nbsp;p)(=&nbsp;:cond&nbsp;(first&nbsp;p)))
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
212&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(make-beowulf-list
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
213&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cons
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
214&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#x27;COND
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
215&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
216&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;gen-cond-clause
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
217&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(rest&nbsp;p))))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
218&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
219&nbsp;&nbsp;(defn&nbsp;gen-fn-call
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
220&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">
221&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">
222&nbsp;&nbsp;&nbsp;&nbsp;[p]
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
223&nbsp;&nbsp;&nbsp;&nbsp;(if
</span><br/>
<span class="partial" title="23 out of 25 forms covered">
224&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(and&nbsp;(coll?&nbsp;p)(=&nbsp;:fncall&nbsp;(first&nbsp;p))(=&nbsp;:mvar&nbsp;(first&nbsp;(second&nbsp;p))))
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
225&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(make-cons-cell
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
226&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(generate&nbsp;(second&nbsp;p))
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
227&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(generate&nbsp;(nth&nbsp;p&nbsp;2)))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
228&nbsp;&nbsp;
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
229&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
230&nbsp;&nbsp;(defn&nbsp;gen-dot-terminated-list
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
231&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">
232&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">
233&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">
234&nbsp;&nbsp;&nbsp;&nbsp;[p]
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
235&nbsp;&nbsp;&nbsp;&nbsp;(cond
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
236&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(empty?&nbsp;p)
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
237&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NIL
</span><br/>
<span class="partial" title="16 out of 17 forms covered">
238&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">
239&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[dt&nbsp;(first&nbsp;p)]
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
240&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(make-cons-cell
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
241&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(generate&nbsp;(nth&nbsp;dt&nbsp;1))
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
242&nbsp;&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">
243&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:else
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
244&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(make-cons-cell
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
245&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(generate&nbsp;(first&nbsp;p))
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
246&nbsp;&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">
247&nbsp;&nbsp;
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
248&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
249&nbsp;&nbsp;(defn&nbsp;strip-leading-zeros
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
250&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">
251&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">
252&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">
253&nbsp;&nbsp;&nbsp;&nbsp;([s]
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
254&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">
255&nbsp;&nbsp;&nbsp;&nbsp;([s&nbsp;prefix]
</span><br/>
<span class="partial" title="1 out of 2 forms covered">
256&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
257&nbsp;&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">
258&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(case&nbsp;(first&nbsp;s)
</span><br/>
<span class="partial" title="12 out of 24 forms covered">
259&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">
260&nbsp;&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">
261&nbsp;&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">
262&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
263&nbsp;&nbsp;(defn&nbsp;generate
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
264&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">
265&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">
266&nbsp;&nbsp;&nbsp;&nbsp;[p]
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
267&nbsp;&nbsp;&nbsp;&nbsp;(if
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
268&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(coll?&nbsp;p)
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
269&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(case&nbsp;(first&nbsp;p)
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
270&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;LAMBDA&quot;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
271&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">
272&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(generate&nbsp;(nth&nbsp;p&nbsp;1))
</span><br/>
<span class="covered" title="7 out of 7 forms covered">
273&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))
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
274&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&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))))
</span><br/>
<span class="covered" title="10 out of 10 forms covered">
275&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:args&nbsp;:list)&nbsp;(gen-dot-terminated-list&nbsp;(rest&nbsp;p))
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
276&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:atom&nbsp;(symbol&nbsp;(second&nbsp;p))
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
277&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:bindings&nbsp;(generate&nbsp;(second&nbsp;p))
</span><br/>
<span class="covered" title="8 out of 8 forms covered">
278&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:body&nbsp;(make-beowulf-list&nbsp;(map&nbsp;generate&nbsp;(rest&nbsp;p)))
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
279&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:cond&nbsp;(gen-cond&nbsp;p)
</span><br/>
<span class="covered" title="14 out of 14 forms covered">
280&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:decimal&nbsp;:integer)&nbsp;(read-string&nbsp;(strip-leading-zeros&nbsp;(second&nbsp;p)))
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
281&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">
282&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))
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
283&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)))
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
284&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:exponent&nbsp;(generate&nbsp;(second&nbsp;p))
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
285&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:fncall&nbsp;(gen-fn-call&nbsp;p)
</span><br/>
<span class="covered" title="7 out of 7 forms covered">
286&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:mvar&nbsp;(symbol&nbsp;(upper-case&nbsp;(second&nbsp;p)))
</span><br/>
<span class="covered" title="9 out of 9 forms covered">
287&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">
288&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;2))]
</span><br/>
<span class="covered" title="7 out of 7 forms covered">
289&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">
290&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
291&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="10 out of 10 forms covered">
292&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))))
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
293&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:scale-factor&nbsp;(if
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
294&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">
295&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="6 out of 6 forms covered">
296&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:scientific&nbsp;(let&nbsp;[n&nbsp;(generate&nbsp;(second&nbsp;p))
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
297&nbsp;&nbsp;&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;2))]
</span><br/>
<span class="covered" title="7 out of 7 forms covered">
298&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="blank" title="0 out of 0 forms covered">
299&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
300&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;default
</span><br/>
<span class="not-covered" title="0 out of 8 forms covered">
301&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(throw&nbsp;(Exception.&nbsp;(str&nbsp;&quot;Cannot&nbsp;yet&nbsp;generate&nbsp;&quot;&nbsp;(first&nbsp;p)))))
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
302&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
303&nbsp;&nbsp;
</span><br/>
<span class="covered" title="40 out of 40 forms covered">
304&nbsp;&nbsp;(defmacro&nbsp;gsp
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
305&nbsp;&nbsp;&nbsp;&nbsp;&quot;Shortcut&nbsp;macro&nbsp;-&nbsp;the&nbsp;internals&nbsp;of&nbsp;read;&nbsp;or,&nbsp;if&nbsp;you&nbsp;like,&nbsp;read-string.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
306&nbsp;&nbsp;&nbsp;&nbsp;Argument&nbsp;`s`&nbsp;should&nbsp;be&nbsp;a&nbsp;string&nbsp;representation&nbsp;of&nbsp;a&nbsp;valid&nbsp;Lisp
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
307&nbsp;&nbsp;&nbsp;&nbsp;expression.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
308&nbsp;&nbsp;&nbsp;&nbsp;[s]
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
309&nbsp;&nbsp;&nbsp;&nbsp;`(generate&nbsp;(simplify&nbsp;(parse&nbsp;~s))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
310&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
311&nbsp;&nbsp;(defn&nbsp;READ
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
312&nbsp;&nbsp;&nbsp;&nbsp;&quot;An&nbsp;implementation&nbsp;of&nbsp;a&nbsp;Lisp&nbsp;reader&nbsp;sufficient&nbsp;for&nbsp;bootstrapping;&nbsp;not&nbsp;necessarily
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
313&nbsp;&nbsp;&nbsp;&nbsp;the&nbsp;final&nbsp;Lisp&nbsp;reader.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
314&nbsp;&nbsp;&nbsp;&nbsp;[input]
</span><br/>
<span class="partial" title="8 out of 10 forms covered">
315&nbsp;&nbsp;&nbsp;&nbsp;(gsp&nbsp;(or&nbsp;input&nbsp;(read-line))))
</span><br/>
</body>
</html>

View file

@ -0,0 +1,40 @@
.covered {
font-family: 'Bitstream Vera Sans Mono', 'Courier', monospace;
background-color: #558B55;
}
.not-covered {
font-family: 'Bitstream Vera Sans Mono', 'Courier', monospace;
background-color: red;
}
.partial {
font-family: 'Bitstream Vera Sans Mono', 'Courier', monospace;
background-color: orange;
}
.not-tracked {
font-family: 'Bitstream Vera Sans Mono', 'Courier', monospace;
}
.blank {
font-family: 'Bitstream Vera Sans Mono', 'Courier', monospace;
}
td {
padding-right: 10px;
}
td.with-bar {
width: 250px;
text-align: center;
}
td.with-number {
text-align: right;
}
td.ns-name {
min-width: 150px;
padding-right: 25px;
}

104
docs/cloverage/index.html Normal file
View file

@ -0,0 +1,104 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" href="./coverage.css"/>
<title>Coverage Summary</title>
</head>
<body>
<table>
<thead><tr>
<td class="ns-name"> Namespace </td>
<td class="with-bar"> Forms </td>
<td class="with-number">Forms %</td>
<td class="with-bar"> Lines </td>
<td class="with-number">Lines %</td>
<td class="with-number">Total</td><td class="with-number">Blank</td><td class="with-number">Instrumented</td>
</tr></thead>
<tr>
<td><a href="beowulf/bootstrap.clj.html">beowulf.bootstrap</a></td><td class="with-bar"><div class="covered"
style="width:67.4439461883408%;
float:left;"> 752 </div><div class="not-covered"
style="width:32.55605381165919%;
float:left;"> 363 </div></td>
<td class="with-number">67.44 %</td>
<td class="with-bar"><div class="covered"
style="width:58.52272727272727%;
float:left;"> 103 </div><div class="partial"
style="width:23.295454545454547%;
float:left;"> 41 </div><div class="not-covered"
style="width:18.181818181818183%;
float:left;"> 32 </div></td>
<td class="with-number">81.82 %</td>
<td class="with-number">338</td><td class="with-number">40</td><td class="with-number">176</td>
</tr>
<tr>
<td><a href="beowulf/cons_cell.clj.html">beowulf.cons-cell</a></td><td class="with-bar"><div class="covered"
style="width:56.82819383259912%;
float:left;"> 129 </div><div class="not-covered"
style="width:43.17180616740088%;
float:left;"> 98 </div></td>
<td class="with-number">56.83 %</td>
<td class="with-bar"><div class="covered"
style="width:57.35294117647059%;
float:left;"> 39 </div><div class="partial"
style="width:4.411764705882353%;
float:left;"> 3 </div><div class="not-covered"
style="width:38.23529411764706%;
float:left;"> 26 </div></td>
<td class="with-number">61.76 %</td>
<td class="with-number">156</td><td class="with-number">15</td><td class="with-number">68</td>
</tr>
<tr>
<td><a href="beowulf/core.clj.html">beowulf.core</a></td><td class="with-bar"><div class="covered"
style="width:90.9090909090909%;
float:left;"> 170 </div><div class="not-covered"
style="width:9.090909090909092%;
float:left;"> 17 </div></td>
<td class="with-number">90.91 %</td>
<td class="with-bar"><div class="covered"
style="width:87.75510204081633%;
float:left;"> 43 </div><div class="partial"
style="width:2.0408163265306123%;
float:left;"> 1 </div><div class="not-covered"
style="width:10.204081632653061%;
float:left;"> 5 </div></td>
<td class="with-number">89.80 %</td>
<td class="with-number">80</td><td class="with-number">3</td><td class="with-number">49</td>
</tr>
<tr>
<td><a href="beowulf/host.clj.html">beowulf.host</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">5</td><td class="with-number">1</td><td class="with-number">1</td>
</tr>
<tr>
<td><a href="beowulf/read.clj.html">beowulf.read</a></td><td class="with-bar"><div class="covered"
style="width:81.8941504178273%;
float:left;"> 588 </div><div class="not-covered"
style="width:18.105849582172702%;
float:left;"> 130 </div></td>
<td class="with-number">81.89 %</td>
<td class="with-bar"><div class="covered"
style="width:73.80952380952381%;
float:left;"> 93 </div><div class="partial"
style="width:7.936507936507937%;
float:left;"> 10 </div><div class="not-covered"
style="width:18.253968253968253%;
float:left;"> 23 </div></td>
<td class="with-number">81.75 %</td>
<td class="with-number">315</td><td class="with-number">31</td><td class="with-number">126</td>
</tr>
<tr><td>Totals:</td>
<td class="with-bar"></td>
<td class="with-number">72.95 %</td>
<td class="with-bar"></td>
<td class="with-number">79.52 %</td>
</tr>
</table>
</body>
</html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,3 @@
<!DOCTYPE html PUBLIC ""
"">
<html><head><meta charset="UTF-8" /><title>beowulf.core documentation</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Beowulf</span> <span class="project-version">0.2.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 "><a href="intro.html"><div class="inner"><span>Introduction to beowulf</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 current"><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.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"><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></ul></div><div class="sidebar secondary"><h3><a href="#top"><span class="inner">Public Vars</span></a></h3><ul><li class="depth-1"><a href="beowulf.core.html#var--main"><div class="inner"><span>-main</span></div></a></li><li class="depth-1"><a href="beowulf.core.html#var-cli-options"><div class="inner"><span>cli-options</span></div></a></li><li class="depth-1"><a href="beowulf.core.html#var-repl"><div class="inner"><span>repl</span></div></a></li></ul></div><div class="namespace-docs" id="content"><h1 class="anchor" id="top">beowulf.core</h1><div class="doc"><div class="markdown"><p>Essentially, the <code>-main</code> function and the bootstrap read-eval-print loop.</p></div></div><div class="public anchor" id="var--main"><h3>-main</h3><div class="usage"><code>(-main &amp; opts)</code></div><div class="doc"><div class="markdown"><p>Parse options, print the banner, read the init file if any, and enter the read/eval/print loop.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/beowulf/blob/master/src/beowulf/core.clj#L50">view source</a></div></div><div class="public anchor" id="var-cli-options"><h3>cli-options</h3><div class="usage"></div><div class="doc"><div class="markdown"><p><strong>TODO</strong>: write docs</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/beowulf/blob/master/src/beowulf/core.clj#L11">view source</a></div></div><div class="public anchor" id="var-repl"><h3>repl</h3><div class="usage"><code>(repl prompt)</code></div><div class="doc"><div class="markdown"><p>Read/eval/print loop.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/beowulf/blob/master/src/beowulf/core.clj#L23">view source</a></div></div></div></body></html>

View file

@ -0,0 +1,3 @@
<!DOCTYPE html PUBLIC ""
"">
<html><head><meta charset="UTF-8" /><title>beowulf.host documentation</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Beowulf</span> <span class="project-version">0.2.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 "><a href="intro.html"><div class="inner"><span>Introduction to beowulf</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 current"><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"><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></ul></div><div class="sidebar secondary"><h3><a href="#top"><span class="inner">Public Vars</span></a></h3><ul></ul></div><div class="namespace-docs" id="content"><h1 class="anchor" id="top">beowulf.host</h1><div class="doc"><div class="markdown"><p>provides Lisp 1.5 functions which cant be (or cant efficiently be) implemented in Lisp 1.5, which therefore need to be implemented in the host language, in this case Clojure.</p></div></div></div></body></html>

View file

@ -0,0 +1,9 @@
<!DOCTYPE html PUBLIC ""
"">
<html><head><meta charset="UTF-8" /><title>beowulf.read documentation</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Beowulf</span> <span class="project-version">0.2.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 "><a href="intro.html"><div class="inner"><span>Introduction to beowulf</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.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 current"><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></ul></div><div class="sidebar secondary"><h3><a href="#top"><span class="inner">Public Vars</span></a></h3><ul><li class="depth-1"><a href="beowulf.read.html#var-gen-cond"><div class="inner"><span>gen-cond</span></div></a></li><li class="depth-1"><a href="beowulf.read.html#var-gen-cond-clause"><div class="inner"><span>gen-cond-clause</span></div></a></li><li class="depth-1"><a href="beowulf.read.html#var-gen-dot-terminated-list"><div class="inner"><span>gen-dot-terminated-list</span></div></a></li><li class="depth-1"><a href="beowulf.read.html#var-gen-fn-call"><div class="inner"><span>gen-fn-call</span></div></a></li><li class="depth-1"><a href="beowulf.read.html#var-generate"><div class="inner"><span>generate</span></div></a></li><li class="depth-1"><a href="beowulf.read.html#var-gsp"><div class="inner"><span>gsp</span></div></a></li><li class="depth-1"><a href="beowulf.read.html#var-parse"><div class="inner"><span>parse</span></div></a></li><li class="depth-1"><a href="beowulf.read.html#var-READ"><div class="inner"><span>READ</span></div></a></li><li class="depth-1"><a href="beowulf.read.html#var-simplify"><div class="inner"><span>simplify</span></div></a></li><li class="depth-1"><a href="beowulf.read.html#var-strip-leading-zeros"><div class="inner"><span>strip-leading-zeros</span></div></a></li></ul></div><div class="namespace-docs" id="content"><h1 class="anchor" id="top">beowulf.read</h1><div class="doc"><div class="markdown"><p>This provides the reader required for boostrapping. Its not a bad reader - it provides feedback on errors found in the input - but it isnt the real Lisp reader.</p>
<p>Intended deviations from the behaviour of the real Lisp reader are as follows:</p>
<ol>
<li>It reads the meta-expression language <code>MEXPR</code> in addition to the symbolic expression language <code>SEXPR</code>, which I do not believe the Lisp 1.5 reader ever did;</li>
<li>It treats everything between a semi-colon and an end of line as a comment, as most modern Lisps do; but I do not believe Lisp 1.5 had this feature.</li>
</ol>
<p>Both these extensions can be disabled by using the <code>--strict</code> command line switch.</p></div></div><div class="public anchor" id="var-gen-cond"><h3>gen-cond</h3><div class="usage"><code>(gen-cond p)</code></div><div class="doc"><div class="markdown"><p>Generate a cond statement from this simplified parse tree fragment <code>p</code>; returns <code>nil</code> if <code>p</code> does not represent a (MEXPR) cond statement.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/beowulf/blob/master/src/beowulf/read.clj#L206">view source</a></div></div><div class="public anchor" id="var-gen-cond-clause"><h3>gen-cond-clause</h3><div class="usage"><code>(gen-cond-clause p)</code></div><div class="doc"><div class="markdown"><p>Generate a cond clause from this simplified parse tree fragment <code>p</code>; returns <code>nil</code> if <code>p</code> does not represent a cond clause.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/beowulf/blob/master/src/beowulf/read.clj#L196">view source</a></div></div><div class="public anchor" id="var-gen-dot-terminated-list"><h3>gen-dot-terminated-list</h3><div class="usage"><code>(gen-dot-terminated-list p)</code></div><div class="doc"><div class="markdown"><p>Generate a list, which may be dot-terminated, from this partial parse tree p. Note that the function acts recursively and progressively decapitates its argument, so that the argument will not always be a valid parse tree.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/beowulf/blob/master/src/beowulf/read.clj#L230">view source</a></div></div><div class="public anchor" id="var-gen-fn-call"><h3>gen-fn-call</h3><div class="usage"><code>(gen-fn-call p)</code></div><div class="doc"><div class="markdown"><p>Generate a function call from this simplified parse tree fragment <code>p</code>; returns <code>nil</code> if <code>p</code> does not represent a (MEXPR) function call.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/beowulf/blob/master/src/beowulf/read.clj#L219">view source</a></div></div><div class="public anchor" id="var-generate"><h3>generate</h3><div class="usage"><code>(generate p)</code></div><div class="doc"><div class="markdown"><p>Generate lisp structure from this parse tree <code>p</code>. It is assumed that <code>p</code> has been simplified.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/beowulf/blob/master/src/beowulf/read.clj#L263">view source</a></div></div><div class="public anchor" id="var-gsp"><h3>gsp</h3><h4 class="type">macro</h4><div class="usage"><code>(gsp s)</code></div><div class="doc"><div class="markdown"><p>Shortcut macro - the internals of read; or, if you like, read-string. Argument <code>s</code> should be a string representation of a valid Lisp expression.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/beowulf/blob/master/src/beowulf/read.clj#L304">view source</a></div></div><div class="public anchor" id="var-parse"><h3>parse</h3><div class="usage"></div><div class="doc"><div class="markdown"><p>Parse a string presented as argument into a parse tree which can then be operated upon further.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/beowulf/blob/master/src/beowulf/read.clj#L32">view source</a></div></div><div class="public anchor" id="var-READ"><h3>READ</h3><div class="usage"><code>(READ input)</code></div><div class="doc"><div class="markdown"><p>An implementation of a Lisp reader sufficient for bootstrapping; not necessarily the final Lisp reader.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/beowulf/blob/master/src/beowulf/read.clj#L311">view source</a></div></div><div class="public anchor" id="var-simplify"><h3>simplify</h3><div class="usage"><code>(simplify p)</code><code>(simplify p context)</code></div><div class="doc"><div class="markdown"><p>Simplify this parse tree <code>p</code>. If <code>p</code> is an instaparse failure object, throw an <code>ex-info</code>, with <code>p</code> as the value of its <code>:failure</code> key.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/beowulf/blob/master/src/beowulf/read.clj#L90">view source</a></div></div><div class="public anchor" id="var-strip-leading-zeros"><h3>strip-leading-zeros</h3><div class="usage"><code>(strip-leading-zeros s)</code><code>(strip-leading-zeros s prefix)</code></div><div class="doc"><div class="markdown"><p><code>read-string</code> interprets strings with leading zeros as octal; strip any from this string <code>s</code>. If whats left is empty (i.e. there were only zeros, return <code>"0"</code>.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/beowulf/blob/master/src/beowulf/read.clj#L249">view source</a></div></div></div></body></html>

551
docs/codox/css/default.css Normal file
View file

@ -0,0 +1,551 @@
body {
font-family: Helvetica, Arial, sans-serif;
font-size: 15px;
}
pre, code {
font-family: Monaco, DejaVu Sans Mono, Consolas, monospace;
font-size: 9pt;
margin: 15px 0;
}
h1 {
font-weight: normal;
font-size: 29px;
margin: 10px 0 2px 0;
padding: 0;
}
h2 {
font-weight: normal;
font-size: 25px;
}
h5.license {
margin: 9px 0 22px 0;
color: #555;
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: #f5f5f5;
padding: 5px 7px;
}
#content {
top: 32px;
right: 0;
bottom: 0;
overflow: auto;
background: #fff;
color: #333;
padding: 0 18px;
}
.sidebar {
position: fixed;
top: 32px;
bottom: 0;
overflow: auto;
}
.sidebar.primary {
background: #e2e2e2;
border-right: solid 1px #cccccc;
left: 0;
width: 250px;
}
.sidebar.secondary {
background: #f2f2f2;
border-right: solid 1px #d7d7d7;
left: 251px;
width: 200px;
}
#content.namespace-index, #content.document {
left: 251px;
}
#content.namespace-docs {
left: 452px;
}
#content.document {
padding-bottom: 10%;
}
#header {
background: #3f3f3f;
box-shadow: 0 0 8px rgba(0, 0, 0, 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 a {
color: #f5f5f5;
}
.sidebar a {
color: #333;
}
#header h2 {
float: right;
font-size: 9pt;
font-weight: normal;
margin: 4px 3px;
padding: 0;
color: #bbb;
}
#header h2 a {
display: inline;
}
.sidebar h3 {
margin: 0;
padding: 10px 13px 0 13px;
font-size: 19px;
font-weight: lighter;
}
.sidebar h3 a {
color: #444;
}
.sidebar h3.no-link {
color: #636363;
}
.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: #777;
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 #aaa;
border-bottom: 1px solid #aaa;
height: 19px;
}
.sidebar li .tree .bottom {
height: 22px;
}
.sidebar li.branch .tree .bottom {
border-left: 1px solid #aaa;
}
.sidebar.primary li.current a {
border-left: 3px solid #a33;
color: #a33;
}
.sidebar.secondary li.current a {
border-left: 3px solid #33a;
color: #33a;
}
.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 #e0e0e0;
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: #555;
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 #bbb;
}
#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: #508820;
}
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: #088;
}
.type-sig pre {
padding-top: 10px;
margin: 0;
}
.usage code {
display: block;
color: #008;
margin: 2px 0;
}
.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 #e4e4e4;
border-radius: 2px;
}
.markdown code:not(.hljs), .src-link a {
background: #f6f6f6;
}
pre.deps {
display: inline-block;
margin: 0 10px;
border: 1px solid #e4e4e4;
border-radius: 2px;
padding: 10px;
background-color: #f6f6f6;
}
.markdown hr {
border-style: solid;
border-top: none;
color: #ccc;
}
.doc ul, .doc ol {
padding-left: 30px;
}
.doc table {
border-collapse: collapse;
margin: 0 10px;
}
.doc table td, .doc table th {
border: 1px solid #dddddd;
padding: 4px 6px;
}
.doc table th {
background: #f2f2f2;
}
.doc dl {
margin: 0 10px 20px 10px;
}
.doc dl dt {
font-weight: bold;
margin: 0;
padding: 3px 0;
border-bottom: 1px solid #ddd;
}
.doc dl dd {
padding: 5px 0;
margin: 0 0 5px 10px;
}
.doc abbr {
border-bottom: 1px dotted #333;
font-variant: none;
cursor: help;
}
.src-link {
margin-bottom: 15px;
}
.src-link a {
font-size: 70%;
padding: 1px 4px;
text-decoration: none;
color: #5555bb;
}

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;
}

3
docs/codox/index.html Normal file

File diff suppressed because one or more lines are too long

4
docs/codox/intro.html Normal file
View file

@ -0,0 +1,4 @@
<!DOCTYPE html PUBLIC ""
"">
<html><head><meta charset="UTF-8" /><title>Introduction to beowulf</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Beowulf</span> <span class="project-version">0.2.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="intro.html"><div class="inner"><span>Introduction to beowulf</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.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"><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></ul></div><div class="document" id="content"><div class="doc"><div class="markdown"><h1><a href="#introduction-to-beowulf" name="introduction-to-beowulf"></a>Introduction to beowulf</h1>
<p>TODO: write <a href="http://jacobian.org/writing/what-to-write/">great documentation</a></p></div></div></div></body></html>

2
docs/codox/js/highlight.min.js vendored Normal file

File diff suppressed because one or more lines are too long

4
docs/codox/js/jquery.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,112 @@
function visibleInParent(element) {
var position = $(element).position().top
return position > -50 && position < ($(element).offsetParent().height() - 50)
}
function hasFragment(link, fragment) {
return $(link).attr("href").indexOf("#" + fragment) != -1
}
function findLinkByFragment(elements, fragment) {
return $(elements).filter(function(i, e) { return hasFragment(e, fragment)}).first()
}
function scrollToCurrentVarLink(elements) {
var elements = $(elements);
var parent = elements.offsetParent();
if (elements.length == 0) return;
var top = elements.first().position().top;
var bottom = elements.last().position().top + elements.last().height();
if (top >= 0 && bottom <= parent.height()) return;
if (top < 0) {
parent.scrollTop(parent.scrollTop() + top);
}
else if (bottom > parent.height()) {
parent.scrollTop(parent.scrollTop() + bottom - parent.height());
}
}
function setCurrentVarLink() {
$('.secondary a').parent().removeClass('current')
$('.anchor').
filter(function(index) { return visibleInParent(this) }).
each(function(index, element) {
findLinkByFragment(".secondary a", element.id).
parent().
addClass('current')
});
scrollToCurrentVarLink('.secondary .current');
}
var hasStorage = (function() { try { return localStorage.getItem } catch(e) {} }())
function scrollPositionId(element) {
var directory = window.location.href.replace(/[^\/]+\.html$/, '')
return 'scroll::' + $(element).attr('id') + '::' + directory
}
function storeScrollPosition(element) {
if (!hasStorage) return;
localStorage.setItem(scrollPositionId(element) + "::x", $(element).scrollLeft())
localStorage.setItem(scrollPositionId(element) + "::y", $(element).scrollTop())
}
function recallScrollPosition(element) {
if (!hasStorage) return;
$(element).scrollLeft(localStorage.getItem(scrollPositionId(element) + "::x"))
$(element).scrollTop(localStorage.getItem(scrollPositionId(element) + "::y"))
}
function persistScrollPosition(element) {
recallScrollPosition(element)
$(element).scroll(function() { storeScrollPosition(element) })
}
function sidebarContentWidth(element) {
var widths = $(element).find('.inner').map(function() { return $(this).innerWidth() })
return Math.max.apply(Math, widths)
}
function calculateSize(width, snap, margin, minimum) {
if (width == 0) {
return 0
}
else {
return Math.max(minimum, (Math.ceil(width / snap) * snap) + (margin * 2))
}
}
function resizeSidebars() {
var primaryWidth = sidebarContentWidth('.primary')
var secondaryWidth = 0
if ($('.secondary').length != 0) {
secondaryWidth = sidebarContentWidth('.secondary')
}
// snap to grid
primaryWidth = calculateSize(primaryWidth, 32, 13, 160)
secondaryWidth = calculateSize(secondaryWidth, 32, 13, 160)
$('.primary').css('width', primaryWidth)
$('.secondary').css('width', secondaryWidth).css('left', primaryWidth + 1)
if (secondaryWidth > 0) {
$('#content').css('left', primaryWidth + secondaryWidth + 2)
}
else {
$('#content').css('left', primaryWidth + 1)
}
}
$(window).ready(resizeSidebars)
$(window).ready(setCurrentVarLink)
$(window).ready(function() { persistScrollPosition('.primary')})
$(window).ready(function() {
$('#content').scroll(setCurrentVarLink)
$(window).resize(setCurrentVarLink)
})

View file

@ -1,14 +1,34 @@
(defproject beowulf "0.1.0-SNAPSHOT"
(defproject beowulf "0.2.1-SNAPSHOT"
:cloverage {:output "docs/cloverage"}
:codox {:metadata {:doc "**TODO**: write docs"
:doc/format :markdown}
:output-path "docs/codox"
:source-uri "https://github.com/simon-brooke/beowulf/blob/master/{filepath}#L{line}"}
:description "An implementation of LISP 1.5 in Clojure"
:url "http://example.com/FIXME"
:license {:name "GPL-2.0-or-later"
:url "https://www.eclipse.org/legal/epl-2.0/"}
:dependencies [[org.clojure/clojure "1.8.0"]
[org.clojure/math.numeric-tower "0.0.4"]
[org.clojure/tools.cli "0.4.2"]
[org.clojure/tools.trace "0.7.10"]
[environ "1.1.0"]
[instaparse "1.4.10"]]
:main ^:skip-aot beowulf.core
:plugins [[lein-environ "1.1.0"]]
:plugins [[lein-cloverage "1.1.1"]
[lein-codox "0.10.7"]
[lein-environ "1.1.0"]]
:profiles {:uberjar {:aot :all}}
:release-tasks [["vcs" "assert-committed"]
["change" "version" "leiningen.release/bump-version" "release"]
["vcs" "commit"]
["vcs" "tag" "v." "--no-sign"]
["clean"]
["codox"]
["cloverage"]
["uberjar"]
["change" "version" "leiningen.release/bump-version"]
["vcs" "commit"]]
:target-path "target/%s"
:profiles {:uberjar {:aot :all}})
:url "https://github.com/simon-brooke/the-great-game"
)

0
resources/lisp1.5.lsp Normal file
View file

View file

@ -1,30 +1,55 @@
(ns beowulf.eval
(ns beowulf.bootstrap
"Lisp as defined in Chapter 1 (pages 1-14) of the
`Lisp 1.5 Programmer's Manual`; that is to say, a very simple Lisp language,
which should, I believe, be sufficient in conjunction with the functions
provided by `beowulf.host`, be sufficient to bootstrap the full Lisp 1.5
interpreter..
The convention is adopted that functions in this file with names in
ALLUPPERCASE are Lisp 1.5 functions (although written in Clojure) and that
therefore all arguments must be numbers, symbols or `beowulf.cons_cell.ConsCell`
objects."
(:require [clojure.tools.trace :refer :all]
[beowulf.cons-cell :refer [make-beowulf-list make-cons-cell NIL T F]]))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;
;;; This file is essentially Lisp as defined in Chapter 1 (pages 1-14) of the
;;; Lisp 1.5 Programmer's Manual; that is to say, a very simple Lisp language,
;;; which should, I believe, be sufficient in conjunction with the functions
;;; provided by `beowulf.host`, be sufficient to bootstrap the full Lisp 1.5
;;; interpreter.
;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(declare EVAL)
(def oblist
"The default environment; modified certainly be `LABEL` (which seems to
be Lisp 1.5's EQuivalent of `SETQ`), possibly by other things."
"The default environment."
(atom NIL))
(defn NULL
[x]
(if (= x NIL) 'T 'F))
(def ^:dynamic *options*
"Command line options from invocation."
{})
(defn ATOM
"It is not clear to me from the documentation whether `(ATOM 7)` should return
`'T` or `'F`. I'm going to assume `'T`."
(defmacro NULL
"Returns `T` if and only if the argument `x` is bound to `NIL`; else `F`."
[x]
(if (or (symbol? x) (number? x)) 'T 'F))
`(if (= ~x NIL) T F))
(defn ATOM?
"The convention of returning `'F` from predicates, rather than `NIL`, is going
(defmacro ATOM
"Returns `T` if and only is the argument `x` is bound to and 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`."
[x]
`(if (or (symbol? ~x) (number? ~x)) T F))
(defmacro ATOM?
"The convention of returning `F` from predicates, rather than `NIL`, is going
to tie me in knots. This is a variant of `ATOM` which returns `NIL`
on failure."
[x]
(if (or (symbol? x) (number? x)) 'T NIL))
`(if (or (symbol? ~x) (number? ~x)) T NIL))
(defn CAR
"Return the item indicated by the first pointer of a pair. NIL is treated
@ -94,10 +119,10 @@
(defn CDADDR [x] (uaf x (seq "dadd")))
(defn EQ
;; For some reason providing a doc string for this function breaks the
;; Clojure parser!
"Returns `T` if and only if both `x` and `y` are bound to the same atom,
else `F`."
[x y]
(if (and (= (ATOM x) 'T) (= x y)) 'T 'F))
(if (and (= (ATOM x) T) (= x y)) T F))
(defn EQUAL
"This is a predicate that is true if its two arguments are identical
@ -105,20 +130,20 @@
`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"
NOTE: returns `F` on failure, not `NIL`"
[x y]
(cond
(= (ATOM x) 'T) (EQ x y)
(= (EQUAL (CAR x) (CAR y)) 'T) (EQUAL (CDR x) (CDR y))
:else 'F))
(= (ATOM x) T) (EQ x y)
(= (EQUAL (CAR x) (CAR y)) T) (EQUAL (CDR x) (CDR y))
:else F))
(defn SUBST
"This function gives the result of substituting the S-expression `x` for
all occurrences of the atomic symbol `y` in the S-expression `z`."
[x y z]
(cond
(= (EQUAL y z) 'T) x
(= (ATOM? z) 'T) z ;; NIL is a symbol
(= (EQUAL y z) T) x
(= (ATOM? z) T) z ;; NIL is a symbol
:else
(make-cons-cell (SUBST x y (CAR z)) (SUBST x y (CDR z)))))
@ -143,7 +168,7 @@
[x y]
(cond
(= y NIL) F ;; NOTE: returns F on falsity, not NIL
(= (EQUAL x (CAR y)) 'T) 'T
(= (EQUAL x (CAR y)) T) T
:else (MEMBER x (CDR y))))
(defn PAIRLIS
@ -177,7 +202,7 @@
(cond
(= NIL a) NIL ;; this clause is not present in the original but is added for
;; robustness.
(= (EQUAL (CAAR a) x) 'T) (CAR a)
(= (EQUAL (CAAR a) x) T) (CAR a)
:else
(ASSOC x (CDR a))))
@ -204,11 +229,11 @@
See page 12 of the Lisp 1.5 Programmers Manual."
[a y]
(cond
(= (ATOM? y) 'T) (SUB2 a y)
(= (ATOM? y) T) (SUB2 a y)
:else
(make-cons-cell (SUBLIS a (CAR y)) (SUBLIS a (CDR y)))))
(deftrace APPLY
(defn APPLY
"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."
@ -216,7 +241,9 @@
(cond
(=
(ATOM? function)
'T)(cond
T)(cond
;; TODO: doesn't check whether `function` is bound in the environment;
;; we'll need that before we can bootstrap.
(= function 'CAR) (CAAR args)
(= function 'CDR) (CDAR args)
(= function 'CONS) (make-cons-cell (CAR args) (CADR args))
@ -261,19 +288,16 @@
(EVAL (CAR args) env)
(EVLIS (CDR args) env))))
(deftrace EVAL
"For bootstrapping, at least, a version of EVAL 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."
(deftrace traced-eval
"Essentially, identical to EVAL except traced."
[expr env]
(cond
(=
(ATOM? expr) 'T)
(ATOM? expr) T)
(CDR (ASSOC expr env))
(=
(ATOM? (CAR expr))
'T)(cond
T)(cond
(= (CAR expr) 'QUOTE) (CADR expr)
(= (CAR expr) 'COND) (EVCON (CDR expr) env)
:else (APPLY
@ -285,3 +309,30 @@
(EVLIS (CDR expr) env)
env)))
(defn EVAL
"For bootstrapping, at least, a version of EVAL 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."
[expr env]
(cond
(true? (:trace *options*))
(traced-eval expr env)
(=
(ATOM? expr) T)
(CDR (ASSOC expr env))
(=
(ATOM? (CAR expr))
T)(cond
(= (CAR expr) 'QUOTE) (CADR expr)
(= (CAR expr) 'COND) (EVCON (CDR expr) env)
:else (APPLY
(CAR expr)
(EVLIS (CDR expr) env)
env))
:else (APPLY
(CAR expr)
(EVLIS (CDR expr) env)
env)))

View file

@ -1,11 +1,20 @@
(ns beowulf.cons-cell
)
"The fundamental cons cell on which all Lisp structures are built.
Lisp 1.5 lists do not necessarily have a sequence as their CDR, so
cannot be implemented on top of Clojure lists.")
(def NIL (symbol "NIL"))
(def NIL
"The canonical empty list symbol."
(symbol "NIL"))
(def T (symbol "T")) ;; true.
(def T
"The canonical true value."
(symbol "T")) ;; true.
(def F (symbol "F")) ;; false as distinct from nil
(def F
"The canonical false value - different from `NIL`, which is not canonically
false in Lisp 1.5."
(symbol "F")) ;; false as distinct from nil
(deftype ConsCell [CAR CDR]
clojure.lang.ISeq
@ -15,12 +24,13 @@
;; https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/ISeq.java
(more [this] (if
(seq? (.CDR this))
clojure.lang.PersistentList/EMPTY
(.CDR this)))
(.CDR this)
clojure.lang.PersistentList/EMPTY))
(next [this] (if
(seq? (.CDR this))
(.CDR this)
nil ;; next returns nil when empty
(.CDR this)))
))
clojure.lang.Seqable
(seq [this] this)
@ -31,11 +41,26 @@
clojure.lang.IPersistentCollection
(count [this] (if
(seq? (.CDR this))
0
(inc (count (.CDR this)))))
(empty [this] false)
(equiv [this other] false))
(coll? (.CDR this))
(inc (.count (.CDR this)))
1))
(empty [this] false) ;; a cons cell is by definition not empty.
(equiv [this other] (if
(seq? other)
(and
(if
(and
(seq? (first this))
(seq? (first other)))
(.equiv (first this) (first other))
(= (first this) (first other)))
(if
(and
(seq? (rest this))
(seq? (rest other)))
(.equiv (rest this) (rest other))
(= (rest this) (rest other))))
false)))
(defn- to-string
"Printing ConsCells gave me a *lot* of trouble. This is an internal function
@ -103,21 +128,29 @@
(defmethod clojure.core/print-method beowulf.cons_cell.ConsCell
(defmethod clojure.core/print-method
;;; I have not worked out how to document defmethod without blowing up the world.
beowulf.cons_cell.ConsCell
[this writer]
(.write writer (to-string this)))
(defn make-cons-cell
[a d]
(ConsCell. a d))
(defmacro make-cons-cell
"Construct a new instance of cons cell with this `car` and `cdr`."
[car cdr]
`(ConsCell. ~car ~cdr))
(defn make-beowulf-list
"Construct a linked list of cons cells with the same content as the
sequence `x`."
[x]
(cond
(empty? x) NIL
(coll? x) (ConsCell.
(first x)
(if
(seq? (first x))
(make-beowulf-list (first x))
(first x))
(make-beowulf-list (rest x)))
:else
NIL))

View file

@ -1,21 +1,36 @@
(ns beowulf.core
(:require [beowulf.eval :refer [EVAL oblist]]
"Essentially, the `-main` function and the bootstrap read-eval-print loop."
(:require [beowulf.bootstrap :refer [EVAL oblist *options*]]
[beowulf.read :refer [READ]]
[clojure.java.io :as io]
[clojure.pprint :refer [pprint]]
[clojure.tools.cli :refer [parse-opts]]
[environ.core :refer [env]])
(:gen-class))
(def cli-options
[["-h" "--help"]
["-p PROMPT" "--prompt PROMPT" "Set the REPL prompt to PROMPT"
:default "Sprecan::"]
["-r INITFILE" "--read INITFILE" "Read Lisp functions from the file INITFILE"
:validate [#(and
(.exists (io/file %))
(.canRead (io/file %)))
"Could not find initfile"]]
["-s" "--strict" "Strictly interpret the Lisp 1.5 language, without extensions."]
["-t" "--trace" "Trace Lisp evaluation."]])
(defn repl
"Read/eval/print loop."
[]
[prompt]
(loop []
(print "Sprecan:: ")
(print prompt)
(flush)
(try
(let [input (read-line)]
(cond
(= input "quit") (throw (ex-info "Færwell!" {:cause :quit}))
input (println (str "> " (EVAL (READ input) @oblist)))
(= input "quit") (throw (ex-info "\nFærwell!" {:cause :quit}))
input (println (str "> " (print-str (EVAL (READ input) @oblist))))
:else (println)))
(catch
Exception
@ -26,20 +41,32 @@
data
(case (:cause data)
:parse-failure (println (:failure data))
:strict nil ;; the message, which has already been printed, is enough.
:quit (throw e)
;; default
(pprint data))))))
(recur)))
(defn -main
[& args]
"Parse options, print the banner, read the init file if any, and enter the
read/eval/print loop."
[& opts]
(let [args (parse-opts opts cli-options)]
(println
(str
"Hider wilcuman. Béowulf is mín nama\nSíðe "
"\nHider wilcuman. Béowulf is mín nama.\n"
(if
(System/getProperty "beowulf.version")
"\n\n"))
(str "Síðe " (System/getProperty "beowulf.version") "\n"))
(if
(:help (:options args))
(:summary args))
(if (:errors args)
(apply str (interpose "; " (:errors args))))
"\nSprecan 'quit' tó laéfan\n"))
(binding [*options* (:options args)]
(try
(repl)
(repl (str (:prompt (:options args)) " "))
(catch
Exception
e
@ -50,4 +77,4 @@
:quit nil
;; default
(pprint data))
(println e))))))
(println e))))))))

5
src/beowulf/host.clj Normal file
View file

@ -0,0 +1,5 @@
(ns beowulf.host
"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
host language, in this case Clojure.")

View file

@ -1,10 +1,31 @@
(ns beowulf.read
(:require [clojure.math.numeric-tower :refer [expt]]
"This provides the reader required for boostrapping. It's not a bad
reader - it provides feedback on errors found in the input - but it isn't
the real Lisp reader.
Intended deviations from the behaviour of the real Lisp reader are as follows:
1. It reads the meta-expression language `MEXPR` in addition to the
symbolic expression language `SEXPR`, which I do not believe the Lisp 1.5
reader ever did;
2. It treats everything between a semi-colon and an end of line as a comment,
as most modern Lisps do; but I do not believe Lisp 1.5 had this feature.
Both these extensions can be disabled by using the `--strict` command line
switch."
(:require [beowulf.bootstrap :refer [*options*]]
[clojure.math.numeric-tower :refer [expt]]
[clojure.string :refer [starts-with? upper-case]]
[instaparse.core :as i]
[beowulf.cons-cell :refer [make-beowulf-list make-cons-cell NIL]])
;; (:import [beowulf.cons-cell ConsCell])
)
[beowulf.cons-cell :refer [make-beowulf-list make-cons-cell NIL]]))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;
;;; This file provides the reader required for boostrapping. It's not a bad
;;; reader - it provides feedback on errors found in the input - but it isn't
;;; the real Lisp reader.
;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(declare generate)
@ -18,7 +39,7 @@
;; mexprs. I'm pretty clear that Lisp 1.5 could never read these,
;; but it's a convenience.
"mexpr := λexpr | fncall | defn | cond | mvar;
"mexpr := λexpr | fncall | defn | cond | mvar | mexpr comment;
λexpr := λ lsqb bindings semi-colon body rsqb;
λ := ';
bindings := lsqb args rsqb;
@ -35,9 +56,12 @@
mvar := #'[a-z]+';
semi-colon := ';';"
;; comments. I'm pretty confident Lisp 1.5 did NOT have these.
"comment := opt-space <';;'> #'[^\\n\\r]*';"
;; sexprs. Note it's not clear to me whether Lisp 1.5 had the quote macro,
;; but I've included it on the basis that it can do little harm.
"sexpr := quoted-expr | atom | number | dotted-pair | list;
"sexpr := quoted-expr | atom | number | dotted-pair | list | sexpr comment;
list := lpar sexpr rpar | lpar (sexpr sep)* rpar | lpar (sexpr sep)* dot-terminal;
dotted-pair := lpar dot-terminal ;
dot := '.';
@ -89,6 +113,11 @@
(= context :mexpr)
[:quoted-expr p]
p)
:comment (if
(:strict *options*)
(throw
(ex-info "Cannot parse comments in strict mode"
{:cause :strict})))
:dotted-pair (if
(= context :mexpr)
[:fncall
@ -97,7 +126,12 @@
(simplify (nth p 1) context)
(simplify (nth p 2) context)]]
(map simplify p))
:mexpr (simplify (second p) :mexpr)
:mexpr (if
(:strict *options*)
(throw
(ex-info "Cannot parse meta expressions in strict mode"
{:cause :strict}))
(simplify (second p) :mexpr))
:list (if
(= context :mexpr)
[:fncall
@ -109,7 +143,6 @@
p)))
;; # From Lisp 1.5 Programmers Manual, page 10
;; Note that I've retyped much of this, since copy/pasting out of PDF is less
;; than reliable. Any typos are mine. Quote starts [[
@ -185,9 +218,7 @@
(defn gen-fn-call
"Generate a function call from this simplified parse tree fragment `p`;
returns `nil` if `p` does not represent a (MEXPR) function call.
TODO: I'm not yet certain but it appears that args in mexprs are
implicitly quoted; this function does not (yet) do that."
returns `nil` if `p` does not represent a (MEXPR) function call."
[p]
(if
(and (coll? p)(= :fncall (first p))(= :mvar (first (second p))))
@ -290,5 +321,7 @@
`(generate (simplify (parse ~s))))
(defn READ
"An implementation of a Lisp reader sufficient for bootstrapping; not necessarily
the final Lisp reader."
[input]
(gsp (or input (read-line))))

View file

@ -2,7 +2,7 @@
(:require [clojure.math.numeric-tower :refer [abs]]
[clojure.test :refer :all]
[beowulf.cons-cell :refer [make-beowulf-list make-cons-cell NIL T F]]
[beowulf.eval :refer :all]
[beowulf.bootstrap :refer :all]
[beowulf.read :refer [gsp]]))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -176,16 +176,24 @@
(deftest member-tests
(testing "member"
(let [expected 'T
actual (MEMBER (gsp "ALBERT") (gsp "(ALBERT BELINDA CHARLIE DORIS ELFREDA FRED)"))]
actual (MEMBER
(gsp "ALBERT")
(gsp "(ALBERT BELINDA CHARLIE DORIS ELFREDA FRED)"))]
(= actual expected))
(let [expected 'T
actual (MEMBER (gsp "BELINDA") (gsp "(ALBERT BELINDA CHARLIE DORIS ELFREDA FRED)"))]
actual (MEMBER
(gsp "BELINDA")
(gsp "(ALBERT BELINDA CHARLIE DORIS ELFREDA FRED)"))]
(= actual expected))
(let [expected 'T
actual (MEMBER (gsp "ELFREDA") (gsp "(ALBERT BELINDA CHARLIE DORIS ELFREDA FRED)"))]
actual (MEMBER
(gsp "ELFREDA")
(gsp "(ALBERT BELINDA CHARLIE DORIS ELFREDA FRED)"))]
(= actual expected))
(let [expected 'F
actual (MEMBER (gsp "BERTRAM") (gsp "(ALBERT BELINDA CHARLIE DORIS ELFREDA FRED)"))]
actual (MEMBER
(gsp "BERTRAM")
(gsp "(ALBERT BELINDA CHARLIE DORIS ELFREDA FRED)"))]
(= actual expected))))
(deftest pairlis-tests

View file

@ -0,0 +1,57 @@
(ns beowulf.core-test
(:require [clojure.test :refer :all]
[beowulf.cons-cell :refer :all]))
(deftest cons-cell-tests
(testing "make-cons-cell"
(let [expected "(A . B)"
actual (print-str (beowulf.cons_cell.ConsCell. 'A 'B))]
(is (= actual expected) "Cons cells should print as cons cells, natch."))
(let [expected "(A . B)"
actual (print-str (make-cons-cell 'A 'B))]
(is (= actual expected) "Even if build with the macro."))
(let [expected beowulf.cons_cell.ConsCell
actual (print-str (make-cons-cell 'A 'B))]
(is (= actual expected) "And they should be cons cells."))
)
(testing "make-beowulf-list"
(let [expected "(A (B C) (D E (F) G) H)"
actual (print-str (make-beowulf-list '(A (B C) (D E (F) G) H)))]
(is (= actual expected) "Should work for clojure lists, recursively."))
(let [expected "(A (B C) (D E (F) G) H)"
actual (print-str (make-beowulf-list [A [B C] [D E [F] G] H]))]
(is (= actual expected) "Should work for vectors, too."))
(let [expected "NIL"
actual (print-str (make-beowulf-list []))]
(is (= actual expected) "An empty sequence is NIL."))
(let [expected beowulf.cons_cell.ConsCell
actual (make-beowulf-list '(A (B C) (D E (F) G) H))]
(is (= actual expected) "A beowulf list is made of cons cells.")))
(testing "pretty-print"
(let [expected "(A\n (B C)\n (D E (F) G) H)"
actual (pretty-print (make-beowulf-list '(A (B C) (D E (F) G) H)) 20 0)]
(is (= actual expected)))
(let [expected "(A (B C) (D E (F) G) H)"
actual (pretty-print (make-beowulf-list '(A (B C) (D E (F) G) H)))]
(is (= actual expected))))
(testing "count"
(let [expected 4
actual (count (make-beowulf-list '(A (B C) (D E (F) G) H)) 20 0)]
(is (= actual expected)))
(let [expected 1
actual (count (make-beowulf-list '(A)))]
(is (= actual expected)))
(let [expected 1
actual (count (make-cons-cell 'A 'B))]
(is (= actual expected))))
(testing "sequence functions"
(let [expected "A"
actual (print-str (first (make-beowulf-list '(A (B C) (D E (F) G) H))))]
(is (= actual expected)))
(let [expected "((B C) (D E (F) G) H)"
actual (print-str (more (make-beowulf-list '(A (B C) (D E (F) G) H))))]
(is (= actual expected)))
(let [expected "((B C) (D E (F) G) H)"
actual (print-str (next (make-beowulf-list '(A (B C) (D E (F) G) H))))]
(is (= actual expected)))
))

View file

@ -1,7 +1,175 @@
(ns beowulf.core-test
(:require [clojure.test :refer :all]
(:require [clojure.java.io :refer [reader]]
[clojure.string :refer [split]]
[clojure.test :refer :all]
[beowulf.core :refer :all]))
;; (deftest a-test
;; (testing "FIXME, I fail."
;; (is (= 0 1))))
(defn string->stream
"Copied shamelessly from
https://stackoverflow.com/questions/38283891/how-to-wrap-a-string-in-an-input-stream"
([s] (string->stream s "UTF-8"))
([s encoding]
(-> s
(.getBytes encoding)
(java.io.ByteArrayInputStream.))))
(deftest repl-tests
(testing "quit functionality"
(with-open [r (reader (string->stream "quit"))]
(binding [*in* r]
(is (thrown-with-msg? Exception #"\nFærwell!" (repl "")))))
(let [expected nil
actual (with-open [r (reader (string->stream "quit"))]
(binding [*in* r]
(-main)))]
(is (= actual expected)))))
(deftest flag-tests
(testing "No flags"
(let [expected-greeting "Hider wilcuman. Béowulf is mín nama."
expected-quit-message "Sprecan 'quit' tó laéfan"
expected-error ""
expected-result #".*\(A \. B\)"
expected-prompt "Sprecan:: "
expected-signoff "Færwell!"
[_ greeting version error quit-message _ result prompt signoff]
(with-open [r (reader (string->stream "cons[A; B]\nquit"))]
(binding [*in* r]
(split (with-out-str (-main)) #"\n")))]
(is (= greeting expected-greeting))
(is (= error expected-error))
(is (re-matches expected-result result))
(is (= quit-message expected-quit-message))
(is (= prompt expected-prompt))
(is (= signoff expected-signoff))
))
(testing "unknown flag"
(let [expected-greeting "Hider wilcuman. Béowulf is mín nama."
expected-quit-message "Sprecan 'quit' tó laéfan"
expected-error #"Unknown option:.*"
expected-result #".*\(A \. B\)"
expected-prompt "Sprecan:: "
expected-signoff "Færwell!"
[_ greeting version error quit-message _ result prompt signoff]
(with-open [r (reader (string->stream "cons[A; B]\nquit"))]
(binding [*in* r]
(split (with-out-str (-main "--unknown")) #"\n")))]
(is (= greeting expected-greeting))
(is (re-matches expected-error error))
(is (re-matches expected-result result))
(is (= quit-message expected-quit-message))
(is (= prompt expected-prompt))
(is (= signoff expected-signoff))
))
(testing "help"
(let [expected-greeting "Hider wilcuman. Béowulf is mín nama."
expected-h1 " -h, --help"
expected-quit-message "Sprecan 'quit' tó laéfan"
expected-result #".*\(A \. B\)"
expected-prompt "Sprecan:: "
expected-signoff "Færwell!"
[_ greeting version h1 h2 h3 h4 h5 quit-message _ result prompt signoff]
(with-open [r (reader (string->stream "cons[A; B]\nquit"))]
(binding [*in* r]
(split (with-out-str (-main "--help")) #"\n")))]
(is (= greeting expected-greeting))
(is (= h1 expected-h1))
(is (re-matches expected-result result))
(is (= quit-message expected-quit-message))
(is (= prompt expected-prompt))
(is (= signoff expected-signoff))
))
(testing "prompt"
(let [expected-greeting "Hider wilcuman. Béowulf is mín nama."
expected-quit-message "Sprecan 'quit' tó laéfan"
expected-error ""
expected-result #".*\(A \. B\).*"
expected-prompt "? "
expected-signoff "Færwell!"
[_ greeting version error quit-message _ result prompt signoff]
(with-open [r (reader (string->stream "cons[A; B]\nquit"))]
(binding [*in* r]
(split (with-out-str (-main "--prompt" "?")) #"\n")))]
(is (= greeting expected-greeting))
(is (= error expected-error))
(is (re-matches expected-result result ))
(is (= quit-message expected-quit-message))
(is (= prompt expected-prompt))
(is (= signoff expected-signoff))
))
(testing "read - file not found"
(let [expected-greeting "Hider wilcuman. Béowulf is mín nama."
expected-quit-message "Sprecan 'quit' tó laéfan"
expected-error #"Failed to validate.*"
expected-result #".*\(A \. B\)"
expected-prompt "Sprecan:: "
expected-signoff "Færwell!"
[_ greeting version error quit-message _ result prompt signoff]
(with-open [r (reader (string->stream "cons[A; B]\nquit"))]
(binding [*in* r]
(split (with-out-str (-main "--read" "froboz")) #"\n")))]
(is (= greeting expected-greeting))
(is (re-matches expected-error error))
(is (re-matches expected-result result))
(is (= quit-message expected-quit-message))
(is (= prompt expected-prompt))
(is (= signoff expected-signoff))
))
(testing "read - file found"
;; TODO: there's no feedback from this because the initfile
;; is not yet read. This will change
(let [expected-greeting "Hider wilcuman. Béowulf is mín nama."
expected-quit-message "Sprecan 'quit' tó laéfan"
expected-error ""
expected-result #".*\(A \. B\)"
expected-prompt "Sprecan:: "
expected-signoff "Færwell!"
[_ greeting version error quit-message _ result prompt signoff]
(with-open [r (reader (string->stream "cons[A; B]\nquit"))]
(binding [*in* r]
(split (with-out-str (-main "--read" "README.md")) #"\n")))]
(is (= greeting expected-greeting))
(is (= error expected-error))
(is (re-matches expected-result result))
(is (= quit-message expected-quit-message))
(is (= prompt expected-prompt))
(is (= signoff expected-signoff))
))
(testing "strict"
(let [expected-greeting "Hider wilcuman. Béowulf is mín nama."
expected-quit-message "Sprecan 'quit' tó laéfan"
expected-error ""
expected-result #".*Cannot parse meta expressions in strict mode.*"
expected-prompt "Sprecan:: "
expected-signoff "Færwell!"
[_ greeting version error quit-message _ result prompt signoff]
(with-open [r (reader (string->stream "cons[A; B]\nquit"))]
(binding [*in* r]
(split (with-out-str (-main "--strict")) #"\n")))]
(is (= greeting expected-greeting))
(is (= error expected-error))
(is (re-matches expected-result result ))
(is (= quit-message expected-quit-message))
(is (= prompt expected-prompt))
(is (= signoff expected-signoff))
))
(testing "trace"
(let [expected-greeting "Hider wilcuman. Béowulf is mín nama."
expected-quit-message "Sprecan 'quit' tó laéfan"
expected-error ""
expected-trace #".*traced-eval.*"
[_ greeting version error quit-message _ trace & _]
(with-open [r (reader (string->stream "cons[A; B]\nquit"))]
(binding [*in* r]
(split (with-out-str (-main "--trace")) #"\n")))]
(is (= greeting expected-greeting))
(is (= error expected-error))
(is (re-matches expected-trace trace))
))
)

View file

@ -1,6 +1,9 @@
(ns beowulf.mexpr-test
"These tests are taken generally from the examples on page 10 of
Lisp 1.5 Programmers Manual"
(:require [clojure.test :refer :all]
[beowulf.read :refer [parse simplify generate]]))
[beowulf.bootstrap :refer [*options*]]
[beowulf.read :refer [parse simplify generate gsp]]))
;; These tests are taken generally from the examples on page 10 of
;; Lisp 1.5 Programmers Manual:
@ -64,4 +67,10 @@
(parse "label[ff;λ[[x];[atom[x]->x; T->ff[car[x]]]]]"))))]
(is (= actual expected)))))
;; (parse "equal[x;y] = [atom[x]->[atom[y]->eq[x;y]; T->F]; equal[car[x]; car[y]]->equal[cdr[x];cdr[y]];T->F]")
(deftest strict-tests
(testing "Strict feature"
(binding [*options* {:strict true}]
(is (thrown-with-msg?
Exception
#"Cannot parse meta expressions in strict mode"
(gsp "label[ff;λ[[x];[atom[x]->x; T->ff[car[x]]]]]"))))))

View file

@ -2,7 +2,8 @@
(:require [clojure.math.numeric-tower :refer [abs]]
[clojure.test :refer :all]
[beowulf.cons-cell :refer :all]
[beowulf.read :refer [parse simplify generate]]))
[beowulf.bootstrap :refer [*options*]]
[beowulf.read :refer [parse simplify generate gsp]]))
;; broadly, sexprs should be homoiconic
@ -24,6 +25,32 @@
actual (generate (simplify (parse (str expected))))]
(is (= actual expected)))))
(deftest comment-tests
(testing "Reading comments"
(let [expected 'A
actual (gsp "A ;; comment")]
(is (= actual expected)))
(let [expected 10
actual (gsp "10 ;; comment")]
(is (= actual expected)))
(let [expected 2/5
actual (gsp "4E-1 ;; comment")]
(is (= actual expected)))
(let [expected "(A B C)"
actual (print-str (gsp "(A ;; comment
B C)"))]
(is (= actual expected)
"Really important that comments work inside lists"))
;; ;; TODO: Currently failing and I'm not sure why
;; (binding [*options* {:strict true}]
;; (is (thrown-with-msg?
;; Exception
;; #"Cannot parse comments in strict mode"
;; (gsp "(A ;; comment
;; B C)"))))
))
(deftest number-tests
(testing "Reading octal numbers"
(let [expected 1