Compare commits
16 commits
Author | SHA1 | Date | |
---|---|---|---|
|
c64e6f3f03 | ||
|
2817362cc9 | ||
|
9899a8b678 | ||
|
dc46735f55 | ||
|
33079232e1 | ||
|
7906ce7ecb | ||
|
d563f390c1 | ||
|
d2ce61e6a7 | ||
|
e9406d5574 | ||
|
7c4d3668a8 | ||
|
01e4572119 | ||
|
26e8c42ba4 | ||
|
8b99c62ac3 | ||
|
6f59385eaf | ||
|
6da5bf53d3 | ||
|
552a40a645 |
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -21,3 +21,7 @@ Sysout*.lsp
|
|||
*.pdf
|
||||
|
||||
src/beowulf/scratch.clj
|
||||
|
||||
.portal/vs-code.edn
|
||||
|
||||
.portal/
|
||||
|
|
|
@ -77,7 +77,7 @@ You are of course welcome to fork the project and do whatever you like with it!
|
|||
|
||||
Invoke with
|
||||
|
||||
java -jar target/uberjar/beowulf-0.3.0-standalone.jar --help
|
||||
java -jar target/uberjar/beowulf-0.3.1-standalone.jar --help
|
||||
|
||||
(Obviously, check your version number)
|
||||
|
||||
|
@ -338,7 +338,7 @@ even has a working compiler!
|
|||
|
||||
### History resources
|
||||
|
||||
I'm compiling a [list of links to historical documents on Lisp 1.5](https://simon-brooke.github.io/beowulf/docs/further_reading.html).
|
||||
I'm compiling a [list of links to historical documents on Lisp 1.5](https://simon-brooke.github.io/beowulf/docs/codox/further_reading.html).
|
||||
|
||||
## License
|
||||
|
||||
|
|
|
@ -961,19 +961,15 @@ But if eval is given (QUOTE X), X should not be evaluated. QUOTE is a special fo
|
|||
that prevents its argument from being evaluated.
|
||||
A special form differs from a function in two ways. Its arguments are not evaluated
|
||||
before the special form sees them. COND, for example, has a very special way of
|
||||
```
|
||||
|
||||
evaluating its arguments by using evcon. The second way which special forms differ
|
||||
from functions is that they may have an indefinite number of arguments. Special forrrls
|
||||
have indicators on their property lists called FEXPR and FSUBR for LISP -defined forms
|
||||
from functions is that they may have an indefinite number of arguments. Special forms
|
||||
have indicators on their property lists called FEXPR and FSUBR for LISP-defined forms
|
||||
and machine language coded forms, respectively.
|
||||
|
||||
```
|
||||
2.6 Programming for the Interpreter
|
||||
```
|
||||
### 2.6 Programming for the Interpreter
|
||||
|
||||
The purpose of this section is to help the programmer avoid certain common errors.
|
||||
Example 1
|
||||
Example 1: CAR
|
||||
fn: CAR
|
||||
args: ((A B))
|
||||
The value is A. Note that the interpreter expects a list of arguments. The one argu-
|
||||
|
@ -981,20 +977,18 @@ ment for car is (A B). The extra pair of parentheses is necessary.
|
|||
One could write (LAMBDA (X) (CAR X)) instead of just CAR. This is correct but
|
||||
unnecessary.
|
||||
|
||||
```
|
||||
Example 2
|
||||
Example 2: CONS
|
||||
fn: CONS
|
||||
args: (A (B. C))
|
||||
The value is cons[^;(^. c)] = (A. (B. C)).
|
||||
The print program will write this as (A B. C).
|
||||
```
|
||||
args: (A (B . C))
|
||||
The value is cons[a; cons[b; c]] = (A . (B . C)).
|
||||
The print program will write this as (A B . C).
|
||||
|
||||
Example (^3) -
|
||||
fn: CONS
|
||||
args: ((CAR (QUOTE (A. B))) (CDR (QUOTE (C. D))))
|
||||
The value of this computation will be ((CAR (QUOTE (A. B))). (CDR (QUOTE (C. D)))).
|
||||
This is not what the programmer expected. He expected (CAR (QUOTE (A. B))) to
|
||||
evaluate to A, and expected (A. D) as the value of cons.
|
||||
args: ((CAR (QUOTE (A . B))) (CDR (QUOTE (C . D))))
|
||||
The value of this computation will be ((CAR (QUOTE (A . B))) . (CDR (QUOTE (C . D)))).
|
||||
This is not what the programmer expected. He expected (CAR (QUOTE (A . B))) to
|
||||
evaluate to A, and expected (A . D) as the value of cons.
|
||||
|
||||
* The interpreter expects a ---- list of arguments. ------- It does not expect a list of expressions
|
||||
-- that will evaluate to the arguments. Tworcorrect ways of writing this function are listed
|
||||
|
@ -1721,6 +1715,7 @@ represented in storage only once,
|
|||
The following simple example has been included to illustrate the exact construction
|
||||
of list structures. Two types of list structures are shown, and a function for deriving
|
||||
one from the other is given in LISP.
|
||||
|
||||
We assume that we have a list of the form
|
||||
n, = ((A B C) (D E F),... , (X Y z)),
|
||||
|
||||
|
@ -2709,7 +2704,9 @@ If `deflist` or `define` is used twice on the same object with the same indicato
|
|||
The function attrib concatenates its two arguments by changing the last element of its first argument to point to the second argument. Thus it is commonly used to tack something onto the end of a property list. The value of attrib is the second argument.
|
||||
|
||||
For example
|
||||
attrib[~~; (EXPR (LAMBDA (X) (COND ((ATOM X) X) (T (FF (CAR x))))))]
|
||||
```
|
||||
attrib[FF; (EXPR (LAMBDA (X) (COND ((ATOM X) X) (T (FF (CAR x))))))]
|
||||
```
|
||||
would put EXPR followed by the LAMBDA expression for FF onto the end of the prop-
|
||||
erty list for FF.
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -11,238 +11,394 @@
|
|||
002 "Essentially, the `-main` function and the bootstrap read-eval-print loop."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
003 (:require [beowulf.bootstrap :refer [EVAL oblist *options*]]
|
||||
003 (:require [beowulf.bootstrap :refer [EVAL]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
004 [beowulf.read :refer [READ]]
|
||||
004 [beowulf.io :refer [default-sysout SYSIN]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
005 [clojure.java.io :as io]
|
||||
005 [beowulf.oblist :refer [*options* NIL]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
006 [clojure.pprint :refer [pprint]]
|
||||
006 [beowulf.read :refer [READ read-from-console]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
007 [clojure.tools.cli :refer [parse-opts]]
|
||||
007 [clojure.java.io :as io]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
008 [environ.core :refer [env]])
|
||||
008 [clojure.pprint :refer [pprint]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
009 (:gen-class))
|
||||
009 [clojure.string :refer [trim]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
010 [clojure.tools.cli :refer [parse-opts]])
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
011 (:gen-class))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
010
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
011 (def cli-options
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
012 [["-h" "--help"]
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
013 ["-p PROMPT" "--prompt PROMPT" "Set the REPL prompt to PROMPT"
|
||||
012
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
014 :default "Sprecan::"]
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
015 ["-r INITFILE" "--read INITFILE" "Read Lisp functions from the file INITFILE"
|
||||
</span><br/>
|
||||
<span class="covered" title="8 out of 8 forms covered">
|
||||
016 :validate [#(and
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
017 (.exists (io/file %))
|
||||
013 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
018 (.canRead (io/file %)))
|
||||
014 ;;;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
019 "Could not find initfile"]]
|
||||
015 ;;; Copyright (C) 2022-2023 Simon Brooke
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
020 ["-s" "--strict" "Strictly interpret the Lisp 1.5 language, without extensions."]
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
016 ;;;
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
021 ["-t" "--trace" "Trace Lisp evaluation."]])
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
017 ;;; This program is free software; you can redistribute it and/or
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
018 ;;; modify it under the terms of the GNU General Public License
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
019 ;;; as published by the Free Software Foundation; either version 2
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
020 ;;; of the License, or (at your option) any later version.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
021 ;;;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
022 ;;; This program is distributed in the hope that it will be useful,
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
023 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
024 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
025 ;;; GNU General Public License for more details.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
026 ;;;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
027 ;;; You should have received a copy of the GNU General Public License
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
028 ;;; along with this program; if not, write to the Free Software
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
029 ;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
030 ;;;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
031 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
022
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
023 (defn repl
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
024 "Read/eval/print loop."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
025 [prompt]
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
026 (loop []
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
027 (print prompt)
|
||||
032
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
028 (flush)
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
029 (try
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
030 (let [input (read-line)]
|
||||
</span><br/>
|
||||
<span class="partial" title="2 out of 3 forms covered">
|
||||
031 (cond
|
||||
</span><br/>
|
||||
<span class="covered" title="11 out of 11 forms covered">
|
||||
032 (= input "quit") (throw (ex-info "\nFærwell!" {:cause :quit}))
|
||||
</span><br/>
|
||||
<span class="covered" title="16 out of 16 forms covered">
|
||||
033 input (println (str "> " (print-str (EVAL (READ input) @oblist))))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
034 :else (println)))
|
||||
033 (def stop-word
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
035 (catch
|
||||
034 "The word which, if submitted an an input line, will cause Beowulf to quit.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
036 Exception
|
||||
035 Question: should this be `forlǣte`?"
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
037 e
|
||||
036 "STOP")
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
038 (let [data (ex-data e)]
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
039 (println (.getMessage e))
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
037
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
040 (if
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
041 data
|
||||
038 (def cli-options
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
042 (case (:cause data)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
043 :parse-failure (println (:failure data))
|
||||
039 [["-f FILEPATH" "--file-path FILEPATH"
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
044 :strict nil ;; the message, which has already been printed, is enough.
|
||||
040 "Set the path to the directory for reading and writing Lisp files."
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
045 :quit (throw e)
|
||||
<span class="partial" title="3 out of 20 forms covered">
|
||||
041 :validate [#(and (.exists (io/file %))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
046 ;; default
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
042 (.isDirectory (io/file %))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
043 (.canRead (io/file %))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
047 (pprint data))))))
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
048 (recur)))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
049
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
050 (defn -main
|
||||
044 (.canWrite (io/file %)))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
051 "Parse options, print the banner, read the init file if any, and enter the
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
052 read/eval/print loop."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
053 [& opts]
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
054 (let [args (parse-opts opts cli-options)]
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
055 (println
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
056 (str
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
057 "\nHider wilcuman. Béowulf is mín nama.\n"
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
058 (if
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
059 (System/getProperty "beowulf.version")
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
060 (str "Síðe " (System/getProperty "beowulf.version") "\n"))
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
061 (if
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
062 (:help (:options args))
|
||||
045 "File path must exist and must be a directory."]]
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
063 (:summary args))
|
||||
046 ["-h" "--help"]
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
064 (if (:errors args)
|
||||
</span><br/>
|
||||
<span class="covered" title="9 out of 9 forms covered">
|
||||
065 (apply str (interpose "; " (:errors args))))
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
047 ["-p PROMPT" "--prompt PROMPT" "Set the REPL prompt to PROMPT"
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
066 "\nSprecan 'quit' tó laéfan\n"))
|
||||
048 :default "Sprecan::"]
|
||||
</span><br/>
|
||||
<span class="covered" title="12 out of 12 forms covered">
|
||||
067 (binding [*options* (:options args)]
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
049 ["-r SYSOUTFILE" "--read SYSOUTFILE" "Read Lisp system from file SYSOUTFILE"
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
068 (try
|
||||
050 :default default-sysout
|
||||
</span><br/>
|
||||
<span class="partial" title="7 out of 8 forms covered">
|
||||
051 :validate [#(and
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
052 (.exists (io/file %))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
053 (.canRead (io/file %)))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
054 "Could not find sysout file"]]
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
055 ["-s" "--strict" "Strictly interpret the Lisp 1.5 language, without extensions."]
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
056 ["-t" "--time" "Time evaluations."]
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
057 ["-x" "--testing" "Disable the jline reader - useful when piping input."]])
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
058
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
059 (defn- re
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
060 "Like REPL, but it isn't a loop and doesn't print."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
061 [input]
|
||||
</span><br/>
|
||||
<span class="covered" title="7 out of 7 forms covered">
|
||||
062 (EVAL (READ input) NIL 0))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
063
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
064 (defn repl
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
065 "Read/eval/print loop."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
066 [prompt]
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
067 (loop []
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
068 (flush)
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
069 (try
|
||||
</span><br/>
|
||||
<span class="covered" title="10 out of 10 forms covered">
|
||||
069 (repl (str (:prompt (:options args)) " "))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
070 (catch
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
071 Exception
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
072 e
|
||||
070 (if-let [input (trim (read-from-console prompt))]
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
073 (let [data (ex-data e)]
|
||||
071 (if (= input stop-word)
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
074 (if
|
||||
<span class="covered" title="7 out of 7 forms covered">
|
||||
072 (throw (ex-info "\nFærwell!" {:cause :quit}))
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
075 data
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
073 (println
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
074 (str "> "
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
076 (case (:cause data)
|
||||
075 (print-str (if (:time *options*)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 18 forms covered">
|
||||
076 (time (re input))
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
077 (re input))))))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
078 (println))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
077 :quit nil
|
||||
079 (catch
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
078 ;; default
|
||||
080 Exception
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
081 e
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
082 (let [data (ex-data e)]
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
083 (println (.getMessage e))
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
084 (when
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
085 data
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
086 (case (:cause data)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
087 :parse-failure (println (:failure data))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
088 :strict nil ;; the message, which has already been printed, is enough.
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
089 :quit (throw e)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
090 ;; default
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
079 (pprint data))
|
||||
091 (pprint data))))))
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
092 (recur)))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
093
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
094 (defn -main
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
095 "Parse options, print the banner, read the init file if any, and enter the
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
096 read/eval/print loop."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
097 [& opts]
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
098 (let [args (parse-opts opts cli-options)]
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
099 (println
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
100 (str
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
101 "\nHider wilcuman. Béowulf is mín nama.\n"
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
102 (when
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
103 (System/getProperty "beowulf.version")
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
104 (str "Síðe " (System/getProperty "beowulf.version") "\n"))
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
105 (when
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
106 (:help (:options args))
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
107 (:summary args))
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
108 (when (:errors args)
|
||||
</span><br/>
|
||||
<span class="covered" title="9 out of 9 forms covered">
|
||||
109 (apply str (interpose "; " (:errors args))))
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
110 "\nSprecan '" stop-word "' tó laéfan\n"))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
111
|
||||
</span><br/>
|
||||
<span class="covered" title="12 out of 12 forms covered">
|
||||
112 (binding [*options* (:options args)]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
113 ;; (pprint *options*)
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
114 (when (:read *options*)
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
115 (try (SYSIN (:read *options*))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
116 (catch Throwable any
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
080 (println e))))))))
|
||||
117 (println any))))
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
118 (try
|
||||
</span><br/>
|
||||
<span class="covered" title="7 out of 7 forms covered">
|
||||
119 (repl (:prompt (:options args)))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
120 (catch
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
121 Exception
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
122 e
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
123 (let [data (ex-data e)]
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
124 (if
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
125 data
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
126 (case (:cause data)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
127 :quit nil
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
128 ;; default
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
129 (do
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
130 (println "STÆFLEAHTER: " (.getMessage e))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
131 (pprint data)))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
132 (println e))))))))
|
||||
</span><br/>
|
||||
</body>
|
||||
</html>
|
||||
|
|
File diff suppressed because it is too large
Load diff
395
docs/cloverage/beowulf/interop.clj.html
Normal file
395
docs/cloverage/beowulf/interop.clj.html
Normal file
|
@ -0,0 +1,395 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<link rel="stylesheet" href="../coverage.css"/> <title> beowulf/interop.clj </title>
|
||||
</head>
|
||||
<body>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
001 (ns beowulf.interop
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
002 (:require [beowulf.cons-cell :refer [make-beowulf-list]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
003 [beowulf.host :refer [CAR CDR]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
004 [beowulf.oblist :refer [*options* NIL]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
005 [clojure.string :as s :refer [last-index-of lower-case split
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
006 upper-case]]))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
007
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
008 ;;;; INTEROP feature ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
009
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
010 (defn listify-qualified-name
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
011 "We need to be able to print something we can link to the particular Clojure
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
012 function `subr` in a form in which Lisp 1.5 is able to read it back in and
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
013 relink it.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
014
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
015 This assumes `subr` is either
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
016 1. a string in the format `#'beowulf.io/SYSIN` or `beowulf.io/SYSIN`; or
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
017 2. something which, when coerced to a string with `str`, will have such
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
018 a format."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
019 [subr]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
020 (make-beowulf-list
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
021 (map
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
022 #(symbol (upper-case %))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 9 forms covered">
|
||||
023 (remove empty? (split (str subr) #"[#'./]")))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
024
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
025
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
026 (defn interpret-qualified-name
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
027 "For interoperation with Clojure, it will often be necessary to pass
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
028 qualified names that are not representable in Lisp 1.5. This function
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
029 takes a sequence in the form `(PART PART PART... NAME)` and returns
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
030 a symbol in the form `part.part.part/NAME`. This symbol will then be
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
031 tried in both that form and lower-cased. Names with hyphens or
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
032 underscores cannot be represented with this scheme."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
033 ([l]
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
034 (symbol
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
035 (let [n (s/join "."
|
||||
</span><br/>
|
||||
<span class="covered" title="13 out of 13 forms covered">
|
||||
036 (concat (map #(lower-case (str %)) (butlast l))
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
037 (list (last l))))
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
038 s (last-index-of n ".")]
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
039 (if s
|
||||
</span><br/>
|
||||
<span class="covered" title="13 out of 13 forms covered">
|
||||
040 (str (subs n 0 s) "/" (subs n (inc s)))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
041 n)))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
042
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
043 (defn to-beowulf
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
044 "Return a beowulf-native representation of the Clojure object `o`.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
045 Numbers and symbols are unaffected. Collections have to be converted;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
046 strings must be converted to symbols."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
047 [o]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
048 (cond
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
049 (coll? o) (make-beowulf-list o)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 8 forms covered">
|
||||
050 (string? o) (symbol (s/upper-case o))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
051 :else o))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
052
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
053 (defn to-clojure
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
054 "If l is a `beowulf.cons_cell.ConsCell`, return a Clojure list having the
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
055 same members in the same order."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
056 [l]
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
057 (cond
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
058 (not (instance? beowulf.cons_cell.ConsCell l))
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
059 l
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
060 (= (CDR l) NIL)
|
||||
</span><br/>
|
||||
<span class="covered" title="7 out of 7 forms covered">
|
||||
061 (list (to-clojure (CAR l)))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
062 :else
|
||||
</span><br/>
|
||||
<span class="covered" title="12 out of 12 forms covered">
|
||||
063 (conj (to-clojure (CDR l)) (to-clojure (CAR l)))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
064
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
065 (defn INTEROP
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
066 "Clojure (or other host environment) interoperation API. `fn-symbol` is expected
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
067 to be either
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
068
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
069 1. a symbol bound in the host environment to a function; or
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
070 2. a sequence (list) of symbols forming a qualified path name bound to a
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
071 function.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
072
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
073 Lower case characters cannot normally be represented in Lisp 1.5, so both the
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
074 upper case and lower case variants of `fn-symbol` will be tried. If the
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
075 function you're looking for has a mixed case name, that is not currently
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
076 accessible.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
077
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
078 `args` is expected to be a Lisp 1.5 list of arguments to be passed to that
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
079 function. Return value must be something acceptable to Lisp 1.5, so either
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
080 a symbol, a number, or a Lisp 1.5 list.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
081
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
082 If `fn-symbol` is not found (even when cast to lower case), or is not a function,
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
083 or the value returned cannot be represented in Lisp 1.5, an exception is thrown
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
084 with `:cause` bound to `:interop` and `:detail` set to a value representing the
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
085 actual problem."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
086 [fn-symbol args]
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
087 (if-not (:strict *options*)
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
088 (let
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
089 [q-name (if
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
090 (seq? fn-symbol)
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
091 (interpret-qualified-name fn-symbol)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
092 fn-symbol)
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
093 l-name (symbol (s/lower-case q-name))
|
||||
</span><br/>
|
||||
<span class="partial" title="1 out of 3 forms covered">
|
||||
094 f (cond
|
||||
</span><br/>
|
||||
<span class="partial" title="1 out of 2 forms covered">
|
||||
095 (try
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
096 (fn? (eval l-name))
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
097 (catch java.lang.ClassNotFoundException _ nil)) l-name
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
098 (try
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
099 (fn? (eval q-name))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
100 (catch java.lang.ClassNotFoundException _ nil)) q-name
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
101 :else (throw
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
102 (ex-info
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
103 (str "INTEROP: ungecnáwen þegnung `" fn-symbol "`")
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 7 forms covered">
|
||||
104 {:cause :interop
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
105 :detail :not-found
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
106 :name fn-symbol
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
107 :also-tried l-name})))
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
108 args' (to-clojure args)]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
109 ;; (print (str "INTEROP: eahtiende `" (cons f args') "`"))
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
110 (flush)
|
||||
</span><br/>
|
||||
<span class="covered" title="7 out of 7 forms covered">
|
||||
111 (let [result (eval (conj args' f))] ;; this has the potential to blow up the world
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
112 ;; (println (str "; ágiefende `" result "`"))
|
||||
</span><br/>
|
||||
<span class="partial" title="4 out of 6 forms covered">
|
||||
113 (cond
|
||||
</span><br/>
|
||||
<span class="partial" title="4 out of 5 forms covered">
|
||||
114 (instance? beowulf.cons_cell.ConsCell result) result
|
||||
</span><br/>
|
||||
<span class="partial" title="3 out of 6 forms covered">
|
||||
115 (coll? result) (make-beowulf-list result)
|
||||
</span><br/>
|
||||
<span class="partial" title="3 out of 4 forms covered">
|
||||
116 (symbol? result) result
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
117 (string? result) (symbol result)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
118 (number? result) result
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
119 :else (throw
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
120 (ex-info
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
121 (str "INTEROP: Ne can eahtiende `" result "` to Lisp 1.5.")
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
122 {:cause :interop
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
123 :detail :not-representable
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
124 :result result})))))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
125 (throw
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
126 (ex-info
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
127 (str "INTEROP ne āfand innan Lisp 1.5.")
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
128 {:cause :interop
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
129 :detail :strict}))))
|
||||
</span><br/>
|
||||
</body>
|
||||
</html>
|
521
docs/cloverage/beowulf/io.clj.html
Normal file
521
docs/cloverage/beowulf/io.clj.html
Normal file
|
@ -0,0 +1,521 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<link rel="stylesheet" href="../coverage.css"/> <title> beowulf/io.clj </title>
|
||||
</head>
|
||||
<body>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
001 (ns beowulf.io
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
002 "Non-standard extensions to Lisp 1.5 to read and write to the filesystem.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
003
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
004 Lisp 1.5 had only `READ`, which read one S-Expression at a time, and
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
005 various forms of `PRIN*` functions, which printed to the line printer.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
006 There was also `PUNCH`, which wrote to a card punch. It does not seem
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
007 that there was any concept of an interactive terminal.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
008
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
009 See Appendix E, `OVERLORD - THE MONITOR`, and Appendix F, `LISP INPUT
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
010 AND OUTPUT`.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
011
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
012 For our purposes, to save the current state of the Lisp system it should
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
013 be sufficient to print the current contents of the oblist to file; and to
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
014 restore a previous state from file, to overwrite the contents of the
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
015 oblist with data from that file.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
016
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
017 Hence functions SYSOUT and SYSIN, which do just that."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
018 (:require [beowulf.cons-cell :refer [make-beowulf-list make-cons-cell
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
019 pretty-print]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
020 [beowulf.host :refer [CADR CAR CDDR CDR]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
021 [beowulf.interop :refer [interpret-qualified-name
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
022 listify-qualified-name]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
023 [beowulf.oblist :refer [*options* NIL oblist]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
024 [beowulf.read :refer [READ]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
025 [clojure.java.io :refer [file resource]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
026 [clojure.string :refer [ends-with?]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
027 [java-time.api :refer [local-date local-date-time]]))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
028
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
029 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
030 ;;;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
031 ;;; Copyright (C) 2022-2023 Simon Brooke
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
032 ;;;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
033 ;;; This program is free software; you can redistribute it and/or
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
034 ;;; modify it under the terms of the GNU General Public License
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
035 ;;; as published by the Free Software Foundation; either version 2
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
036 ;;; of the License, or (at your option) any later version.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
037 ;;;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
038 ;;; This program is distributed in the hope that it will be useful,
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
039 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
040 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
041 ;;; GNU General Public License for more details.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
042 ;;;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
043 ;;; You should have received a copy of the GNU General Public License
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
044 ;;; along with this program; if not, write to the Free Software
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
045 ;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
046 ;;;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
047 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
048
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
049 (def ^:constant default-sysout "lisp1.5.lsp")
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
050
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
051 (defn- full-path
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
052 [fp]
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
053 (str
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
054 (if (:filepath *options*)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
055 (str (:filepath *options*) (java.io.File/separator))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
056 "")
|
||||
</span><br/>
|
||||
<span class="partial" title="12 out of 14 forms covered">
|
||||
057 (if (and (string? fp)
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
058 (> (count fp) 0)
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
059 (not= fp "NIL"))
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
060 fp
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
061 (str "Sysout-" (local-date)))
|
||||
</span><br/>
|
||||
<span class="partial" title="6 out of 7 forms covered">
|
||||
062 (if (ends-with? fp ".lsp")
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
063 ""
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
064 ".lsp")))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
065
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
066 ;; (find-var (symbol "beowulf.io/SYSIN"))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
067 ;; (@(resolve (symbol "beowulf.host/TIMES")) 2 2)
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
068
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
069 (defn safely-wrap-subr
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
070 [entry]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 7 forms covered">
|
||||
071 (cond (= entry NIL) NIL
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 7 forms covered">
|
||||
072 (= (CAR entry) 'SUBR) (make-cons-cell
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
073 (CAR entry)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
074 (make-cons-cell
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
075 (listify-qualified-name (CADR entry))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
076 (CDDR entry)))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
077 :else (make-cons-cell
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 8 forms covered">
|
||||
078 (CAR entry) (safely-wrap-subr (CDR entry)))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
079
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
080 (defn safely-wrap-subrs
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
081 [objects]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
082 (make-beowulf-list (map safely-wrap-subr objects)))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
083
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
084 (defn SYSOUT
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
085 "Dump the current content of the object list to file. If no `filepath` is
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
086 specified, a file name will be constructed of the symbol `Sysout` and
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
087 the current date. File paths will be considered relative to the filepath
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
088 set when starting Lisp.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
089
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
090 **NOTE THAT** this is an extension function, not available in strct mode."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
091 ([]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
092 (SYSOUT nil))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
093 ([filepath]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 7 forms covered">
|
||||
094 (spit (full-path (str filepath))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 15 forms covered">
|
||||
095 (with-out-str
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 9 forms covered">
|
||||
096 (println (apply str (repeat 79 ";")))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
097 (println (format ";; Beowulf %s Sysout file generated at %s"
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 7 forms covered">
|
||||
098 (or (System/getProperty "beowulf.version") "")
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
099 (local-date-time)))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
100 (when (System/getenv "USER")
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 7 forms covered">
|
||||
101 (println (format ";; generated by %s" (System/getenv "USER"))))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 9 forms covered">
|
||||
102 (println (apply str (repeat 79 ";")))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
103 (println)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
104 (let [output (safely-wrap-subrs @oblist)]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
105 (pretty-print output)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
106 )))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
107
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
108 (defn resolve-subr
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
109 "If this oblist `entry` references a subroutine, attempt to fix up that
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
110 reference."
|
||||
</span><br/>
|
||||
<span class="partial" title="1 out of 3 forms covered">
|
||||
111 ([entry]
|
||||
</span><br/>
|
||||
<span class="partial" title="9 out of 12 forms covered">
|
||||
112 (or (resolve-subr entry 'SUBR)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
113 (resolve-subr entry 'FSUBR)))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
114 ([entry prop]
|
||||
</span><br/>
|
||||
<span class="covered" title="7 out of 7 forms covered">
|
||||
115 (cond (= entry NIL) NIL
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
116 (= (CAR entry) prop) (try
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
117 (make-cons-cell
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
118 (CAR entry)
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
119 (make-cons-cell
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
120 (interpret-qualified-name
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
121 (CADR entry))
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
122 (CDDR entry)))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
123 (catch Exception _
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
124 (print "Warnung: ne can āfinde "
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
125 (CADR entry))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
126 (CDDR entry)))
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
127 :else (make-cons-cell
|
||||
</span><br/>
|
||||
<span class="covered" title="8 out of 8 forms covered">
|
||||
128 (CAR entry) (resolve-subr (CDR entry))))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
129
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
130
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
131 (defn- resolve-subroutines
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
132 "Attempt to fix up the references to subroutines (Clojure functions) among
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
133 these `objects`, being new content for the object list."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
134 [objects]
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
135 (make-beowulf-list
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
136 (map
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
137 resolve-subr
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
138 objects)))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
139
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
140 (defn SYSIN
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
141 "Read the contents of the file at this `filename` into the object list.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
142
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
143 If the file is not a valid Beowulf sysout file, this will probably
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
144 corrupt the system, you have been warned. File paths will be considered
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
145 relative to the filepath set when starting Lisp.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
146
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
147 It is intended that sysout files can be read both from resources within
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
148 the jar file, and from the file system. If a named file exists in both the
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
149 file system and the resources, the file system will be preferred.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
150
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
151 **NOTE THAT** if the provided `filename` does not end with `.lsp` (which,
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
152 if you're writing it from the Lisp REPL, it won't), the extension `.lsp`
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
153 will be appended.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
154
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
155 **NOTE THAT** this is an extension function, not available in strct mode."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
156 ([]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 13 forms covered">
|
||||
157 (SYSIN (or (:read *options*) (str "resources/" default-sysout))))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
158 ([filename]
|
||||
</span><br/>
|
||||
<span class="covered" title="8 out of 8 forms covered">
|
||||
159 (let [fp (file (full-path (str filename)))
|
||||
</span><br/>
|
||||
<span class="covered" title="9 out of 9 forms covered">
|
||||
160 file (when (and (.exists fp) (.canRead fp)) fp)
|
||||
</span><br/>
|
||||
<span class="partial" title="4 out of 5 forms covered">
|
||||
161 res (try (resource filename)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
162 (catch Throwable _ nil))
|
||||
</span><br/>
|
||||
<span class="covered" title="11 out of 11 forms covered">
|
||||
163 content (try (READ (slurp (or file res)))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
164 (catch Throwable _
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
165 (throw (ex-info "Ne can ārǣde"
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
166 {:context "SYSIN"
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
167 :filename filename
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
168 :filepath fp}))))]
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
169 (swap! oblist
|
||||
</span><br/>
|
||||
<span class="partial" title="7 out of 10 forms covered">
|
||||
170 #(when (or % (seq content))
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
171 (resolve-subroutines content))))))
|
||||
</span><br/>
|
||||
</body>
|
||||
</html>
|
2315
docs/cloverage/beowulf/manual.clj.html
Normal file
2315
docs/cloverage/beowulf/manual.clj.html
Normal file
File diff suppressed because it is too large
Load diff
143
docs/cloverage/beowulf/oblist.clj.html
Normal file
143
docs/cloverage/beowulf/oblist.clj.html
Normal file
|
@ -0,0 +1,143 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<link rel="stylesheet" href="../coverage.css"/> <title> beowulf/oblist.clj </title>
|
||||
</head>
|
||||
<body>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
001 (ns beowulf.oblist
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
002 "A namespace mainly devoted to the object list and other top level
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
003 global variables.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
004
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
005 Yes, this makes little sense, but if you put them anywhere else you end
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
006 up in cyclic dependency hell."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
007 )
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
008
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
009 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
010 ;;;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
011 ;;; Copyright (C) 2022-2023 Simon Brooke
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
012 ;;;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
013 ;;; This program is free software; you can redistribute it and/or
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
014 ;;; modify it under the terms of the GNU General Public License
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
015 ;;; as published by the Free Software Foundation; either version 2
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
016 ;;; of the License, or (at your option) any later version.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
017 ;;;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
018 ;;; This program is distributed in the hope that it will be useful,
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
019 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
020 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
021 ;;; GNU General Public License for more details.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
022 ;;;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
023 ;;; You should have received a copy of the GNU General Public License
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
024 ;;; along with this program; if not, write to the Free Software
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
025 ;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
026 ;;;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
027 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
028
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
029 (def NIL
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
030 "The canonical empty list symbol.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
031
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
032 TODO: this doesn't really work, because (from Clojure) `(empty? NIL)` throws
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
033 an exception. It might be better to subclass beowulf.cons_cell.ConsCell to create
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
034 a new singleton class Nil which overrides the `empty` method of
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
035 IPersistentCollection?"
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
036 'NIL)
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
037
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
038 (def oblist
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
039 "The default environment."
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
040 (atom NIL))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
041
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
042 (def ^:dynamic *options*
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
043 "Command line options from invocation."
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
044 {:testing true})
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
045
|
||||
</span><br/>
|
||||
</body>
|
||||
</html>
|
File diff suppressed because it is too large
Load diff
329
docs/cloverage/beowulf/reader/char_reader.clj.html
Normal file
329
docs/cloverage/beowulf/reader/char_reader.clj.html
Normal file
|
@ -0,0 +1,329 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<link rel="stylesheet" href="../../coverage.css"/> <title> beowulf/reader/char_reader.clj </title>
|
||||
</head>
|
||||
<body>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
001 (ns beowulf.reader.char-reader
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
002 "Provide sensible line editing, auto completion, and history recall.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
003
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
004 None of what's needed here is really working yet, and a pull request with
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
005 a working implementation would be greatly welcomed.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
006
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
007 ## What's needed (rough specification)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
008
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
009 1. Carriage return **does not** cause input to be returned, **unless**
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
010 a. the number of open brackets `(` and closing brackets `)` match; and
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
011 b. the number of open square brackets `[` and closing square brackets `]` also match;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
012 2. <Ctrl-D> aborts editing and returns the string `STOP`;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
013 3. <Up-arrow> and <down-arrow> scroll back and forward through history, but ideally I'd like
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
014 this to be the Lisp history (i.e. the history of S-Expressions actually read by `READ`,
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
015 rather than the strings which were supplied to `READ`);
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
016 4. <Tab> offers potential auto-completions taken from the value of `(OBLIST)`, ideally the
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
017 current value, not the value at the time the session started;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
018 5. <Back-arrow> and <Forward-arrow> offer movement and editing within the line.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
019
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
020 TODO: There are multiple problems with JLine; a better solution might be
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
021 to start from here:
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
022 https://stackoverflow.com/questions/7931988/how-to-manipulate-control-characters"
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
023 (:require [beowulf.oblist :refer [*options* oblist]])
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
024 (:import [org.jline.reader.impl.completer StringsCompleter]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
025 [org.jline.reader.impl DefaultParser DefaultParser$Bracket]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
026 [org.jline.reader LineReaderBuilder]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
027 [org.jline.terminal TerminalBuilder]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
028 [org.jline.widget AutopairWidgets AutosuggestionWidgets]))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
029
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
030 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
031 ;;;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
032 ;;; Copyright (C) 2022-2023 Simon Brooke
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
033 ;;;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
034 ;;; This program is free software; you can redistribute it and/or
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
035 ;;; modify it under the terms of the GNU General Public License
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
036 ;;; as published by the Free Software Foundation; either version 2
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
037 ;;; of the License, or (at your option) any later version.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
038 ;;;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
039 ;;; This program is distributed in the hope that it will be useful,
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
040 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
041 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
042 ;;; GNU General Public License for more details.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
043 ;;;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
044 ;;; You should have received a copy of the GNU General Public License
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
045 ;;; along with this program; if not, write to the Free Software
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
046 ;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
047 ;;;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
048 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
049
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
050 ;; It looks from the example given [here](https://github.com/jline/jline3/blob/master/demo/src/main/java/org/jline/demo/Repl.java)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
051 ;; as though JLine could be used to build a perfect line-reader for Beowulf; but it also
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
052 ;; looks as though you'd need a DPhil in JLine to write it, and I don't have
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
053 ;; the time.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
054
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
055 (defn build-completer
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
056 "Build a completer which takes tokens from the oblist.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
057
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
058 This is sort-of working, in as much as hitting <TAB> on a blank line will
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
059 show a table of values from the oblist, but hitting <TAB> after you've
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
060 started input does not show potential completions for tokens you've started."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
061 []
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 12 forms covered">
|
||||
062 (StringsCompleter. (map #(str (first %)) @oblist)))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
063
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
064 ;; This breaks; it is not correctly resolving the Enum, although I can't work out
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
065 ;; why not.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
066 ;; (defn build-parser
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
067 ;; []
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
068 ;; (println "Building parser")
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
069 ;; (let [parser (DefaultParser.)]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
070 ;; (doall
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
071 ;; (.setEofOnUnclosedBracket
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
072 ;; parser DefaultParser$Bracket/ROUND))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
073
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
074 (def get-reader
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
075 "Return a reader, first constructing it if necessary.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
076
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
077 **NOTE THAT** this is not settled API. The existence and call signature of
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
078 this function is not guaranteed in future versions."
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
079 (memoize (fn []
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
080 (let [term (.build (.system (TerminalBuilder/builder) true))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
081 reader (-> (LineReaderBuilder/builder)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
082 (.terminal term)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
083 (.completer (build-completer))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
084 ;; #(.parser % (build-parser))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
085 (.build))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
086 ;; apw (AutopairWidgets. reader false)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
087 ;; asw (AutosuggestionWidgets. reader)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
088 ]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
089 ;; (.enable apw)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
090 ;; (.enable asw)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
091 reader))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
092
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
093 (defn read-chars
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
094 "A drop-in replacement for `clojure.core/read-line`, except that line editing
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
095 and history should be enabled.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
096
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
097 **NOTE THAT** this does not fully work yet, but it is in the API because I
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
098 hope that it will work later!"
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
099 [prompt]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
100 (let [eddie (get-reader)]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
101 (loop [s (.readLine eddie (str prompt " "))]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 12 forms covered">
|
||||
102 (if (and (= (count (re-seq #"\(" s))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
103 (count (re-seq #"\)" s)))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
104 (= (count (re-seq #"\[]" s))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
105 (count (re-seq #"\]" s))))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
106 s
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
107 (recur (str s " " (.readLine eddie ":: ")))))))
|
||||
</span><br/>
|
||||
</body>
|
||||
</html>
|
836
docs/cloverage/beowulf/reader/generate.clj.html
Normal file
836
docs/cloverage/beowulf/reader/generate.clj.html
Normal file
|
@ -0,0 +1,836 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<link rel="stylesheet" href="../../coverage.css"/> <title> beowulf/reader/generate.clj </title>
|
||||
</head>
|
||||
<body>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
001 (ns beowulf.reader.generate
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
002 "Generating S-Expressions from parse trees.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
003
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
004 ## From Lisp 1.5 Programmers Manual, page 10
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
005 *Note that I've retyped much of this, since copy/pasting out of PDF is less
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
006 than reliable. Any typos are mine.*
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
007
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
008 *Quote starts:*
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
009
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
010 We are now in a position to define the universal LISP function
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
011 `evalquote[fn;args]`, When evalquote is given a function and a list of arguments
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
012 for that function, it computes the value of the function applied to the arguments.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
013 LISP functions have S-expressions as arguments. In particular, the argument `fn`
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
014 of the function evalquote must be an S-expression. Since we have been
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
015 writing functions as M-expressions, it is necessary to translate them into
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
016 S-expressions.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
017
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
018 The following rules define a method of translating functions written in the
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
019 meta-language into S-expressions.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
020 1. If the function is represented by its name, it is translated by changing
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
021 all of the letters to upper case, making it an atomic symbol. Thus `car` is
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
022 translated to `CAR`.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
023 2. If the function uses the lambda notation, then the expression
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
024 `λ[[x ..;xn]; ε]` is translated into `(LAMBDA (X1 ...XN) ε*)`, where ε* is the translation
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
025 of ε.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
026 3. If the function begins with label, then the translation of
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
027 `label[α;ε]` is `(LABEL α* ε*)`.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
028
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
029 Forms are translated as follows:
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
030 1. A variable, like a function name, is translated by using uppercase letters.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
031 Thus the translation of `var1` is `VAR1`.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
032 2. The obvious translation of letting a constant translate into itself will not
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
033 work. Since the translation of `x` is `X`, the translation of `X` must be something
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
034 else to avoid ambiguity. The solution is to quote it. Thus `X` is translated
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
035 into `(QUOTE X)`.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
036 3. The form `fn[argl;. ..;argn]` is translated into `(fn* argl* ...argn*)`
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
037 4. The conditional expression `[pl-el;...;pn-en]` is translated into
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
038 `(COND (p1* e1*)...(pn* en*))`
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
039
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
040 ## Examples
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
041 ```
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
042 M-expressions S-expressions
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
043
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
044 x X
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
045 car CAR
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
046 car[x] (CAR X)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
047 T (QUOTE T)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
048 ff[car [x]] (FF (CAR X))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
049 [atom[x]->x; T->ff[car[x]]] (COND ((ATOM X) X)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
050 ((QUOTE T)(FF (CAR X))))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
051 label[ff;λ[[x];[atom[x]->x; (LABEL FF (LAMBDA (X)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
052 T->ff[car[x]]]]] (COND ((ATOM X) X)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
053 ((QUOTE T)(FF (CAR X))))))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
054 ```
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
055
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
056 *quote ends*
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
057 "
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
058 (:require [beowulf.cons-cell :refer [make-beowulf-list make-cons-cell]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
059 [beowulf.reader.macros :refer [expand-macros]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
060 [beowulf.oblist :refer [NIL]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
061 [clojure.math.numeric-tower :refer [expt]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
062 [clojure.string :refer [upper-case]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
063 [clojure.tools.trace :refer [deftrace]]))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
064
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
065 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
066 ;;;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
067 ;;; Copyright (C) 2022-2023 Simon Brooke
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
068 ;;;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
069 ;;; This program is free software; you can redistribute it and/or
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
070 ;;; modify it under the terms of the GNU General Public License
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
071 ;;; as published by the Free Software Foundation; either version 2
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
072 ;;; of the License, or (at your option) any later version.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
073 ;;;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
074 ;;; This program is distributed in the hope that it will be useful,
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
075 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
076 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
077 ;;; GNU General Public License for more details.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
078 ;;;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
079 ;;; You should have received a copy of the GNU General Public License
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
080 ;;; along with this program; if not, write to the Free Software
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
081 ;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
082 ;;;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
083 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
084
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
085 (declare generate)
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
086
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
087 (defn gen-cond-clause
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
088 "Generate a cond clause from this simplified parse tree fragment `p`;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
089 returns `nil` if `p` does not represent a cond clause."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
090 [p context]
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
091 (when
|
||||
</span><br/>
|
||||
<span class="partial" title="11 out of 12 forms covered">
|
||||
092 (and (coll? p) (= :cond-clause (first p)))
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
093 (make-beowulf-list
|
||||
</span><br/>
|
||||
<span class="partial" title="12 out of 13 forms covered">
|
||||
094 (list (if (= (nth p 1) [:quoted-expr [:atom "T"]])
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
095 'T
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
096 (generate (nth p 1) context))
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
097 (generate (nth p 2) context)))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
098
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
099 (defn gen-cond
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
100 "Generate a cond statement from this simplified parse tree fragment `p`;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
101 returns `nil` if `p` does not represent a (MEXPR) cond statement."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
102 [p context]
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
103 (when
|
||||
</span><br/>
|
||||
<span class="partial" title="11 out of 12 forms covered">
|
||||
104 (and (coll? p) (= :cond (first p)))
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
105 (make-beowulf-list
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
106 (cons
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
107 'COND
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
108 (map
|
||||
</span><br/>
|
||||
<span class="partial" title="8 out of 9 forms covered">
|
||||
109 #(generate % (if (= context :mexpr) :cond-mexpr context))
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
110 (rest p))))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
111
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
112 (defn gen-fn-call
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
113 "Generate a function call from this simplified parse tree fragment `p`;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
114 returns `nil` if `p` does not represent a (MEXPR) function call."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
115 [p context]
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
116 (when
|
||||
</span><br/>
|
||||
<span class="partial" title="21 out of 23 forms covered">
|
||||
117 (and (coll? p) (= :fncall (first p)) (= :mvar (first (second p))))
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
118 (make-cons-cell
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
119 (generate (second p) context)
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
120 (generate (nth p 2) context))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
121
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
122
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
123 (defn gen-dot-terminated-list
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
124 "Generate a list, which may be dot-terminated, from this partial parse tree
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
125 'p'. Note that the function acts recursively and progressively decapitates
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
126 its argument, so that the argument will not always be a valid parse tree."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
127 [p]
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
128 (cond
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
129 (empty? p)
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
130 NIL
|
||||
</span><br/>
|
||||
<span class="partial" title="15 out of 16 forms covered">
|
||||
131 (and (coll? (first p)) (= :dot-terminal (first (first p))))
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
132 (let [dt (first p)]
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
133 (make-cons-cell
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
134 (generate (nth dt 1))
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
135 (generate (nth dt 2))))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
136 :else
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
137 (make-cons-cell
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
138 (generate (first p))
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
139 (gen-dot-terminated-list (rest p)))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
140
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
141 ;; null[x] = [x = NIL -> T; T -> F]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
142 ;; [:defn
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
143 ;; [:mexpr [:fncall [:mvar "null"] [:bindings [:args [:mexpr [:mvar "x"]]]]]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
144 ;; "="
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
145 ;; [:mexpr [:cond
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
146 ;; [:cond-clause [:mexpr [:iexpr [:lhs [:mexpr [:mvar "x"]]] [:iop "="] [:rhs [:mexpr [:mconst "NIL"]]]]] [:mexpr [:mconst "T"]]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
147 ;; [:cond-clause [:mexpr [:mconst "T"]] [:mexpr [:mconst "F"]]]]]]
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
148
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
149 (defn generate-defn
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
150 [tree context]
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
151 (if (= :mexpr (first tree))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
152 (generate-defn (second tree) context)
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
153 (make-beowulf-list
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
154 (list 'PUT
|
||||
</span><br/>
|
||||
<span class="covered" title="13 out of 13 forms covered">
|
||||
155 (list 'QUOTE (generate (-> tree second second second) context))
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
156 (list 'QUOTE 'EXPR)
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
157 (list 'QUOTE
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
158 (cons 'LAMBDA
|
||||
</span><br/>
|
||||
<span class="covered" title="12 out of 12 forms covered">
|
||||
159 (list (generate (nth (-> tree second second) 2) context)
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
160 (generate (nth tree 3) context))))))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
161
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
162 (defn gen-iexpr
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
163 [tree context]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 11 forms covered">
|
||||
164 (let [bundle (reduce #(assoc %1 (first %2) %2)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
165 {}
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
166 (rest tree))]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 8 forms covered">
|
||||
167 (list (generate (:iop bundle) context)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
168 (generate (:lhs bundle) context)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
169 (generate (:rhs bundle) context))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
170
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
171 (defn generate-set
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
172 "Actually not sure what the mexpr representation of set looks like"
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
173 [tree context]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 7 forms covered">
|
||||
174 (throw (ex-info "Not Yet Implemented" {:feature "generate-set"})))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
175
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
176 (defn generate-assign
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
177 "Generate an assignment statement based on this `tree`. If the thing
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
178 being assigned to is a function signature, then we have to do something
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
179 different to if it's an atom."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
180 [tree context]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 13 forms covered">
|
||||
181 (case (first (second tree))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
182 :fncall (generate-defn tree context)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 12 forms covered">
|
||||
183 :mexpr (map #(generate % context) (rest (second tree)))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 8 forms covered">
|
||||
184 (:mvar :atom) (generate-set tree context)))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
185
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
186 (defn strip-leading-zeros
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
187 "`read-string` interprets strings with leading zeros as octal; strip
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
188 any from this string `s`. If what's left is empty (i.e. there were
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
189 only zeros, return `\"0\"`."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
190 ([s]
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
191 (strip-leading-zeros s ""))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
192 ([s prefix]
|
||||
</span><br/>
|
||||
<span class="partial" title="1 out of 2 forms covered">
|
||||
193 (if
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
194 (empty? s) "0"
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
195 (case (first s)
|
||||
</span><br/>
|
||||
<span class="partial" title="12 out of 24 forms covered">
|
||||
196 (\+ \-) (strip-leading-zeros (subs s 1) (str (first s) prefix))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 7 forms covered">
|
||||
197 "0" (strip-leading-zeros (subs s 1) prefix)
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
198 (str prefix s)))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
199
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
200 (defn generate
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
201 "Generate lisp structure from this parse tree `p`. It is assumed that
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
202 `p` has been simplified."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
203 ([p]
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
204 (generate p :expr))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
205 ([p context]
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
206 (try
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
207 (expand-macros
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
208 (if
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
209 (coll? p)
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
210 (case (first p)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
211 :λ "LAMBDA"
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
212 :λexpr (make-cons-cell
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
213 (generate (nth p 1) context)
|
||||
</span><br/>
|
||||
<span class="covered" title="8 out of 8 forms covered">
|
||||
214 (make-cons-cell (generate (nth p 2) context)
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
215 (generate (nth p 3) context)))
|
||||
</span><br/>
|
||||
<span class="covered" title="12 out of 12 forms covered">
|
||||
216 :args (make-beowulf-list (map #(generate % context) (rest p)))
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
217 :atom (symbol (second p))
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
218 :bindings (generate (second p) context)
|
||||
</span><br/>
|
||||
<span class="covered" title="12 out of 12 forms covered">
|
||||
219 :body (make-beowulf-list (map #(generate % context) (rest p)))
|
||||
</span><br/>
|
||||
<span class="covered" title="12 out of 12 forms covered">
|
||||
220 (:coefficient :exponent) (generate (second p) context)
|
||||
</span><br/>
|
||||
<span class="partial" title="8 out of 9 forms covered">
|
||||
221 :cond (gen-cond p (if (= context :mexpr) :cond-mexpr context))
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
222 :cond-clause (gen-cond-clause p context)
|
||||
</span><br/>
|
||||
<span class="covered" title="11 out of 11 forms covered">
|
||||
223 :decimal (read-string (apply str (map second (rest p))))
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
224 :defn (generate-defn p context)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
225 :dotted-pair (make-cons-cell
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
226 (generate (nth p 1) context)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
227 (generate (nth p 2) context))
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
228 :fncall (gen-fn-call p context)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
229 :iexpr (gen-iexpr p context)
|
||||
</span><br/>
|
||||
<span class="covered" title="7 out of 7 forms covered">
|
||||
230 :integer (read-string (strip-leading-zeros (second p)))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 11 forms covered">
|
||||
231 :iop (case (second p)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
232 "/" 'DIFFERENCE
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
233 "=" 'EQUAL
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
234 ">" 'GREATERP
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
235 "<" 'LESSP
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
236 "+" 'PLUS
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
237 "*" 'TIMES
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
238 ;; else
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
239 (throw (ex-info "Unrecognised infix operator symbol"
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
240 {:phase :generate
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
241 :fragment p})))
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
242 :list (gen-dot-terminated-list (rest p))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 12 forms covered">
|
||||
243 (:lhs :rhs) (generate (second p) context)
|
||||
</span><br/>
|
||||
<span class="covered" title="11 out of 11 forms covered">
|
||||
244 :mexpr (generate (second p) (if (= context :cond-mexpr) context :mexpr))
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
245 :mconst (if (= context :cond-mexpr)
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
246 (case (second p)
|
||||
</span><br/>
|
||||
<span class="partial" title="5 out of 15 forms covered">
|
||||
247 ("T" "F" "NIL") (symbol (second p))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
248 ;; else
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 8 forms covered">
|
||||
249 (list 'QUOTE (symbol (second p))))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
250 ;; else
|
||||
</span><br/>
|
||||
<span class="covered" title="8 out of 8 forms covered">
|
||||
251 (list 'QUOTE (symbol (second p))))
|
||||
</span><br/>
|
||||
<span class="covered" title="7 out of 7 forms covered">
|
||||
252 :mvar (symbol (upper-case (second p)))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
253 :number (generate (second p) context)
|
||||
</span><br/>
|
||||
<span class="covered" title="9 out of 9 forms covered">
|
||||
254 :octal (let [n (read-string (strip-leading-zeros (second p) "0"))
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
255 scale (generate (nth p 3) context)]
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
256 (* n (expt 8 scale)))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
257
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
258 ;; the quote read macro (which probably didn't exist in Lisp 1.5, but...)
|
||||
</span><br/>
|
||||
<span class="covered" title="11 out of 11 forms covered">
|
||||
259 :quoted-expr (make-beowulf-list (list 'QUOTE (generate (second p) context)))
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
260 :scale-factor (if
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
261 (empty? (second p)) 0
|
||||
</span><br/>
|
||||
<span class="covered" title="7 out of 7 forms covered">
|
||||
262 (read-string (strip-leading-zeros (second p))))
|
||||
</span><br/>
|
||||
<span class="covered" title="7 out of 7 forms covered">
|
||||
263 :scientific (let [n (generate (second p) context)
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
264 exponent (generate (nth p 3) context)]
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
265 (* n (expt 10 exponent)))
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
266 :sexpr (generate (second p) :sexpr)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
267 :subr (symbol (second p))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
268
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
269 ;; default
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 9 forms covered">
|
||||
270 (throw (ex-info (str "Unrecognised head: " (first p))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
271 {:generating p})))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
272 p))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
273 (catch Throwable any
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
274 (throw (ex-info "Could not generate"
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
275 {:generating p}
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
276 any))))))
|
||||
</span><br/>
|
||||
</body>
|
||||
</html>
|
212
docs/cloverage/beowulf/reader/macros.clj.html
Normal file
212
docs/cloverage/beowulf/reader/macros.clj.html
Normal file
|
@ -0,0 +1,212 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<link rel="stylesheet" href="../../coverage.css"/> <title> beowulf/reader/macros.clj </title>
|
||||
</head>
|
||||
<body>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
001 (ns beowulf.reader.macros
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
002 "Can I implement reader macros? let's see!
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
003
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
004 We don't need (at least, in the Clojure reader) to rewrite forms like
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
005 `'FOO`, because that's handled by the parser. But we do need to rewrite
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
006 things which don't evaluate their arguments, like `SETQ`, because (unless
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
007 LABEL does it, which I'm not yet sure of) we're not yet able to implement
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
008 things which don't evaluate arguments.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
009
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
010 TODO: at this stage, the following should probably also be read macros:
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
011 DEFINE"
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
012 (:require [beowulf.cons-cell :refer [make-beowulf-list]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
013 [beowulf.host :refer [CONS LIST]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
014 [clojure.string :refer [join]]))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
015
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
016 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
017 ;;;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
018 ;;; We don't need (at least, in the Clojure reader) to rewrite forms like
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
019 ;;; "'FOO", because that's handled by the parser. But we do need to rewrite
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
020 ;;; things which don't evaluate their arguments, like `SETQ`, because (unless
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
021 ;;; LABEL does it, which I'm not yet sure of) we're not yet able to implement
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
022 ;;; things which don't evaluate arguments.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
023 ;;;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
024 ;;; TODO: at this stage, the following should probably also be read macros:
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
025 ;;; DEFINE
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
026 ;;;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
027 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
028 ;;;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
029 ;;; Copyright (C) 2022-2023 Simon Brooke
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
030 ;;;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
031 ;;; This program is free software; you can redistribute it and/or
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
032 ;;; modify it under the terms of the GNU General Public License
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
033 ;;; as published by the Free Software Foundation; either version 2
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
034 ;;; of the License, or (at your option) any later version.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
035 ;;;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
036 ;;; This program is distributed in the hope that it will be useful,
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
037 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
038 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
039 ;;; GNU General Public License for more details.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
040 ;;;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
041 ;;; You should have received a copy of the GNU General Public License
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
042 ;;; along with this program; if not, write to the Free Software
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
043 ;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
044 ;;;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
045 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
046
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
047 (def ^:dynamic *readmacros*
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
048 {:car {'DEFUN (fn [f]
|
||||
</span><br/>
|
||||
<span class="covered" title="9 out of 9 forms covered">
|
||||
049 (LIST 'SET (LIST 'QUOTE (second f))
|
||||
</span><br/>
|
||||
<span class="covered" title="11 out of 11 forms covered">
|
||||
050 (LIST 'QUOTE (CONS 'LAMBDA (rest (rest f))))))
|
||||
</span><br/>
|
||||
<span class="covered" title="13 out of 13 forms covered">
|
||||
051 'SETQ (fn [f] (LIST 'SET (LIST 'QUOTE (second f)) (nth f 2)))}})
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
052
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
053 (defn expand-macros
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
054 [form]
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
055 (try
|
||||
</span><br/>
|
||||
<span class="covered" title="19 out of 19 forms covered">
|
||||
056 (if-let [car (when (and (coll? form) (symbol? (first form)))
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
057 (first form))]
|
||||
</span><br/>
|
||||
<span class="covered" title="10 out of 10 forms covered">
|
||||
058 (if-let [macro (-> *readmacros* :car car)]
|
||||
</span><br/>
|
||||
<span class="covered" title="8 out of 8 forms covered">
|
||||
059 (make-beowulf-list (apply macro (list form)))
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
060 form)
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
061 form)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
062 (catch Exception any
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
063 (println (join "\n"
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
064 ["# ERROR while expanding macro:"
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
065 (str "# Form: " form)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
066 (str "# Error class: " (.getName (.getClass any)))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
067 (str "# Message: " (.getMessage any))]))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
068 form)))
|
||||
</span><br/>
|
||||
</body>
|
||||
</html>
|
368
docs/cloverage/beowulf/reader/parser.clj.html
Normal file
368
docs/cloverage/beowulf/reader/parser.clj.html
Normal file
|
@ -0,0 +1,368 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<link rel="stylesheet" href="../../coverage.css"/> <title> beowulf/reader/parser.clj </title>
|
||||
</head>
|
||||
<body>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
001 (ns beowulf.reader.parser
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
002 "The actual parser, supporting both S-expression and M-expression syntax."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
003 (:require [instaparse.core :as i]))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
004
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
005 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
006 ;;;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
007 ;;; Copyright (C) 2022-2023 Simon Brooke
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
008 ;;;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
009 ;;; This program is free software; you can redistribute it and/or
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
010 ;;; modify it under the terms of the GNU General Public License
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
011 ;;; as published by the Free Software Foundation; either version 2
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
012 ;;; of the License, or (at your option) any later version.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
013 ;;;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
014 ;;; This program is distributed in the hope that it will be useful,
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
015 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
016 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
017 ;;; GNU General Public License for more details.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
018 ;;;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
019 ;;; You should have received a copy of the GNU General Public License
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
020 ;;; along with this program; if not, write to the Free Software
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
021 ;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
022 ;;;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
023 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
024
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
025 (def parse
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
026 "Parse a string presented as argument into a parse tree which can then
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
027 be operated upon further."
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
028 (i/parser
|
||||
</span><br/>
|
||||
<span class="covered" title="13 out of 13 forms covered">
|
||||
029 (str
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
030 ;; we tolerate whitespace and comments around legitimate input
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
031 "raw := expr | opt-comment expr opt-comment;"
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
032 ;; top level: we accept mexprs as well as sexprs.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
033 "expr := mexpr | sexpr ;"
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
034
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
035 ;; comments. I'm pretty confident Lisp 1.5 did NOT have these.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
036 "comment := opt-space <';;'> opt-space #'[^\\n\\r]*';"
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
037
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
038 ;; there's a notation comprising a left brace followed by mexprs
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
039 ;; followed by a right brace which doesn't seem to be documented
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
040 ;; but I think must represent assembly code(?)
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
041
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
042 ;; "assembly := lbrace exprs rbrace;"
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
043
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
044 ;; mexprs. I'm pretty clear that Lisp 1.5 could never read these,
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
045 ;; but it's a convenience.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
046
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
047 ;; TODO: this works for now but in fact the Programmer's Manual
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
048 ;; gives a much simpler formulation of M-expression grammar on
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
049 ;; page 9, and of the S-expression grammar on page 8. It would
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
050 ;; be worth going back and redoing this from the book.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
051
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
052 "exprs := expr | exprs;"
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
053 "mexpr := λexpr | fncall | defn | cond | mvar | mconst | iexpr | number | mexpr comment;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
054 λexpr := λ lsqb bindings semi-colon opt-space body opt-space rsqb;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
055 λ := 'λ' | 'lambda';
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
056 bindings := lsqb args rsqb | lsqb rsqb;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
057 body := (opt-space mexpr semi-colon)* opt-space mexpr;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
058 fncall := fn-name bindings;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
059 lsqb := '[';
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
060 rsqb := ']';
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
061 lbrace := '{';
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
062 rbrace := '}';
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
063 defn := mexpr opt-space '=' opt-space mexpr;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
064 cond := lsqb (opt-space cond-clause semi-colon opt-space)* cond-clause rsqb;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
065 cond-clause := mexpr opt-space arrow opt-space mexpr opt-space;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
066 arrow := '->';
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
067 args := arg | (opt-space arg semi-colon opt-space)* opt-space arg opt-space;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
068 arg := mexpr;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
069 fn-name := mvar;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
070 mvar := #'[a-z][a-z0-9]*';
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
071 mconst := #'[A-Z][A-Z0-9]*';
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
072 semi-colon := ';';"
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
073
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
074 ;; Infix operators appear in mexprs, e.g. on page 7. Ooops!
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
075 ;; I do not know what infix operators are considered legal.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
076 ;; In particular I do not know what symbol was used for
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
077 ;; multiply
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
078 "iexpr := iexp iop iexp;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
079 iexp := mexpr | number | opt-space iexp opt-space;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
080 iop := '>' | '<' | '+' | '-' | '*' '/' | '=' ;"
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
081
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
082 ;; comments. I'm pretty confident Lisp 1.5 did NOT have these.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
083 "opt-comment := opt-space | comment;"
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
084 "comment := opt-space <';;'> #'[^\\n\\r]*' opt-space;"
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
085
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
086 ;; sexprs. Note it's not clear to me whether Lisp 1.5 had the quote macro,
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
087 ;; but I've included it on the basis that it can do little harm.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
088 "sexpr := quoted-expr | atom | number | subr | dotted-pair | list | sexpr comment;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
089 list := lpar sexpr rpar | lpar (sexpr sep)* rpar | lpar (sexpr sep)* dot-terminal | lbrace exprs rbrace;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
090 list := lpar opt-space sexpr rpar | lpar opt-space (sexpr sep)* rpar | lpar opt-space (sexpr sep)* dot-terminal;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
091 dotted-pair := lpar dot-terminal ;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
092 dot := '.';
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
093 lpar := '(';
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
094 rpar := ')';
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
095 quoted-expr := quote sexpr;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
096 quote := '\\'';
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
097 dot-terminal := sexpr space dot space sexpr rpar;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
098 space := #'\\p{javaWhitespace}+';
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
099 opt-space := #'\\p{javaWhitespace}*';
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
100 sep := ',' | opt-space;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
101 atom := #'[A-Z][A-Z0-9]*';"
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
102
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
103 ;; we need a way of representing Clojure functions on the object list;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
104 ;; subr objects aren't expected to be normally entered on the REPL, but
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
105 ;; must be on the object list or functions to which functions are passed
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
106 ;; won't be able to access them.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
107 "subr := #'[a-z][a-z.]*/[A-Za-z][A-Za-z0-9]*';"
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
108
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
109 ;; Lisp 1.5 supported octal as well as decimal and scientific notation
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
110 "number := integer | decimal | scientific | octal;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
111 integer := #'-?[0-9]+';
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
112 decimal := integer dot integer;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
113 scientific := coefficient e exponent;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
114 coefficient := decimal | integer;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
115 exponent := integer;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
116 e := 'E';
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
117 octal := #'[+-]?[0-7]+{1,12}' q scale-factor;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
118 q := 'Q';
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
119 scale-factor := #'[0-9]*'")))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
120
|
||||
</span><br/>
|
||||
</body>
|
||||
</html>
|
401
docs/cloverage/beowulf/reader/simplify.clj.html
Normal file
401
docs/cloverage/beowulf/reader/simplify.clj.html
Normal file
|
@ -0,0 +1,401 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<link rel="stylesheet" href="../../coverage.css"/> <title> beowulf/reader/simplify.clj </title>
|
||||
</head>
|
||||
<body>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
001 (ns beowulf.reader.simplify
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
002 "Simplify parse trees. Be aware that this is very tightly coupled
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
003 with the parser."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
004 (:require [beowulf.oblist :refer [*options*]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
005 [instaparse.failure :as f])
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
006 (:import [instaparse.gll Failure]))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
007
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
008 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
009 ;;;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
010 ;;; Copyright (C) 2022-2023 Simon Brooke
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
011 ;;;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
012 ;;; This program is free software; you can redistribute it and/or
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
013 ;;; modify it under the terms of the GNU General Public License
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
014 ;;; as published by the Free Software Foundation; either version 2
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
015 ;;; of the License, or (at your option) any later version.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
016 ;;;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
017 ;;; This program is distributed in the hope that it will be useful,
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
018 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
019 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
020 ;;; GNU General Public License for more details.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
021 ;;;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
022 ;;; You should have received a copy of the GNU General Public License
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
023 ;;; along with this program; if not, write to the Free Software
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
024 ;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
025 ;;;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
026 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
027
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
028 (declare simplify-tree)
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
029
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
030 (defn remove-optional-space
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
031 [tree]
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
032 (if (vector? tree)
|
||||
</span><br/>
|
||||
<span class="covered" title="7 out of 7 forms covered">
|
||||
033 (if (= :opt-space (first tree))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
034 nil
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
035 (let [v (remove nil?
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
036 (map remove-optional-space tree))]
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
037 (if (seq v)
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
038 (apply vector v)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
039 v)))
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
040 tree))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
041
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
042 (defn remove-nesting
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
043 [tree context]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
044 (let [tree' (remove-optional-space tree)]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 15 forms covered">
|
||||
045 (if-let [key (when (and (vector? tree')
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
046 (keyword? (first tree')))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
047 (first tree'))]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
048 (loop [r tree']
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 18 forms covered">
|
||||
049 (if (and r (vector? r) (keyword? (first r)))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
050 (if (= (first r) key)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
051 (recur (simplify-tree (second r) context))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
052 r)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
053 r))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
054 tree')))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
055
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
056 (defn simplify-tree
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
057 "Simplify this parse tree `p`. If `p` is an instaparse failure object, throw
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
058 an `ex-info`, with `p` as the value of its `:failure` key.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
059
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
060 **NOTE THAT** it is assumed that `remove-optional-space` has been run on the
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
061 parse tree **BEFORE** it is passed to `simplify-tree`."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
062 ([p]
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
063 (if
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
064 (instance? Failure p)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
065 (throw (ex-info
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
066 (str "Ic ne behæfd: " (f/pprint-failure p))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
067 {:cause :parse-failure
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
068 :phase :simplify
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
069 :failure p}))
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
070 (simplify-tree p :expr)))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
071 ([p context]
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
072 (cond
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
073 (string? p) p
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
074 (coll? p) (apply
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
075 vector
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
076 (remove
|
||||
</span><br/>
|
||||
<span class="covered" title="8 out of 8 forms covered">
|
||||
077 #(when (coll? %) (empty? %))
|
||||
</span><br/>
|
||||
<span class="partial" title="16 out of 19 forms covered">
|
||||
078 (case (first p)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
079 (:λexpr
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
080 :args :bindings :body :cond :cond-clause :defn :dot-terminal
|
||||
</span><br/>
|
||||
<span class="partial" title="80 out of 96 forms covered">
|
||||
081 :fncall :lhs :quoted-expr :rhs ) (map #(simplify-tree % context) p)
|
||||
</span><br/>
|
||||
<span class="partial" title="24 out of 30 forms covered">
|
||||
082 (:arg :expr :coefficient :fn-name :number) (simplify-tree (second p) context)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
083 (:arrow :dot :e :lpar :lsqb :opt-comment :opt-space :q :quote :rpar :rsqb
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
084 :semi-colon :sep :space) nil
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
085 :atom (if
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
086 (= context :mexpr)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
087 [:quoted-expr p]
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
088 p)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
089 :comment (when
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
090 (:strict *options*)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
091 (throw
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
092 (ex-info "Cannot parse comments in strict mode"
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
093 {:cause :strict})))
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
094 (:decimal :integer :mconst :octal :scientific) p
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
095 :dotted-pair (if
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
096 (= context :mexpr)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
097 [:fncall
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
098 [:mvar "cons"]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
099 [:args
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
100 (simplify-tree (nth p 1) context)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
101 (simplify-tree (nth p 2) context)]]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 8 forms covered">
|
||||
102 (map #(simplify-tree % context) p))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
103 :iexp (simplify-tree (second p) context)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
104 :iexpr [:iexpr
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 8 forms covered">
|
||||
105 [:lhs (simplify-tree (second p) context)]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
106 (simplify-tree (nth p 2) context) ;; really should be the operator
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 8 forms covered">
|
||||
107 [:rhs (simplify-tree (nth p 3) context)]]
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
108 :mexpr (if
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
109 (:strict *options*)
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
110 (throw
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
111 (ex-info "Cannot parse meta expressions in strict mode"
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
112 {:cause :strict}))
|
||||
</span><br/>
|
||||
<span class="covered" title="8 out of 8 forms covered">
|
||||
113 [:mexpr (simplify-tree (second p) :mexpr)])
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
114 :list (if
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
115 (= context :mexpr)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
116 [:fncall
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
117 [:mvar "list"]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 11 forms covered">
|
||||
118 [:args (apply vector (map simplify-tree (rest p)))]]
|
||||
</span><br/>
|
||||
<span class="covered" title="8 out of 8 forms covered">
|
||||
119 (map #(simplify-tree % context) p))
|
||||
</span><br/>
|
||||
<span class="covered" title="11 out of 11 forms covered">
|
||||
120 :raw (first (remove empty? (map simplify-tree (rest p))))
|
||||
</span><br/>
|
||||
<span class="covered" title="8 out of 8 forms covered">
|
||||
121 :sexpr [:sexpr (simplify-tree (second p) :sexpr)]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
122 ;;default
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
123 p)))
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
124 :else p)))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
125
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
126 (defn simplify
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
127 "Simplify this parse tree `p`. If `p` is an instaparse failure object, throw
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
128 an `ex-info`, with `p` as the value of its `:failure` key. Calls
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
129 `remove-optional-space` before processing."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
130 [p]
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
131 (simplify-tree (remove-optional-space p)))
|
||||
</span><br/>
|
||||
</body>
|
||||
</html>
|
|
@ -16,88 +16,229 @@
|
|||
</tr></thead>
|
||||
<tr>
|
||||
<td><a href="beowulf/bootstrap.clj.html">beowulf.bootstrap</a></td><td class="with-bar"><div class="covered"
|
||||
style="width:60.47808764940239%;
|
||||
float:left;"> 759 </div><div class="not-covered"
|
||||
style="width:39.52191235059761%;
|
||||
float:left;"> 496 </div></td>
|
||||
<td class="with-number">60.48 %</td>
|
||||
style="width:64.03688524590164%;
|
||||
float:left;"> 625 </div><div class="not-covered"
|
||||
style="width:35.96311475409836%;
|
||||
float:left;"> 351 </div></td>
|
||||
<td class="with-number">64.04 %</td>
|
||||
<td class="with-bar"><div class="covered"
|
||||
style="width:47.92626728110599%;
|
||||
float:left;"> 104 </div><div class="partial"
|
||||
style="width:19.35483870967742%;
|
||||
float:left;"> 42 </div><div class="not-covered"
|
||||
style="width:32.71889400921659%;
|
||||
float:left;"> 71 </div></td>
|
||||
<td class="with-number">67.28 %</td>
|
||||
<td class="with-number">414</td><td class="with-number">46</td><td class="with-number">217</td>
|
||||
style="width:59.48275862068966%;
|
||||
float:left;"> 138 </div><div class="partial"
|
||||
style="width:8.189655172413794%;
|
||||
float:left;"> 19 </div><div class="not-covered"
|
||||
style="width:32.327586206896555%;
|
||||
float:left;"> 75 </div></td>
|
||||
<td class="with-number">67.67 %</td>
|
||||
<td class="with-number">422</td><td class="with-number">33</td><td class="with-number">232</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>
|
||||
style="width:76.0914760914761%;
|
||||
float:left;"> 366 </div><div class="not-covered"
|
||||
style="width:23.908523908523907%;
|
||||
float:left;"> 115 </div></td>
|
||||
<td class="with-number">76.09 %</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>
|
||||
style="width:78.62068965517241%;
|
||||
float:left;"> 114 </div><div class="partial"
|
||||
style="width:6.206896551724138%;
|
||||
float:left;"> 9 </div><div class="not-covered"
|
||||
style="width:15.172413793103448%;
|
||||
float:left;"> 22 </div></td>
|
||||
<td class="with-number">84.83 %</td>
|
||||
<td class="with-number">274</td><td class="with-number">23</td><td class="with-number">145</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>
|
||||
style="width:73.94366197183099%;
|
||||
float:left;"> 210 </div><div class="not-covered"
|
||||
style="width:26.056338028169016%;
|
||||
float:left;"> 74 </div></td>
|
||||
<td class="with-number">73.94 %</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>
|
||||
style="width:78.26086956521739%;
|
||||
float:left;"> 54 </div><div class="partial"
|
||||
style="width:2.898550724637681%;
|
||||
float:left;"> 2 </div><div class="not-covered"
|
||||
style="width:18.840579710144926%;
|
||||
float:left;"> 13 </div></td>
|
||||
<td class="with-number">81.16 %</td>
|
||||
<td class="with-number">132</td><td class="with-number">6</td><td class="with-number">69</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="beowulf/host.clj.html">beowulf.host</a></td><td class="with-bar"><div class="covered"
|
||||
style="width:56.44047135310849%;
|
||||
float:left;"> 1389 </div><div class="not-covered"
|
||||
style="width:43.55952864689151%;
|
||||
float:left;"> 1072 </div></td>
|
||||
<td class="with-number">56.44 %</td>
|
||||
<td class="with-bar"><div class="covered"
|
||||
style="width:75.37878787878788%;
|
||||
float:left;"> 199 </div><div class="partial"
|
||||
style="width:12.121212121212121%;
|
||||
float:left;"> 32 </div><div class="not-covered"
|
||||
style="width:12.5%;
|
||||
float:left;"> 33 </div></td>
|
||||
<td class="with-number">87.50 %</td>
|
||||
<td class="with-number">589</td><td class="with-number">67</td><td class="with-number">264</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="beowulf/interop.clj.html">beowulf.interop</a></td><td class="with-bar"><div class="covered"
|
||||
style="width:57.72357723577236%;
|
||||
float:left;"> 142 </div><div class="not-covered"
|
||||
style="width:42.27642276422764%;
|
||||
float:left;"> 104 </div></td>
|
||||
<td class="with-number">57.72 %</td>
|
||||
<td class="with-bar"><div class="covered"
|
||||
style="width:46.96969696969697%;
|
||||
float:left;"> 31 </div><div class="partial"
|
||||
style="width:9.090909090909092%;
|
||||
float:left;"> 6 </div><div class="not-covered"
|
||||
style="width:43.93939393939394%;
|
||||
float:left;"> 29 </div></td>
|
||||
<td class="with-number">56.06 %</td>
|
||||
<td class="with-number">129</td><td class="with-number">11</td><td class="with-number">66</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="beowulf/io.clj.html">beowulf.io</a></td><td class="with-bar"><div class="covered"
|
||||
style="width:43.962848297213625%;
|
||||
float:left;"> 142 </div><div class="not-covered"
|
||||
style="width:56.037151702786375%;
|
||||
float:left;"> 181 </div></td>
|
||||
<td class="with-number">43.96 %</td>
|
||||
<td class="with-bar"><div class="covered"
|
||||
style="width:45.833333333333336%;
|
||||
float:left;"> 33 </div><div class="partial"
|
||||
style="width:8.333333333333334%;
|
||||
float:left;"> 6 </div><div class="not-covered"
|
||||
style="width:45.833333333333336%;
|
||||
float:left;"> 33 </div></td>
|
||||
<td class="with-number">54.17 %</td>
|
||||
<td class="with-number">171</td><td class="with-number">12</td><td class="with-number">72</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="beowulf/manual.clj.html">beowulf.manual</a></td><td class="with-bar"><div class="covered"
|
||||
style="width:95.93088071348942%;
|
||||
float:left;"> 1721 </div><div class="not-covered"
|
||||
style="width:4.069119286510591%;
|
||||
float:left;"> 73 </div></td>
|
||||
<td class="with-number">95.93 %</td>
|
||||
<td class="with-bar"><div class="covered"
|
||||
style="width:94.60317460317461%;
|
||||
float:left;"> 298 </div><div class="not-covered"
|
||||
style="width:5.396825396825397%;
|
||||
float:left;"> 17 </div></td>
|
||||
<td class="with-number">94.60 %</td>
|
||||
<td class="with-number">769</td><td class="with-number">4</td><td class="with-number">315</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="beowulf/oblist.clj.html">beowulf.oblist</a></td><td class="with-bar"><div class="covered"
|
||||
style="width:100.0%;
|
||||
float:left;"> 1 </div></td>
|
||||
float:left;"> 11 </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>
|
||||
float:left;"> 6 </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>
|
||||
<td class="with-number">45</td><td class="with-number">5</td><td class="with-number">6</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>
|
||||
style="width:54.36893203883495%;
|
||||
float:left;"> 112 </div><div class="not-covered"
|
||||
style="width:45.63106796116505%;
|
||||
float:left;"> 94 </div></td>
|
||||
<td class="with-number">54.37 %</td>
|
||||
<td class="with-bar"><div class="covered"
|
||||
style="width:73.80952380952381%;
|
||||
float:left;"> 93 </div><div class="partial"
|
||||
style="width:61.702127659574465%;
|
||||
float:left;"> 29 </div><div class="partial"
|
||||
style="width:6.382978723404255%;
|
||||
float:left;"> 3 </div><div class="not-covered"
|
||||
style="width:31.914893617021278%;
|
||||
float:left;"> 15 </div></td>
|
||||
<td class="with-number">68.09 %</td>
|
||||
<td class="with-number">120</td><td class="with-number">10</td><td class="with-number">47</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="beowulf/reader/char_reader.clj.html">beowulf.reader.char-reader</a></td><td class="with-bar"><div class="covered"
|
||||
style="width:10.0%;
|
||||
float:left;"> 7 </div><div class="not-covered"
|
||||
style="width:90.0%;
|
||||
float:left;"> 63 </div></td>
|
||||
<td class="with-number">10.00 %</td>
|
||||
<td class="with-bar"><div class="covered"
|
||||
style="width:26.31578947368421%;
|
||||
float:left;"> 5 </div><div class="not-covered"
|
||||
style="width:73.6842105263158%;
|
||||
float:left;"> 14 </div></td>
|
||||
<td class="with-number">26.32 %</td>
|
||||
<td class="with-number">107</td><td class="with-number">6</td><td class="with-number">19</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="beowulf/reader/generate.clj.html">beowulf.reader.generate</a></td><td class="with-bar"><div class="covered"
|
||||
style="width:69.7872340425532%;
|
||||
float:left;"> 492 </div><div class="not-covered"
|
||||
style="width:30.21276595744681%;
|
||||
float:left;"> 213 </div></td>
|
||||
<td class="with-number">69.79 %</td>
|
||||
<td class="with-bar"><div class="covered"
|
||||
style="width:67.46031746031746%;
|
||||
float:left;"> 85 </div><div class="partial"
|
||||
style="width:7.936507936507937%;
|
||||
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>
|
||||
style="width:24.603174603174605%;
|
||||
float:left;"> 31 </div></td>
|
||||
<td class="with-number">75.40 %</td>
|
||||
<td class="with-number">276</td><td class="with-number">21</td><td class="with-number">126</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="beowulf/reader/macros.clj.html">beowulf.reader.macros</a></td><td class="with-bar"><div class="covered"
|
||||
style="width:80.18867924528301%;
|
||||
float:left;"> 85 </div><div class="not-covered"
|
||||
style="width:19.81132075471698%;
|
||||
float:left;"> 21 </div></td>
|
||||
<td class="with-number">80.19 %</td>
|
||||
<td class="with-bar"><div class="covered"
|
||||
style="width:70.0%;
|
||||
float:left;"> 14 </div><div class="not-covered"
|
||||
style="width:30.0%;
|
||||
float:left;"> 6 </div></td>
|
||||
<td class="with-number">70.00 %</td>
|
||||
<td class="with-number">68</td><td class="with-number">4</td><td class="with-number">20</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="beowulf/reader/parser.clj.html">beowulf.reader.parser</a></td><td class="with-bar"><div class="covered"
|
||||
style="width:100.0%;
|
||||
float:left;"> 17 </div></td>
|
||||
<td class="with-number">100.00 %</td>
|
||||
<td class="with-bar"><div class="covered"
|
||||
style="width:100.0%;
|
||||
float:left;"> 4 </div></td>
|
||||
<td class="with-number">100.00 %</td>
|
||||
<td class="with-number">120</td><td class="with-number">14</td><td class="with-number">4</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="beowulf/reader/simplify.clj.html">beowulf.reader.simplify</a></td><td class="with-bar"><div class="covered"
|
||||
style="width:57.30337078651685%;
|
||||
float:left;"> 255 </div><div class="not-covered"
|
||||
style="width:42.69662921348315%;
|
||||
float:left;"> 190 </div></td>
|
||||
<td class="with-number">57.30 %</td>
|
||||
<td class="with-bar"><div class="covered"
|
||||
style="width:49.382716049382715%;
|
||||
float:left;"> 40 </div><div class="partial"
|
||||
style="width:3.7037037037037037%;
|
||||
float:left;"> 3 </div><div class="not-covered"
|
||||
style="width:46.91358024691358%;
|
||||
float:left;"> 38 </div></td>
|
||||
<td class="with-number">53.09 %</td>
|
||||
<td class="with-number">131</td><td class="with-number">6</td><td class="with-number">81</td>
|
||||
</tr>
|
||||
<tr><td>Totals:</td>
|
||||
<td class="with-bar"></td>
|
||||
<td class="with-number">68.97 %</td>
|
||||
<td class="with-number">68.60 %</td>
|
||||
<td class="with-bar"></td>
|
||||
<td class="with-number">72.89 %</td>
|
||||
<td class="with-number">77.76 %</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,17 +1,19 @@
|
|||
<!DOCTYPE html PUBLIC ""
|
||||
"">
|
||||
<html><head><meta charset="UTF-8" /><title>Further Reading</title><link rel="icon" type="image/x-icon" href="../img/beowulf_logo_favicon.png" /><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Beowulf</span> <span class="project-version">0.3.0</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 current"><a href="further_reading.html"><div class="inner"><span>Further Reading</span></div></a></li><li class="depth-1 "><a href="intro.html"><div class="inner"><span>beowulf</span></div></a></li><li class="depth-1 "><a href="mexpr.html"><div class="inner"><span>Interpreting M-Expressions</span></div></a></li><li class="depth-1 "><a href="values.html"><div class="inner"><span>The properties of the system, and their values</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>beowulf</span></div></div></li><li class="depth-2 branch"><a href="beowulf.bootstrap.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>bootstrap</span></div></a></li><li class="depth-2 branch"><a href="beowulf.cons-cell.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>cons-cell</span></div></a></li><li class="depth-2 branch"><a href="beowulf.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-2 branch"><a href="beowulf.gendoc.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>gendoc</span></div></a></li><li class="depth-2 branch"><a href="beowulf.host.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>host</span></div></a></li><li class="depth-2 branch"><a href="beowulf.interop.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>interop</span></div></a></li><li class="depth-2 branch"><a href="beowulf.io.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>io</span></div></a></li><li class="depth-2 branch"><a href="beowulf.manual.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>manual</span></div></a></li><li class="depth-2 branch"><a href="beowulf.oblist.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>oblist</span></div></a></li><li class="depth-2 branch"><a href="beowulf.read.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>read</span></div></a></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>reader</span></div></div></li><li class="depth-3 branch"><a href="beowulf.reader.char-reader.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>char-reader</span></div></a></li><li class="depth-3 branch"><a href="beowulf.reader.generate.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>generate</span></div></a></li><li class="depth-3 branch"><a href="beowulf.reader.macros.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>macros</span></div></a></li><li class="depth-3 branch"><a href="beowulf.reader.parser.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>parser</span></div></a></li><li class="depth-3"><a href="beowulf.reader.simplify.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>simplify</span></div></a></li></ul></div><div class="document" id="content"><div class="doc"><div class="markdown"><h1><a href="#further-reading" name="further-reading"></a>Further Reading</h1>
|
||||
<html><head><meta charset="UTF-8" /><title>Further Reading</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><link rel="icon" type="image/x-icon" href="../img/beowulf_logo_favicon.png" /></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Beowulf</span> <span class="project-version">0.3.1-SNAPSHOT</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 current"><a href="further_reading.html"><div class="inner"><span>Further Reading</span></div></a></li><li class="depth-1 "><a href="intro.html"><div class="inner"><span>beowulf</span></div></a></li><li class="depth-1 "><a href="mexpr.html"><div class="inner"><span>Interpreting M-Expressions</span></div></a></li><li class="depth-1 "><a href="values.html"><div class="inner"><span>The properties of the system, and their values</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>beowulf</span></div></div></li><li class="depth-2 branch"><a href="beowulf.bootstrap.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>bootstrap</span></div></a></li><li class="depth-2 branch"><a href="beowulf.cons-cell.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>cons-cell</span></div></a></li><li class="depth-2 branch"><a href="beowulf.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-2 branch"><a href="beowulf.gendoc.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>gendoc</span></div></a></li><li class="depth-2 branch"><a href="beowulf.host.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>host</span></div></a></li><li class="depth-2 branch"><a href="beowulf.interop.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>interop</span></div></a></li><li class="depth-2 branch"><a href="beowulf.io.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>io</span></div></a></li><li class="depth-2 branch"><a href="beowulf.manual.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>manual</span></div></a></li><li class="depth-2 branch"><a href="beowulf.oblist.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>oblist</span></div></a></li><li class="depth-2 branch"><a href="beowulf.read.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>read</span></div></a></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>reader</span></div></div></li><li class="depth-3 branch"><a href="beowulf.reader.char-reader.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>char-reader</span></div></a></li><li class="depth-3 branch"><a href="beowulf.reader.generate.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>generate</span></div></a></li><li class="depth-3 branch"><a href="beowulf.reader.macros.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>macros</span></div></a></li><li class="depth-3 branch"><a href="beowulf.reader.parser.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>parser</span></div></a></li><li class="depth-3"><a href="beowulf.reader.simplify.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>simplify</span></div></a></li></ul></div><div class="document" id="content"><div class="doc"><div class="markdown"><h1><a href="#further-reading" id="further-reading"></a>Further Reading</h1>
|
||||
<ol>
|
||||
<li><a href="http://bitsavers.org/pdf/mit/computer_center/Coding_for_the_MIT-IBM_704_Computer_Oct57.pdf">CODING for the MIT-IBM 704 COMPUTER, October 1957</a> This paper is not about Lisp. But it is about the particular individual computer on which Lisp was first implemented, and it is written in part by members of the Lisp team. I have found it useful in understanding the software environment in which, and the constraints under which, Lisp was written.</li>
|
||||
<li><a href="https://www.softwarepreservation.org/projects/LISP/MIT/AIM-001.pdf">MIT AI Memo 1, John McCarthy, September 1958</a> This is, as far as I can find, the earliest specification document of the Lisp project.</li>
|
||||
<li><a href="https://bitsavers.org/pdf/mit/rle_lisp/LISP_I_Programmers_Manual_Mar60.pdf">Lisp 1 Programmer’s Manual, Phyllis Fox, March 1960</a></li>
|
||||
<li><a href="https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=81">Lisp 1.5 Programmer’s Manual, Michael I. Levin, August 1962</a> This book is essential reading: it documents in some detail the first fully realised Lisp language system.</li>
|
||||
<li><a href="https://dl.acm.org/doi/pdf/10.1145/800055.802047#page=3">Early LISP History (1956 - 1959), Herbert Stoyan, August 1984</a></li>
|
||||
<li>
|
||||
<p><a href="http://www.paulgraham.com/rootsoflisp.html">The Roots of Lisp, Paul Graham, 2001</a></p></li>
|
||||
<li>
|
||||
<p><a href="http://www.paulgraham.com/icad.html">The Revenge of the Nerds, Paul Graham, 2002</a> This is mainly about why to use Lisp as a language for modern commercial software, but has useful insights into where it comes from.</p>
|
||||
<blockquote>
|
||||
<p>So the short explanation of why this 1950s language is not obsolete is that it was not technology but math, and math doesn’t get stale.</p>
|
||||
</blockquote></li>
|
||||
</ol></div></div></div></body></html>
|
||||
<li><a href="http://bitsavers.org/pdf/mit/computer_center/Coding_for_the_MIT-IBM_704_Computer_Oct57.pdf">CODING for the MIT-IBM 704 COMPUTER, October 1957</a> This paper is not about Lisp. But it is about the particular individual computer on which Lisp was first implemented, and it is written in part by members of the Lisp team. I have found it useful in understanding the software environment in which, and the constraints under which, Lisp was written.</li>
|
||||
<li><a href="https://www.softwarepreservation.org/projects/LISP/MIT/AIM-001.pdf">MIT AI Memo 1, John McCarthy, September 1958</a> This is, as far as I can find, the earliest specification document of the Lisp project.</li>
|
||||
<li><a href="https://bitsavers.org/pdf/mit/rle_lisp/LISP_I_Programmers_Manual_Mar60.pdf">Lisp 1 Programmer’s Manual, Phyllis Fox, March 1960</a></li>
|
||||
<li><a href="https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=81">Lisp 1.5 Programmer’s Manual, Michael I. Levin, August 1962</a> This book is essential reading: it documents in some detail the first fully realised Lisp language system.</li>
|
||||
<li><a href="https://dl.acm.org/doi/pdf/10.1145/800055.802047#page=3">Early LISP History (1956 - 1959), Herbert Stoyan, August 1984</a></li>
|
||||
<li>
|
||||
<p><a href="http://www.paulgraham.com/rootsoflisp.html">The Roots of Lisp, Paul Graham, 2001</a></p>
|
||||
</li>
|
||||
<li><a href="http://www.paulgraham.com/icad.html">The Revenge of the Nerds, Paul Graham, 2002</a> This is mainly about why to use Lisp as a language for modern commercial software, but has useful insights into where it comes from.
|
||||
<blockquote>
|
||||
<p>So the short explanation of why this 1950s language is not obsolete is that it was not technology but math, and math doesn’t get stale.</p>
|
||||
</blockquote>
|
||||
</li>
|
||||
</ol>
|
||||
</div></div></div></body></html>
|
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
23
project.clj
23
project.clj
|
@ -1,17 +1,12 @@
|
|||
(defproject beowulf "0.3.0"
|
||||
(defproject beowulf "0.3.1-SNAPSHOT"
|
||||
:aot :all
|
||||
:cloverage {:output "docs/cloverage"
|
||||
:ns-exclude-regex [#"beowulf\.gendoc" #"beowulf\.scratch"]}
|
||||
:codox {:html {:transforms [[:head] [:append
|
||||
[:link {:rel "icon"
|
||||
:type "image/x-icon"
|
||||
:href "../img/beowulf_logo_favicon.png"}]]]}
|
||||
:metadata {:doc "**TODO**: write docs"
|
||||
: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}"
|
||||
;; :themes [:journeyman]
|
||||
}
|
||||
:themes [:journeyman]}
|
||||
:description "LISP 1.5 is to all Lisp dialects as Beowulf is to English literature."
|
||||
:license {:name "GPL-2.0-or-later"
|
||||
:url "https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html"}
|
||||
|
@ -23,15 +18,17 @@
|
|||
[clojure.java-time "1.2.0"]
|
||||
[environ "1.2.0"]
|
||||
[instaparse "1.4.12"]
|
||||
;; [org.jline/jline "3.23.0"]
|
||||
[rhizome "0.2.9"] ;; not needed in production builds
|
||||
[org.jline/jline "3.23.0"]
|
||||
[com.github.seancorfield/expectations "2.0.165"]
|
||||
;; [rhizome "0.2.9"] ;; not needed in production builds
|
||||
]
|
||||
:main beowulf.core
|
||||
:plugins [[lein-cloverage "1.2.2"]
|
||||
[lein-codox "0.10.7"]
|
||||
[lein-codox "0.10.8"]
|
||||
[lein-environ "1.1.0"]]
|
||||
:profiles {:jar {:aot :all}
|
||||
:uberjar {:aot :all}}
|
||||
:uberjar {:aot :all}
|
||||
:dev {:resource-paths ["resources"]}}
|
||||
:release-tasks [["vcs" "assert-committed"]
|
||||
["change" "version" "leiningen.release/bump-version" "release"]
|
||||
["vcs" "commit"]
|
||||
|
@ -42,4 +39,4 @@
|
|||
["change" "version" "leiningen.release/bump-version"]
|
||||
["vcs" "commit"]]
|
||||
:target-path "target/%s"
|
||||
:url "https://github.com/simon-brooke/the-great-game")
|
||||
:url "https://github.com/simon-brooke/beowulf")
|
||||
|
|
563
resources/codox/theme/journeyman/css/default.css
Normal file
563
resources/codox/theme/journeyman/css/default.css
Normal file
|
@ -0,0 +1,563 @@
|
|||
body {
|
||||
font-family: Helvetica, Arial, sans-serif;
|
||||
font-size: 15px;
|
||||
color: limegreen;
|
||||
background-color: black;
|
||||
}
|
||||
|
||||
a {
|
||||
color: lime;
|
||||
}
|
||||
|
||||
a:active, a:hover {
|
||||
color: yellowgreen;
|
||||
}
|
||||
|
||||
a:visited {
|
||||
color: green;
|
||||
}
|
||||
|
||||
pre, code {
|
||||
font-family: Monaco, DejaVu Sans Mono, Consolas, monospace;
|
||||
font-size: 9pt;
|
||||
margin: 15px 0;
|
||||
color: limegreen;
|
||||
background-color: #111;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-weight: normal;
|
||||
font-size: 29px;
|
||||
margin: 10px 0 2px 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-weight: normal;
|
||||
font-size: 25px;
|
||||
}
|
||||
|
||||
th, td {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
h5.license {
|
||||
margin: 9px 0 22px 0;
|
||||
color: lime;
|
||||
font-weight: normal;
|
||||
font-size: 12px;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.document h1, .namespace-index h1 {
|
||||
font-size: 32px;
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
#header, #content, .sidebar {
|
||||
position: fixed;
|
||||
}
|
||||
|
||||
#header {
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 22px;
|
||||
color: limegreen;
|
||||
padding: 5px 7px;
|
||||
}
|
||||
|
||||
#content {
|
||||
top: 32px;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
overflow: auto;
|
||||
background: black;
|
||||
color: green;
|
||||
padding: 0 18px;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
position: fixed;
|
||||
top: 32px;
|
||||
bottom: 0;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.sidebar.primary {
|
||||
background: #080808;
|
||||
border-right: solid 1px forestgreen;
|
||||
left: 0;
|
||||
width: 250px;
|
||||
}
|
||||
|
||||
.sidebar.secondary {
|
||||
background: #111;
|
||||
border-right: solid 1px darkgreen;
|
||||
left: 251px;
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
#content.namespace-index, #content.document {
|
||||
left: 251px;
|
||||
}
|
||||
|
||||
#content.namespace-docs {
|
||||
left: 452px;
|
||||
}
|
||||
|
||||
#content.document {
|
||||
padding-bottom: 10%;
|
||||
}
|
||||
|
||||
#header {
|
||||
background: #080808;
|
||||
box-shadow: 0 0 8px rgba(192, 255, 192, 0.4);
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
#header h1 {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-size: 18px;
|
||||
font-weight: lighter;
|
||||
text-shadow: -1px -1px 0px #333;
|
||||
}
|
||||
|
||||
#header h1 .project-version {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.project-version {
|
||||
padding-left: 0.15em;
|
||||
}
|
||||
|
||||
#header a, .sidebar a {
|
||||
display: block;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
#header h2 {
|
||||
float: right;
|
||||
font-size: 9pt;
|
||||
font-weight: normal;
|
||||
margin: 4px 3px;
|
||||
padding: 0;
|
||||
color: #5f5;
|
||||
}
|
||||
|
||||
#header h2 a {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.sidebar h3 {
|
||||
margin: 0;
|
||||
padding: 10px 13px 0 13px;
|
||||
font-size: 19px;
|
||||
font-weight: lighter;
|
||||
}
|
||||
|
||||
.sidebar h3 a {
|
||||
color: #4f4;
|
||||
}
|
||||
|
||||
.sidebar h3.no-link {
|
||||
color: green;
|
||||
}
|
||||
|
||||
.sidebar ul {
|
||||
padding: 7px 0 6px 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.sidebar ul.index-link {
|
||||
padding-bottom: 4px;
|
||||
}
|
||||
|
||||
.sidebar li {
|
||||
display: block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.sidebar li a, .sidebar li .no-link {
|
||||
border-left: 3px solid transparent;
|
||||
padding: 0 10px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.sidebar li .no-link {
|
||||
display: block;
|
||||
color: #7F7;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.sidebar li .inner {
|
||||
display: inline-block;
|
||||
padding-top: 7px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
.sidebar li a, .sidebar li .tree {
|
||||
height: 31px;
|
||||
}
|
||||
|
||||
.depth-1 .inner { padding-left: 2px; }
|
||||
.depth-2 .inner { padding-left: 6px; }
|
||||
.depth-3 .inner { padding-left: 20px; }
|
||||
.depth-4 .inner { padding-left: 34px; }
|
||||
.depth-5 .inner { padding-left: 48px; }
|
||||
.depth-6 .inner { padding-left: 62px; }
|
||||
|
||||
.sidebar li .tree {
|
||||
display: block;
|
||||
float: left;
|
||||
position: relative;
|
||||
top: -10px;
|
||||
margin: 0 4px 0 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.sidebar li.depth-1 .tree {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.sidebar li .tree .top, .sidebar li .tree .bottom {
|
||||
display: block;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 7px;
|
||||
}
|
||||
|
||||
.sidebar li .tree .top {
|
||||
border-left: 1px solid yellowgreen;
|
||||
border-bottom: 1px solid yellowgreen;
|
||||
height: 19px;
|
||||
}
|
||||
|
||||
.sidebar li .tree .bottom {
|
||||
height: 22px;
|
||||
}
|
||||
|
||||
.sidebar li.branch .tree .bottom {
|
||||
border-left: 1px solid yellowgreen;
|
||||
}
|
||||
|
||||
.sidebar.primary li.current a {
|
||||
border-left: 3px solid goldenrod;
|
||||
color: goldenrod;
|
||||
}
|
||||
|
||||
.sidebar.secondary li.current a {
|
||||
border-left: 3px solid yellow;
|
||||
color: yellow;
|
||||
}
|
||||
|
||||
.namespace-index h2 {
|
||||
margin: 30px 0 0 0;
|
||||
}
|
||||
|
||||
.namespace-index h3 {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.namespace-index .topics {
|
||||
padding-left: 30px;
|
||||
margin: 11px 0 0 0;
|
||||
}
|
||||
|
||||
.namespace-index .topics li {
|
||||
padding: 5px 0;
|
||||
}
|
||||
|
||||
.namespace-docs h3 {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.public h3 {
|
||||
margin: 0;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.usage {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.public {
|
||||
margin: 0;
|
||||
border-top: 1px solid lime;
|
||||
padding-top: 14px;
|
||||
padding-bottom: 6px;
|
||||
}
|
||||
|
||||
.public:last-child {
|
||||
margin-bottom: 20%;
|
||||
}
|
||||
|
||||
.members .public:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.members {
|
||||
margin: 15px 0;
|
||||
}
|
||||
|
||||
.members h4 {
|
||||
color: lime;
|
||||
font-weight: normal;
|
||||
font-variant: small-caps;
|
||||
margin: 0 0 5px 0;
|
||||
}
|
||||
|
||||
.members .inner {
|
||||
padding-top: 5px;
|
||||
padding-left: 12px;
|
||||
margin-top: 2px;
|
||||
margin-left: 7px;
|
||||
border-left: 1px solid #5f5;
|
||||
}
|
||||
|
||||
#content .members .inner h3 {
|
||||
font-size: 12pt;
|
||||
}
|
||||
|
||||
.members .public {
|
||||
border-top: none;
|
||||
margin-top: 0;
|
||||
padding-top: 6px;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.members .public:first-child {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
h4.type,
|
||||
h4.dynamic,
|
||||
h4.added,
|
||||
h4.deprecated {
|
||||
float: left;
|
||||
margin: 3px 10px 15px 0;
|
||||
font-size: 15px;
|
||||
font-weight: bold;
|
||||
font-variant: small-caps;
|
||||
}
|
||||
|
||||
.public h4.type,
|
||||
.public h4.dynamic,
|
||||
.public h4.added,
|
||||
.public h4.deprecated {
|
||||
font-size: 13px;
|
||||
font-weight: bold;
|
||||
margin: 3px 0 0 10px;
|
||||
}
|
||||
|
||||
.members h4.type,
|
||||
.members h4.added,
|
||||
.members h4.deprecated {
|
||||
margin-top: 1px;
|
||||
}
|
||||
|
||||
h4.type {
|
||||
color: #717171;
|
||||
}
|
||||
|
||||
h4.dynamic {
|
||||
color: #9933aa;
|
||||
}
|
||||
|
||||
h4.added {
|
||||
color: #7acc32;
|
||||
}
|
||||
|
||||
h4.deprecated {
|
||||
color: #880000;
|
||||
}
|
||||
|
||||
.namespace {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.namespace:last-child {
|
||||
margin-bottom: 10%;
|
||||
}
|
||||
|
||||
.index {
|
||||
padding: 0;
|
||||
font-size: 80%;
|
||||
margin: 15px 0;
|
||||
line-height: 16px;
|
||||
}
|
||||
|
||||
.index * {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.index p {
|
||||
padding-right: 3px;
|
||||
}
|
||||
|
||||
.index li {
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
.index ul {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.type-sig {
|
||||
clear: both;
|
||||
color: goldenrod;
|
||||
}
|
||||
|
||||
.type-sig pre {
|
||||
padding-top: 10px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.usage code {
|
||||
display: block;
|
||||
margin: 2px 0;
|
||||
color: limegreen;
|
||||
}
|
||||
|
||||
.usage code:first-child {
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 15px 0;
|
||||
}
|
||||
|
||||
.public p:first-child, .public pre.plaintext {
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.doc {
|
||||
margin: 0 0 26px 0;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.public .doc {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.namespace-index .doc {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.namespace-index .namespace .doc {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.markdown p, .markdown li, .markdown dt, .markdown dd, .markdown td {
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
.markdown li {
|
||||
padding: 2px 0;
|
||||
}
|
||||
|
||||
.markdown h2 {
|
||||
font-weight: normal;
|
||||
font-size: 25px;
|
||||
margin: 30px 0 10px 0;
|
||||
}
|
||||
|
||||
.markdown h3 {
|
||||
font-weight: normal;
|
||||
font-size: 20px;
|
||||
margin: 30px 0 0 0;
|
||||
}
|
||||
|
||||
.markdown h4 {
|
||||
font-size: 15px;
|
||||
margin: 22px 0 -4px 0;
|
||||
}
|
||||
|
||||
.doc, .public, .namespace .index {
|
||||
max-width: 680px;
|
||||
overflow-x: visible;
|
||||
}
|
||||
|
||||
.markdown pre > code {
|
||||
display: block;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.markdown pre > code, .src-link a {
|
||||
border: 1px solid lime;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.markdown code:not(.hljs), .src-link a {
|
||||
background: #111;
|
||||
}
|
||||
|
||||
pre.deps {
|
||||
display: inline-block;
|
||||
margin: 0 10px;
|
||||
border: 1px solid lime;
|
||||
border-radius: 2px;
|
||||
padding: 10px;
|
||||
background-color: #111;
|
||||
}
|
||||
|
||||
.markdown hr {
|
||||
border-style: solid;
|
||||
border-top: none;
|
||||
color: goldenrod;
|
||||
}
|
||||
|
||||
.doc ul, .doc ol {
|
||||
padding-left: 30px;
|
||||
}
|
||||
|
||||
.doc table {
|
||||
border-collapse: collapse;
|
||||
margin: 0 10px;
|
||||
}
|
||||
|
||||
.doc table td, .doc table th {
|
||||
border: 1px solid goldenrod;
|
||||
padding: 4px 6px;
|
||||
}
|
||||
|
||||
.doc table th {
|
||||
background: #111;
|
||||
}
|
||||
|
||||
.doc dl {
|
||||
margin: 0 10px 20px 10px;
|
||||
}
|
||||
|
||||
.doc dl dt {
|
||||
font-weight: bold;
|
||||
margin: 0;
|
||||
padding: 3px 0;
|
||||
border-bottom: 1px solid goldenrod;
|
||||
}
|
||||
|
||||
.doc dl dd {
|
||||
padding: 5px 0;
|
||||
margin: 0 0 5px 10px;
|
||||
}
|
||||
|
||||
.doc abbr {
|
||||
border-bottom: 1px dotted goldenrod;
|
||||
font-variant: none;
|
||||
cursor: help;
|
||||
}
|
||||
|
||||
.src-link {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.src-link a {
|
||||
font-size: 70%;
|
||||
padding: 1px 4px;
|
||||
text-decoration: none;
|
||||
color: lime5bb;
|
||||
}
|
97
resources/codox/theme/journeyman/css/highlight.css
Normal file
97
resources/codox/theme/journeyman/css/highlight.css
Normal 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;
|
||||
}
|
11
resources/codox/theme/journeyman/theme.edn
Normal file
11
resources/codox/theme/journeyman/theme.edn
Normal file
|
@ -0,0 +1,11 @@
|
|||
{:resources ["css/default.css" "css/highlight.css"]
|
||||
:transforms [[:head] [:append
|
||||
[:link {:rel "stylesheet"
|
||||
:type "text/css"
|
||||
:href "css/default.css"}]
|
||||
[:link {:rel "stylesheet"
|
||||
:type "text/css"
|
||||
:href "css/highlight.css"}]
|
||||
[:link {:rel "icon"
|
||||
:type "image/x-icon"
|
||||
:href "../img/beowulf_logo_favicon.png"}]]]}
|
|
@ -1 +0,0 @@
|
|||
{:resources ["css/default.css" "css/highlight.css"]}
|
|
@ -25,6 +25,7 @@
|
|||
(T (ASSOC X (CDR L)))))
|
||||
SUBR (BEOWULF HOST ASSOC))
|
||||
(ATOM 32767 SUBR (BEOWULF HOST ATOM))
|
||||
(ATTRIB 32767 SUBR (BEOWULF HOST ATTRIB))
|
||||
(CAR 32767 SUBR (BEOWULF HOST CAR))
|
||||
(CAAAAR 32767 EXPR (LAMBDA (X) (CAR (CAR (CAR (CAR X))))))
|
||||
(CAAADR 32767 EXPR (LAMBDA (X) (CAR (CAR (CAR (CDR X))))))
|
||||
|
@ -55,6 +56,16 @@
|
|||
(CDDDR 32767 EXPR (LAMBDA (X) (CDR (CDR (CDR X)))))
|
||||
(CDDR 32767 EXPR (LAMBDA (X) (CDR (CDR X))))
|
||||
(CDR 32767 SUBR (BEOWULF HOST CDR))
|
||||
(CONC
|
||||
32767
|
||||
FEXPR
|
||||
(LABEL
|
||||
ARGS
|
||||
(COND
|
||||
((COND
|
||||
((ONEP (LENGTH ARGS)) ARGS)
|
||||
(T (ATTRIB (CAR ARGS) (APPLY CONC (CDR ARGS) NIL))))
|
||||
ARGS))))
|
||||
(CONS 32767 SUBR (BEOWULF HOST CONS))
|
||||
(CONSP 32767 SUBR (BEOWULF HOST CONSP))
|
||||
(COPY
|
||||
|
@ -170,6 +181,7 @@
|
|||
(COND
|
||||
((NULL X) (U))
|
||||
((EQ (CAR X) Y) (CDR X)) (T (PROP (CDR X) Y U)))))
|
||||
(PUT 32767 SUBR (BEOWULF HOST PUT))
|
||||
(QUOTE 32767 EXPR (LAMBDA (X) X))
|
||||
(QUOTIENT 32767 SUBR (BEOWULF HOST QUOTIENT))
|
||||
(RANGE
|
||||
|
@ -187,6 +199,7 @@
|
|||
(LAMBDA (N X) (COND ((EQ N 0) NIL) (T (CONS X (REPEAT (SUB1 N) X))))))
|
||||
(RPLACA 32767 SUBR (BEOWULF HOST RPLACA))
|
||||
(RPLACD 32767 SUBR (BEOWULF HOST RPLACD))
|
||||
(SASSOC 32767 SUBR (BEOWULF BOOTSTRAP SASSOC))
|
||||
(SEARCH 32767 EXPR
|
||||
(LAMBDA (X P F U)
|
||||
(COND ((NULL X) (U X))
|
||||
|
|
|
@ -1 +1,7 @@
|
|||
;; TODO
|
||||
;; This isn't working but it's really not far off.
|
||||
|
||||
(PUT 'CONC 'FEXPR
|
||||
;; possibly ARGS should be (ARGS)...
|
||||
'(LABEL ARGS
|
||||
(COND ((COND ((ONEP (LENGTH ARGS)) ARGS)
|
||||
(T (ATTRIB (CAR ARGS) (APPLY CONC (CDR ARGS) NIL)))) ARGS))))
|
22
resources/sexpr/fact.lsp
Normal file
22
resources/sexpr/fact.lsp
Normal file
|
@ -0,0 +1,22 @@
|
|||
;; Common Lisp
|
||||
|
||||
(defun range (max &key (min 0) (step 1))
|
||||
(loop for n from min below max by step
|
||||
collect n))
|
||||
|
||||
(mapcar #'(lambda (x) (+ x 1)) (range 10))
|
||||
|
||||
(defun factoriali (n)
|
||||
(reduce #'* (range (+ n 1) :min 1 :step 1)))
|
||||
|
||||
(defun factorialr (n)
|
||||
(cond ((= n 1) 1)
|
||||
(t (* n (factorialr (- n 1))))))
|
||||
|
||||
|
||||
;; Clojure
|
||||
(defn factorial [n]
|
||||
(reduce *' (range 1 (+ n 1))))
|
||||
|
||||
(defn expt [n x]
|
||||
(reduce *' (repeat x n)))
|
13
resources/sexpr/select.lsp
Normal file
13
resources/sexpr/select.lsp
Normal file
|
@ -0,0 +1,13 @@
|
|||
;; Bottom of page 66
|
||||
|
||||
(PUT 'SELECT 'FEXPR
|
||||
'(LABEL FORM
|
||||
(PROG (Q BODY)
|
||||
(SETQ Q (EVAL (CAR FORM))) ;; not sure that Q should be evaled.
|
||||
(SETQ BODY (CDR FORM))
|
||||
LOOP
|
||||
(COND
|
||||
((EQ NIL (CDR BODY)) (RETURN (CAR BODY)))
|
||||
((EQ Q (EVAL (CAAR BODY))) (RETURN (CDAR BODY))))
|
||||
(SETQ BODY (CDR BODY))
|
||||
(GO LOOP))))
|
|
@ -11,9 +11,11 @@
|
|||
objects."
|
||||
(:require [beowulf.cons-cell :refer [F make-beowulf-list make-cons-cell
|
||||
pretty-print T]]
|
||||
[beowulf.host :refer [ASSOC ATOM CAAR CADAR CADDR CADR CAR CDR GET
|
||||
LIST NUMBERP PAIRLIS traced?]]
|
||||
[beowulf.oblist :refer [*options* NIL oblist]])
|
||||
[beowulf.host :refer [ASSOC ATOM CAAR CAADR CADAR CADDR CADR CAR CDR
|
||||
CONS ERROR GET LIST NUMBERP PAIRLIS traced?]]
|
||||
[beowulf.oblist :refer [*options* NIL]]
|
||||
[clojure.string :as s]
|
||||
[clojure.tools.trace :refer [deftrace]])
|
||||
(:import [beowulf.cons_cell ConsCell]
|
||||
[clojure.lang Symbol]))
|
||||
|
||||
|
@ -37,10 +39,20 @@
|
|||
;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(declare APPLY EVAL prog-eval)
|
||||
(declare APPLY EVAL EVCON prog-eval)
|
||||
|
||||
;;;; The PROGram feature ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(def ^:dynamic
|
||||
*depth*
|
||||
"Stack depth. Unfortunately we need to be able to pass round depth for
|
||||
functions which call EVAL/APPLY but do not know about depth."
|
||||
0)
|
||||
|
||||
(defn- trace-indent
|
||||
([] (trace-indent *depth*))
|
||||
([d] (s/join (repeat d " "))))
|
||||
|
||||
(def find-target
|
||||
(memoize
|
||||
(fn [target body]
|
||||
|
@ -82,30 +94,45 @@
|
|||
(cond
|
||||
(number? expr) expr
|
||||
(symbol? expr) (@vars expr)
|
||||
(instance? ConsCell expr) (case (.getCar expr)
|
||||
COND (prog-cond (.getCdr expr)
|
||||
(instance? ConsCell expr) (case (CAR expr)
|
||||
COND (prog-cond (CDR expr)
|
||||
vars env depth)
|
||||
GO (make-cons-cell
|
||||
'*PROGGO* (.getCar (.getCdr expr)))
|
||||
RETURN (make-cons-cell
|
||||
'*PROGRETURN*
|
||||
(prog-eval (.getCar (.getCdr expr))
|
||||
vars env depth))
|
||||
SET (let [v (CADDR expr)]
|
||||
GO (let [target (CADR expr)]
|
||||
(when (traced? 'PROG)
|
||||
(println " PROG:GO: Goto " target))
|
||||
(make-cons-cell
|
||||
'*PROGGO* target))
|
||||
RETURN (let [val (prog-eval
|
||||
(CADR expr)
|
||||
vars env depth)]
|
||||
(when (traced? 'PROG)
|
||||
(println " PROG:RETURN: Returning "
|
||||
val))
|
||||
(make-cons-cell
|
||||
'*PROGRETURN*
|
||||
val))
|
||||
SET (let [var (prog-eval (CADR expr)
|
||||
vars env depth)
|
||||
val (prog-eval (CADDR expr)
|
||||
vars env depth)]
|
||||
(when (traced? 'PROG)
|
||||
(println " PROG:SET: Setting "
|
||||
var " to " val))
|
||||
(swap! vars
|
||||
assoc
|
||||
(prog-eval (CADR expr)
|
||||
vars env depth)
|
||||
(prog-eval (CADDR expr)
|
||||
vars env depth))
|
||||
v)
|
||||
SETQ (let [v (CADDR expr)]
|
||||
var
|
||||
val)
|
||||
val)
|
||||
SETQ (let [var (CADDR expr)
|
||||
val (prog-eval var
|
||||
vars env depth)]
|
||||
(when (traced? 'PROG)
|
||||
(println " PROG:SETQ: Setting " var " to " val))
|
||||
(swap! vars
|
||||
assoc
|
||||
(CADR expr)
|
||||
(prog-eval v
|
||||
vars env depth))
|
||||
v)
|
||||
val)
|
||||
val)
|
||||
;; else
|
||||
(beowulf.bootstrap/EVAL expr
|
||||
(merge-vars vars env)
|
||||
|
@ -173,7 +200,7 @@
|
|||
(println "Program:")
|
||||
(pretty-print program))) ;; for debugging
|
||||
(loop [cursor body]
|
||||
(let [step (.getCar cursor)]
|
||||
(let [step (if (= NIL cursor) NIL (.getCar cursor))]
|
||||
(when trace (do (println "Executing step: " step)
|
||||
(println " with vars: " @vars)))
|
||||
(cond (= cursor NIL) NIL
|
||||
|
@ -206,7 +233,7 @@
|
|||
with these `args` at this depth."
|
||||
[function-symbol args depth]
|
||||
(when (traced? function-symbol)
|
||||
(let [indent (apply str (repeat depth "-"))]
|
||||
(let [indent (trace-indent depth)]
|
||||
(println (str indent "> " function-symbol " " args)))))
|
||||
|
||||
(defn- trace-response
|
||||
|
@ -214,11 +241,13 @@
|
|||
`function-symbol` at this depth."
|
||||
[function-symbol response depth]
|
||||
(when (traced? function-symbol)
|
||||
(let [indent (apply str (repeat depth "-"))]
|
||||
(let [indent (apply str (trace-indent depth))]
|
||||
(println (str "<" indent " " function-symbol " " response))))
|
||||
response)
|
||||
|
||||
(defn- value
|
||||
;;;; Support functions for interpreter ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defn value
|
||||
"Seek a value for this symbol `s` by checking each of these indicators in
|
||||
turn."
|
||||
([s]
|
||||
|
@ -228,6 +257,21 @@
|
|||
(first (remove #(= % NIL) (map #(GET s %)
|
||||
indicators))))))
|
||||
|
||||
(defn SASSOC
|
||||
"Like `ASSOC`, but with an action to take if no value is found.
|
||||
|
||||
From the manual, page 60:
|
||||
|
||||
'The function `sassoc` searches `y`, which is a list of dotted pairs, for
|
||||
a pair whose first element that is `x`. If such a pair is found, the value
|
||||
of `sassoc` is this pair. Otherwise the function `u` of no arguments is
|
||||
taken as the value of `sassoc`.'"
|
||||
[x y u]
|
||||
(let [v (ASSOC x y)]
|
||||
(if-not (= v NIL) v
|
||||
(APPLY u NIL NIL))))
|
||||
|
||||
|
||||
;;;; APPLY ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defn try-resolve-subroutine
|
||||
|
@ -248,7 +292,7 @@
|
|||
return the result."
|
||||
[^Symbol function-symbol args ^ConsCell environment depth]
|
||||
(trace-call function-symbol args depth)
|
||||
(let [lisp-fn (value function-symbol '(EXPR FEXPR))
|
||||
(let [lisp-fn (value function-symbol '(EXPR FEXPR)) ;; <-- should these be handled differently? I think so!
|
||||
args' (cond (= NIL args) args
|
||||
(empty? args) NIL
|
||||
(instance? ConsCell args) args
|
||||
|
@ -275,6 +319,43 @@
|
|||
(trace-response function-symbol result depth)
|
||||
result))
|
||||
|
||||
;; (LABEL ARGS
|
||||
;; (COND ((COND ((ONEP (LENGTH ARGS)) ARGS)
|
||||
;; (T (ATTRIB (CAR ARGS) (APPLY CONC (CDR ARGS) NIL))))
|
||||
;; ARGS)))
|
||||
;; ((1 2 3 4) (5 6 7 8) (9 10 11 12))
|
||||
;; NIL
|
||||
;; (def function (make-beowulf-list '(LABEL ARGS (COND
|
||||
;; ((COND ((ONEP (LENGTH ARGS)) ARGS)
|
||||
;; (T (ATTRIB (CAR ARGS)
|
||||
;; (APPLY CONC (CDR ARGS) NIL))))
|
||||
;; ARGS)))))
|
||||
;; (def args (make-beowulf-list '((1 2 3 4) (5 6 7 8) (9 10 11 12))))
|
||||
|
||||
;; function
|
||||
;; (CADR function)
|
||||
;; (CADDR function)
|
||||
|
||||
(defn apply-label
|
||||
"Apply in the special case that the first element in the function is `LABEL`."
|
||||
[function args environment depth]
|
||||
(EVAL
|
||||
(CADDR function)
|
||||
(CONS
|
||||
(CONS (CADR function) args)
|
||||
environment)
|
||||
depth))
|
||||
|
||||
;; (apply-label function args NIL 1)
|
||||
;; (APPLY function args NIL 1)
|
||||
|
||||
(defn- apply-lambda
|
||||
"Apply in the special case that the first element in the function is `LAMBDA`."
|
||||
[function args environment depth]
|
||||
(EVAL
|
||||
(CADDR function)
|
||||
(PAIRLIS (CADR function) args environment) depth))
|
||||
|
||||
(defn APPLY
|
||||
"Apply this `function` to these `arguments` in this `environment` and return
|
||||
the result.
|
||||
|
@ -282,38 +363,34 @@
|
|||
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."
|
||||
[function args environment depth]
|
||||
(trace-call 'APPLY (list function args environment) depth)
|
||||
(let [result (cond
|
||||
(= NIL function) (if (:strict *options*)
|
||||
NIL
|
||||
(throw (ex-info "NIL sí ne þegnung"
|
||||
{:phase :apply
|
||||
:function "NIL"
|
||||
:args args
|
||||
:type :beowulf})))
|
||||
(= (ATOM function) T) (apply-symbolic function args environment (inc depth))
|
||||
:else (case (first function)
|
||||
LABEL (APPLY
|
||||
(CADDR function)
|
||||
args
|
||||
(make-cons-cell
|
||||
(make-cons-cell
|
||||
(CADR function)
|
||||
(CADDR function))
|
||||
environment)
|
||||
depth)
|
||||
FUNARG (APPLY (CADR function) args (CADDR function) depth)
|
||||
LAMBDA (EVAL
|
||||
(CADDR function)
|
||||
(PAIRLIS (CADR function) args environment) depth)
|
||||
(throw (ex-info "Ungecnáwen wyrþan sí þegnung-weard"
|
||||
{:phase :apply
|
||||
:function function
|
||||
:args args
|
||||
:type :beowulf}))))]
|
||||
(trace-response 'APPLY result depth)
|
||||
result))
|
||||
([function args environment]
|
||||
(APPLY function args environment *depth*))
|
||||
([function args environment depth]
|
||||
(binding [*depth* (inc depth)]
|
||||
(trace-call 'APPLY (list function args environment) depth)
|
||||
(let [result (cond
|
||||
(= NIL function) (if (:strict *options*)
|
||||
NIL
|
||||
(throw (ex-info "NIL sí ne þegnung"
|
||||
{:phase :apply
|
||||
:function "NIL"
|
||||
:args args
|
||||
:type :beowulf})))
|
||||
(= (ATOM function) T) (apply-symbolic function args environment (inc depth))
|
||||
:else (case (first function)
|
||||
LABEL (apply-label function args environment depth)
|
||||
FUNARG (APPLY (CADR function) args (CADDR function) depth)
|
||||
LAMBDA (apply-lambda function args environment depth)
|
||||
;; else
|
||||
;; OK, this is *not* what is says in the manual...
|
||||
;; COND (EVCON ???)
|
||||
(throw (ex-info "Ungecnáwen wyrþan sí þegnung-weard"
|
||||
{:phase :apply
|
||||
:function function
|
||||
:args args
|
||||
:type :beowulf}))))]
|
||||
(trace-response 'APPLY result depth)
|
||||
result))))
|
||||
|
||||
;;;; EVAL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
|
@ -361,12 +438,12 @@
|
|||
(println (str indent ": EVAL: sceald bindele: " (or v "nil"))))
|
||||
(if (instance? ConsCell v)
|
||||
(.getCdr v)
|
||||
(let [v' (value expr (list 'APVAL))]
|
||||
(let [v' (value expr)]
|
||||
(when (traced? 'EVAL)
|
||||
(println (str indent ": EVAL: deóp bindele: (" expr " . " (or v' "nil") ")")))
|
||||
(if v'
|
||||
v'
|
||||
(throw (ex-info "Ne tácen-bindele āfand"
|
||||
(throw (ex-info (format "Ne tácen-bindele āfand: `%s`" expr)
|
||||
{:phase :eval
|
||||
:function 'EVAL
|
||||
:args (list expr env depth)
|
||||
|
@ -412,11 +489,10 @@
|
|||
(EVLIS (CDR expr) env depth)
|
||||
env
|
||||
depth))
|
||||
:else (APPLY
|
||||
(CAR expr)
|
||||
(EVLIS (CDR expr) env depth)
|
||||
env
|
||||
depth))]
|
||||
:else (EVAL (CONS (CDR (SASSOC (CAR expr) env (fn [] (ERROR 'A9))))
|
||||
(CDR expr))
|
||||
env
|
||||
(inc depth)))]
|
||||
(trace-response 'EVAL result depth)
|
||||
result)))
|
||||
|
||||
|
|
|
@ -53,7 +53,8 @@
|
|||
(.canRead (io/file %)))
|
||||
"Could not find sysout file"]]
|
||||
["-s" "--strict" "Strictly interpret the Lisp 1.5 language, without extensions."]
|
||||
["-t" "--time" "Time evaluations."]])
|
||||
["-t" "--time" "Time evaluations."]
|
||||
["-x" "--testing" "Disable the jline reader - useful when piping input."]])
|
||||
|
||||
(defn- re
|
||||
"Like REPL, but it isn't a loop and doesn't print."
|
||||
|
@ -63,11 +64,10 @@
|
|||
(defn repl
|
||||
"Read/eval/print loop."
|
||||
[prompt]
|
||||
(loop []
|
||||
(print prompt)
|
||||
(loop []
|
||||
(flush)
|
||||
(try
|
||||
(if-let [input (trim (read-from-console))]
|
||||
(if-let [input (trim (read-from-console prompt))]
|
||||
(if (= input stop-word)
|
||||
(throw (ex-info "\nFærwell!" {:cause :quit}))
|
||||
(println
|
||||
|
@ -116,7 +116,7 @@
|
|||
(catch Throwable any
|
||||
(println any))))
|
||||
(try
|
||||
(repl (str (:prompt (:options args)) " "))
|
||||
(repl (:prompt (:options args)))
|
||||
(catch
|
||||
Exception
|
||||
e
|
||||
|
|
|
@ -91,22 +91,21 @@
|
|||
(cond
|
||||
(= l NIL) NIL
|
||||
(empty? path) l
|
||||
:else
|
||||
(try
|
||||
(case (last path)
|
||||
\a (uaf (.first l) (butlast path))
|
||||
\d (uaf (.getCdr l) (butlast path))
|
||||
(throw (ex-info (str "uaf: unexpected letter in path (only `a` and `d` permitted): " (last path))
|
||||
{:cause :uaf
|
||||
:detail :unexpected-letter
|
||||
:expr (last path)})))
|
||||
(catch ClassCastException e
|
||||
(throw (ex-info
|
||||
(str "uaf: Not a LISP list? " (type l))
|
||||
{:cause :uaf
|
||||
:detail :not-a-lisp-list
|
||||
:expr l}
|
||||
e))))))
|
||||
(not (instance? ConsCell l)) (throw (ex-info (str "Ne liste: "
|
||||
l "; " (type l))
|
||||
{:phase :eval
|
||||
:function "universal access function"
|
||||
:args [l path]
|
||||
:type :beowulf}))
|
||||
:else (case (last path)
|
||||
\a (uaf (.first l) (butlast path))
|
||||
\d (uaf (.getCdr l) (butlast path))
|
||||
(throw (ex-info (str "uaf: unexpected letter in path (only `a` and `d` permitted): "
|
||||
(last path))
|
||||
{:phase :eval
|
||||
:function "universal access function"
|
||||
:args [l path]
|
||||
:type :beowulf})))))
|
||||
|
||||
(defmacro CAAR [x] `(uaf ~x '(\a \a)))
|
||||
(defmacro CADR [x] `(uaf ~x '(\a \d)))
|
||||
|
@ -217,7 +216,7 @@
|
|||
:phase :host
|
||||
:detail :rplacd
|
||||
:args (list cell value)
|
||||
:type :beowulf}))));; PLUS
|
||||
:type :beowulf}))))
|
||||
|
||||
(defn LIST
|
||||
[& args]
|
||||
|
@ -433,6 +432,41 @@
|
|||
"The unexplained magic number which marks the start of a property list."
|
||||
(Integer/parseInt "77777" 8))
|
||||
|
||||
(defn hit-or-miss-assoc
|
||||
"Find the position of the binding of this `target` in a Lisp 1.5
|
||||
property list `plist`.
|
||||
|
||||
Lisp 1.5 property lists are not assoc lists, but lists of the form
|
||||
`(name value name value name value...)`. It's therefore necessary to
|
||||
recurse down the list two entries at a time to avoid confusing names
|
||||
with values."
|
||||
[target plist]
|
||||
(if (and (instance? ConsCell plist) (even? (count plist)))
|
||||
(cond (= plist NIL) NIL
|
||||
(= (first plist) target) plist
|
||||
:else (hit-or-miss-assoc target (CDDR plist)))
|
||||
NIL))
|
||||
|
||||
(defn ATTRIB
|
||||
"Destructive append. From page 59 of the manual:
|
||||
|
||||
The function `attrib` concatenates its two arguments by changing the last
|
||||
element of its first argument to point to the second argument. Thus it
|
||||
is commonly used to tack something onto the end of a property list.
|
||||
The value of `attrib` is the second argument.
|
||||
|
||||
For example
|
||||
```
|
||||
attrib[FF; (EXPR (LAMBDA (X) (COND ((ATOM X) X) (T (FF (CAR x))))))]
|
||||
```
|
||||
would put EXPR followed by the LAMBDA expression for FF onto the end of
|
||||
the property list for FF."
|
||||
[x e]
|
||||
(loop [l x]
|
||||
(cond
|
||||
(instance? ConsCell (CDR l)) (recur (CDR l))
|
||||
:else (when (RPLACD l e) e))))
|
||||
|
||||
(defn PUT
|
||||
"Put this `value` as the value of the property indicated by this `indicator`
|
||||
of this `symbol`. Return `value` on success.
|
||||
|
@ -440,22 +474,27 @@
|
|||
NOTE THAT there is no `PUT` defined in the manual, but it would have been
|
||||
easy to have defined it so I don't think this fully counts as an extension."
|
||||
[symbol indicator value]
|
||||
(if-let [binding (ASSOC symbol @oblist)]
|
||||
(if-let [prop (ASSOC indicator (CDDR binding))]
|
||||
(RPLACD prop value)
|
||||
(RPLACD binding
|
||||
(make-cons-cell
|
||||
magic-marker
|
||||
(make-cons-cell
|
||||
indicator
|
||||
(make-cons-cell value (CDDR binding))))))
|
||||
(swap!
|
||||
oblist
|
||||
(fn [ob s p v]
|
||||
(make-cons-cell
|
||||
(make-beowulf-list (list s magic-marker p v))
|
||||
ob))
|
||||
symbol indicator value)))
|
||||
(let [binding (ASSOC symbol @oblist)]
|
||||
(if (instance? ConsCell binding)
|
||||
(let [prop (hit-or-miss-assoc indicator (CDDR binding))]
|
||||
(if (instance? ConsCell prop)
|
||||
(RPLACA (CDR prop) value)
|
||||
;; The implication is ATTRIB was used here, but I have not made that
|
||||
;; work and this does work, so if it ain't broke don't fix it.
|
||||
(RPLACD binding
|
||||
(make-cons-cell
|
||||
magic-marker
|
||||
(make-cons-cell
|
||||
indicator
|
||||
(make-cons-cell value (CDDR binding)))))))
|
||||
(swap!
|
||||
oblist
|
||||
(fn [ob s p v]
|
||||
(make-cons-cell
|
||||
(make-beowulf-list (list s magic-marker p v))
|
||||
ob))
|
||||
symbol indicator value)))
|
||||
value)
|
||||
|
||||
(defn GET
|
||||
"From the manual:
|
||||
|
@ -477,13 +516,9 @@
|
|||
val (cond
|
||||
(= binding NIL) NIL
|
||||
(= magic-marker
|
||||
(CADR binding)) (loop [b binding]
|
||||
;; (println "GET loop, seeking " indicator ":")
|
||||
;; (pretty-print b)
|
||||
(if (instance? ConsCell b)
|
||||
(if (= (CAR b) indicator)
|
||||
(CADR b) ;; <- this is what we should actually be returning
|
||||
(recur (CDR b)))
|
||||
(CADR binding)) (let [p (hit-or-miss-assoc indicator binding)]
|
||||
(if-not (= NIL p)
|
||||
(CADR p)
|
||||
NIL))
|
||||
:else (throw
|
||||
(ex-info "Misformatted property list (missing magic marker)"
|
||||
|
@ -499,9 +534,10 @@
|
|||
`indicator` of the symbol which is the first element of the pair to the
|
||||
value which is the second element of the pair. See page 58 of the manual."
|
||||
[a-list indicator]
|
||||
(map
|
||||
#(PUT (CAR %) indicator (CDR %))
|
||||
a-list))
|
||||
(doall
|
||||
(map
|
||||
#(when (PUT (CAR %) indicator (CDR %)) (CAR %))
|
||||
a-list)))
|
||||
|
||||
(defn DEFINE
|
||||
"Bootstrap-only version of `DEFINE` which, post boostrap, can be overwritten
|
||||
|
|
|
@ -91,7 +91,8 @@
|
|||
([]
|
||||
(SYSOUT nil))
|
||||
([filepath]
|
||||
(spit (full-path (str filepath))
|
||||
(let [destination (full-path (str filepath))]
|
||||
(spit destination
|
||||
(with-out-str
|
||||
(println (apply str (repeat 79 ";")))
|
||||
(println (format ";; Beowulf %s Sysout file generated at %s"
|
||||
|
@ -103,7 +104,9 @@
|
|||
(println)
|
||||
(let [output (safely-wrap-subrs @oblist)]
|
||||
(pretty-print output)
|
||||
)))))
|
||||
)))
|
||||
(println "Saved sysout to " destination)
|
||||
NIL)))
|
||||
|
||||
(defn resolve-subr
|
||||
"If this oblist `entry` references a subroutine, attempt to fix up that
|
||||
|
|
|
@ -41,5 +41,5 @@
|
|||
|
||||
(def ^:dynamic *options*
|
||||
"Command line options from invocation."
|
||||
{})
|
||||
{:testing true})
|
||||
|
||||
|
|
|
@ -13,13 +13,14 @@
|
|||
|
||||
Both these extensions can be disabled by using the `--strict` command line
|
||||
switch."
|
||||
(:require ;; [beowulf.reader.char-reader :refer [read-chars]]
|
||||
(:require [beowulf.oblist :refer [*options*]]
|
||||
[beowulf.reader.char-reader :refer [read-chars]]
|
||||
[beowulf.reader.generate :refer [generate]]
|
||||
[beowulf.reader.parser :refer [parse]]
|
||||
[beowulf.reader.simplify :refer [simplify]]
|
||||
[clojure.string :refer [join split starts-with? trim]])
|
||||
(:import [java.io InputStream]
|
||||
[instaparse.gll Failure]))
|
||||
(:import [instaparse.gll Failure]
|
||||
[java.io InputStream]))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;
|
||||
|
@ -82,24 +83,35 @@
|
|||
(throw (ex-info "Ne can forstande " (assoc parse-tree :source source))))
|
||||
(generate (simplify parse-tree)))))
|
||||
|
||||
(defn read-from-console
|
||||
"Attempt to read a complete lisp expression from the console. NOTE that this
|
||||
will only really work for S-Expressions, not M-Expressions."
|
||||
[]
|
||||
(loop [r (read-line)]
|
||||
(if (and (= (count (re-seq #"\(" r))
|
||||
(count (re-seq #"\)" r)))
|
||||
(defn- dummy-read-chars [prompt]
|
||||
(loop [r "" p prompt]
|
||||
(if (and (seq r)
|
||||
(= (count (re-seq #"\(" r))
|
||||
(count (re-seq #"\)" r)))
|
||||
(= (count (re-seq #"\[" r))
|
||||
(count (re-seq #"\]" r))))
|
||||
r
|
||||
(recur (str r "\n" (read-line))))))
|
||||
(do
|
||||
(print (str p " "))
|
||||
(flush)
|
||||
(recur (str r "\n" (read-line)) "::")))))
|
||||
|
||||
(defn read-from-console
|
||||
"Attempt to read a complete lisp expression from the console.
|
||||
|
||||
There's a major problem here that the read-chars reader messes up testing.
|
||||
We need to be able to disable it while testing!"
|
||||
[prompt]
|
||||
(if (:testing *options*)
|
||||
(dummy-read-chars prompt)
|
||||
(read-chars prompt)))
|
||||
|
||||
(defn READ
|
||||
"An implementation of a Lisp reader sufficient for bootstrapping; not necessarily
|
||||
the final Lisp reader. `input` should be either a string representation of a LISP
|
||||
expression, or else an input stream. A single form will be read."
|
||||
([]
|
||||
(gsp (read-from-console)))
|
||||
(gsp (read-from-console (:prompt *options*))))
|
||||
([input]
|
||||
(cond
|
||||
(empty? input) (READ)
|
||||
|
|
|
@ -20,9 +20,12 @@
|
|||
TODO: There are multiple problems with JLine; a better solution might be
|
||||
to start from here:
|
||||
https://stackoverflow.com/questions/7931988/how-to-manipulate-control-characters"
|
||||
;; (:import [org.jline.reader LineReader LineReaderBuilder]
|
||||
;; [org.jline.terminal TerminalBuilder])
|
||||
)
|
||||
(:require [beowulf.oblist :refer [*options* oblist]])
|
||||
(:import [org.jline.reader.impl.completer StringsCompleter]
|
||||
[org.jline.reader.impl DefaultParser DefaultParser$Bracket]
|
||||
[org.jline.reader LineReaderBuilder]
|
||||
[org.jline.terminal TerminalBuilder]
|
||||
[org.jline.widget AutopairWidgets AutosuggestionWidgets]))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;
|
||||
|
@ -49,27 +52,56 @@
|
|||
;; looks as though you'd need a DPhil in JLine to write it, and I don't have
|
||||
;; the time.
|
||||
|
||||
;; (def get-reader
|
||||
;; "Return a reader, first constructing it if necessary.
|
||||
(defn build-completer
|
||||
"Build a completer which takes tokens from the oblist.
|
||||
|
||||
;; **NOTE THAT** this is not settled API. The existence and call signature of
|
||||
;; this function is not guaranteed in future versions."
|
||||
;; (memoize (fn []
|
||||
;; (let [term (.build (.system (TerminalBuilder/builder) true))]
|
||||
;; (.build (.terminal (LineReaderBuilder/builder) term))))))
|
||||
This is sort-of working, in as much as hitting <TAB> on a blank line will
|
||||
show a table of values from the oblist, but hitting <TAB> after you've
|
||||
started input does not show potential completions for tokens you've started."
|
||||
[]
|
||||
(StringsCompleter. (map #(str (first %)) @oblist)))
|
||||
|
||||
;; (defn read-chars
|
||||
;; "A drop-in replacement for `clojure.core/read-line`, except that line editing
|
||||
;; and history should be enabled.
|
||||
;; This breaks; it is not correctly resolving the Enum, although I can't work out
|
||||
;; why not.
|
||||
;; (defn build-parser
|
||||
;; []
|
||||
;; (println "Building parser")
|
||||
;; (let [parser (DefaultParser.)]
|
||||
;; (doall
|
||||
;; (.setEofOnUnclosedBracket
|
||||
;; parser DefaultParser$Bracket/ROUND))))
|
||||
|
||||
(def get-reader
|
||||
"Return a reader, first constructing it if necessary.
|
||||
|
||||
;; **NOTE THAT** this does not work yet, but it is in the API because I hope
|
||||
;; that it will work later!"
|
||||
;; []
|
||||
;; (let [eddie (get-reader)]
|
||||
;; (loop [s (.readLine eddie)]
|
||||
;; (if (and (= (count (re-seq #"\(" s))
|
||||
;; (count (re-seq #"\)" s)))
|
||||
;; (= (count (re-seq #"\[]" s))
|
||||
;; (count (re-seq #"\]" s))))
|
||||
;; s
|
||||
;; (recur (str s " " (.readLine eddie)))))))
|
||||
**NOTE THAT** this is not settled API. The existence and call signature of
|
||||
this function is not guaranteed in future versions."
|
||||
(memoize (fn []
|
||||
(let [term (.build (.system (TerminalBuilder/builder) true))
|
||||
reader (-> (LineReaderBuilder/builder)
|
||||
(.terminal term)
|
||||
(.completer (build-completer))
|
||||
;; #(.parser % (build-parser))
|
||||
(.build))
|
||||
;; apw (AutopairWidgets. reader false)
|
||||
;; asw (AutosuggestionWidgets. reader)
|
||||
]
|
||||
;; (.enable apw)
|
||||
;; (.enable asw)
|
||||
reader))))
|
||||
|
||||
(defn read-chars
|
||||
"A drop-in replacement for `clojure.core/read-line`, except that line editing
|
||||
and history should be enabled.
|
||||
|
||||
**NOTE THAT** this does not fully work yet, but it is in the API because I
|
||||
hope that it will work later!"
|
||||
[prompt]
|
||||
(let [eddie (get-reader)]
|
||||
(loop [s (.readLine eddie (str prompt " "))]
|
||||
(if (and (= (count (re-seq #"\(" s))
|
||||
(count (re-seq #"\)" s)))
|
||||
(= (count (re-seq #"\[]" s))
|
||||
(count (re-seq #"\]" s))))
|
||||
s
|
||||
(recur (str s " " (.readLine eddie ":: ")))))))
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
(ns beowulf.core-test
|
||||
(:require [clojure.java.io :refer [reader]]
|
||||
[clojure.string :refer [split]]
|
||||
[clojure.test :refer [deftest is testing]]
|
||||
[beowulf.core :refer [-main repl stop-word]]))
|
||||
(:require [beowulf.core :refer [-main repl stop-word]]
|
||||
[beowulf.oblist :refer [*options*]]
|
||||
[clojure.java.io :refer [reader]]
|
||||
[clojure.string :refer [split starts-with?]]
|
||||
[clojure.test :refer [deftest is testing]]))
|
||||
|
||||
;; (deftest a-test
|
||||
;; (testing "FIXME, I fail."
|
||||
|
@ -20,45 +21,43 @@
|
|||
(deftest repl-tests
|
||||
(testing "quit functionality"
|
||||
(with-open [r (reader (string->stream stop-word))]
|
||||
(binding [*in* r]
|
||||
(binding [clojure.core/*in* r
|
||||
*options* (assoc *options* :testing true)]
|
||||
(is (thrown-with-msg? Exception #"\nFærwell!" (repl "")))))
|
||||
|
||||
(let [expected nil
|
||||
actual (with-open [r (reader (string->stream stop-word))]
|
||||
(binding [*in* r]
|
||||
(-main)))]
|
||||
(-main "--testing")))]
|
||||
(is (= actual expected)))))
|
||||
|
||||
;; TODO: not working because STOP is not being recognised, but I haven't
|
||||
;; worked out why not yet. It *did* work.
|
||||
|
||||
;; The new read-chars interface is really messing with this. Need to sort out!
|
||||
;; OK, binding `:testing` doesn't work because `*options*` gets rebound in main.
|
||||
;; Need to be able to pass in a testing flag as argument to -main
|
||||
(deftest flag-tests
|
||||
(testing "No flags"
|
||||
(testing "Only testing flag"
|
||||
(let [expected-greeting "Hider wilcuman. Béowulf is mín nama."
|
||||
expected-quit-message (str "Sprecan '" stop-word "' tó laéfan")
|
||||
expected-result #".*\(3 \. 4\)"
|
||||
expected-prompt "Sprecan:: "
|
||||
expected-signoff "Færwell!"
|
||||
;; anticipated output (note blank lines):
|
||||
|
||||
; Hider wilcuman. Béowulf is mín nama.
|
||||
|
||||
; Sprecan 'STOP' tó laéfan
|
||||
|
||||
; Sprecan:: > (3 . 4)
|
||||
; Sprecan::
|
||||
; Færwell!
|
||||
|
||||
;; Hider wilcuman. Béowulf is mín nama.
|
||||
|
||||
;; Sprecan 'STOP' tó laéfan
|
||||
|
||||
;; Sprecan:: > (3 . 4)
|
||||
;; Sprecan::
|
||||
;; Færwell!
|
||||
[_ greeting _ _ quit-message _ result prompt signoff]
|
||||
(with-open [r (reader (string->stream (str "cons[3; 4]\n" stop-word)))]
|
||||
(binding [*in* r]
|
||||
(split (with-out-str (-main)) #"\n")))]
|
||||
(split (with-out-str (-main "--testing")) #"\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))
|
||||
))
|
||||
(is (= signoff expected-signoff))))
|
||||
(testing "unknown flag"
|
||||
(let [expected-greeting "Hider wilcuman. Béowulf is mín nama."
|
||||
expected-quit-message (str "Sprecan '" stop-word "' tó laéfan")
|
||||
|
@ -69,115 +68,63 @@
|
|||
[_ greeting _ error quit-message _ result prompt signoff]
|
||||
(with-open [r (reader (string->stream (str "cons[5; 6]\n" stop-word)))]
|
||||
(binding [*in* r]
|
||||
(split (with-out-str (-main "--unknown")) #"\n")))]
|
||||
(split (with-out-str (-main "--unknown" "--testing")) #"\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 (str "Sprecan '" stop-word "' tó laéfan")
|
||||
; expected-result #".*\(A \. B\)"
|
||||
; expected-prompt "Sprecan:: "
|
||||
; expected-signoff "Færwell!"
|
||||
; [_ greeting _ h1 _ _ _ _ quit-message _ result prompt signoff]
|
||||
; (with-open [r (reader (string->stream (str "cons[A; B]\n" stop-word)))]
|
||||
; (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 (str "Sprecan '" stop-word "' tó laéfan")
|
||||
; expected-error ""
|
||||
; expected-result #".*\(A \. B\).*"
|
||||
; expected-prompt "? "
|
||||
; expected-signoff "Færwell!"
|
||||
; [_ greeting _ error quit-message _ result prompt signoff]
|
||||
; (with-open [r (reader (string->stream (str stop-word)))]
|
||||
; (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 (str "Sprecan '" stop-word "' tó laéfan")
|
||||
; expected-error #"Failed to validate.*"
|
||||
; expected-result #".*\(A \. B\)"
|
||||
; expected-prompt "Sprecan:: "
|
||||
; expected-signoff "Færwell!"
|
||||
; [_ greeting _ error quit-message _ result prompt signoff]
|
||||
; (with-open [r (reader (string->stream (str "cons[A; B]\n" stop-word)))]
|
||||
; (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 (str "Sprecan '" stop-word "' tó laéfan")
|
||||
; expected-error ""
|
||||
; expected-result #".*\(A \. B\)"
|
||||
; expected-prompt "Sprecan:: "
|
||||
; expected-signoff "Færwell!"
|
||||
; [_ greeting error quit-message _ _ result prompt signoff]
|
||||
; (with-open [r (reader (string->stream (str "cons[A; B]\n" stop-word)))]
|
||||
; (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 (str "Sprecan '" stop-word "' tó laéfan")
|
||||
; expected-error ""
|
||||
; expected-result #".*Cannot parse meta expressions in strict mode.*"
|
||||
; expected-prompt "Sprecan:: "
|
||||
; expected-signoff "Færwell!"
|
||||
; [_ greeting _ error quit-message _ result prompt signoff]
|
||||
; (with-open [r (reader (string->stream (str "cons[A; B]\n" stop-word)))]
|
||||
; (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-error ""
|
||||
; expected-trace #".*traced-eval.*"
|
||||
; [_ greeting _ error _ _ trace & _]
|
||||
; (with-open [r (reader (string->stream (str "cons[A; B]\n" stop-word)))]
|
||||
; (binding [*in* r]
|
||||
; (split (with-out-str (-main "--trace")) #"\n")))]
|
||||
; (is (= greeting expected-greeting))
|
||||
; (is (= error expected-error))
|
||||
; (is (re-matches expected-trace trace))
|
||||
)
|
||||
(is (= signoff expected-signoff))))
|
||||
;; ;; TODO: not working because STOP is not being recognised, but I haven't
|
||||
;; ;; worked out why not yet. It *did* work.
|
||||
|
||||
;; Hider wilcuman. Béowulf is mín nama.
|
||||
;; -f FILEPATH, --file-path FILEPATH Set the path to the directory for reading and writing Lisp files.
|
||||
;; -h, --help
|
||||
;; -p PROMPT, --prompt PROMPT Sprecan:: Set the REPL prompt to PROMPT
|
||||
;; -r SYSOUTFILE, --read SYSOUTFILE lisp1.5.lsp Read Lisp system from file SYSOUTFILE
|
||||
;; -s, --strict Strictly interpret the Lisp 1.5 language, without extensions.
|
||||
;; -t, --time Time evaluations.
|
||||
;; -x, --testing Disable the jline reader - useful when piping input.
|
||||
;; Sprecan 'STOP' tó laéfan
|
||||
|
||||
;; Sprecan::
|
||||
|
||||
(testing "help"
|
||||
(let [expected-greeting "Hider wilcuman. Béowulf is mín nama."
|
||||
expected-h1 " -h, --help"
|
||||
expected-quit-message (str "Sprecan '" stop-word "' tó laéfan")
|
||||
expected-result #".*\(A \. B\)"
|
||||
expected-prompt "Sprecan:: "
|
||||
expected-signoff "Færwell!"
|
||||
[_ greeting _ _ h1 _ _ _ _ _ quit-message _ result prompt signoff]
|
||||
(with-open [r (reader (string->stream (str "cons[A; B]\n" stop-word)))]
|
||||
(binding [*in* r]
|
||||
(split (with-out-str (-main "--help" "--testing")) #"\n")))]
|
||||
(is (= greeting expected-greeting))
|
||||
(is (= h1 expected-h1))
|
||||
(is (re-matches expected-result result))
|
||||
(is (= quit-message expected-quit-message))
|
||||
(is (starts-with? prompt expected-prompt))
|
||||
(is (= signoff expected-signoff))))
|
||||
(testing "prompt"
|
||||
(let [expected-prompt "? "
|
||||
[_ _ _ _ _ _ prompt _]
|
||||
(with-open [r (reader (string->stream stop-word))]
|
||||
(binding [*in* r]
|
||||
(split (with-out-str (-main "--prompt" "?" "--testing")) #"\n")))]
|
||||
(is (= prompt expected-prompt))))
|
||||
(testing "read - file not found"
|
||||
(let [expected-error #"Failed to validate.*"
|
||||
[_ _ _ error _ _ _ _ _]
|
||||
(with-open [r (reader (string->stream (str "cons[A; B]\n" stop-word)))]
|
||||
(binding [*in* r]
|
||||
(split (with-out-str (-main "--testing" "--read" "froboz")) #"\n")))]
|
||||
(is (re-matches expected-error error))))
|
||||
(testing "strict"
|
||||
(let [expected-result #".*Cannot parse meta expressions in strict mode.*"
|
||||
[_ _ _ _ _ _ result _ _]
|
||||
(with-open [r (reader (string->stream (str "cons[A; B]\n" stop-word)))]
|
||||
(binding [*in* r]
|
||||
(split (with-out-str (-main "--strict" "--testing")) #"\n")))]
|
||||
(is (re-matches expected-result result )))))
|
||||
|
|
|
@ -1,38 +1,66 @@
|
|||
(ns beowulf.host-test
|
||||
(:require [clojure.test :refer [deftest is testing]]
|
||||
[beowulf.cons-cell :refer [F make-beowulf-list T]]
|
||||
[beowulf.host :refer [CDR DIFFERENCE NUMBERP PLUS RPLACA RPLACD TIMES]]
|
||||
[beowulf.oblist :refer [NIL]]
|
||||
[beowulf.read :refer [gsp]]))
|
||||
(:require [beowulf.cons-cell :refer [F make-beowulf-list make-cons-cell T]]
|
||||
[beowulf.host :refer [ADD1 AND CADDDR CAR CDR DEFINE DIFFERENCE
|
||||
ERROR FIXP GREATERP lax? LESSP NILP NULL
|
||||
NUMBERP OR PLUS RPLACA RPLACD SUB1 TIMES uaf]]
|
||||
[beowulf.io :refer [SYSIN]]
|
||||
[beowulf.oblist :refer [*options* NIL]]
|
||||
[beowulf.read :refer [gsp]]
|
||||
[clojure.test :refer [deftest is testing use-fixtures]]
|
||||
[expectations.clojure.test
|
||||
:refer [defexpect expect more-> more-of]]))
|
||||
|
||||
(use-fixtures :once (fn [f]
|
||||
(try (when (SYSIN "resources/lisp1.5.lsp")
|
||||
(f))
|
||||
(catch Throwable any
|
||||
(throw (ex-info "Failed to load Lisp sysout"
|
||||
{:phase test
|
||||
:function 'SYSIN
|
||||
:file "resources/lisp1.5.lsp"}
|
||||
any))))))
|
||||
|
||||
(deftest destructive-change-test
|
||||
(testing "RPLACA"
|
||||
(let
|
||||
[l (make-beowulf-list '(A B C D E))
|
||||
target (CDR l)
|
||||
expected "(A F C D E)"
|
||||
actual (do (RPLACA target 'F) (print-str l))]
|
||||
[l (make-beowulf-list '(A B C D E))
|
||||
target (CDR l)
|
||||
expected "(A F C D E)"
|
||||
actual (do (RPLACA target 'F) (print-str l))]
|
||||
(is (= actual expected)))
|
||||
(is (thrown-with-msg?
|
||||
Exception
|
||||
#"Un-ġefōg þing in RPLACA.*"
|
||||
(RPLACA (make-beowulf-list '(A B C D E)) "F"))
|
||||
Exception
|
||||
#"Un-ġefōg þing in RPLACA.*"
|
||||
(RPLACA (make-beowulf-list '(A B C D E)) "F"))
|
||||
"You can't represent a string in Lisp 1.5")
|
||||
(is (thrown-with-msg?
|
||||
Exception
|
||||
#"Uncynlic miercels in RPLACA.*"
|
||||
(RPLACA '(A B C D E) 'F))
|
||||
"You can't RPLACA into anything which isn't a MutableSequence.")
|
||||
)
|
||||
(testing "RPLACA"
|
||||
Exception
|
||||
#"Uncynlic miercels in RPLACA.*"
|
||||
(RPLACA '(A B C D E) 'F))
|
||||
"You can't RPLACA into anything which isn't a MutableSequence."))
|
||||
(testing "RPLACD"
|
||||
(let
|
||||
[l (make-beowulf-list '(A B C D E))
|
||||
target (CDR l)
|
||||
expected "(A B . F)"
|
||||
actual (do (RPLACD target 'F) (print-str l))]
|
||||
[l (make-beowulf-list '(A B C D E))
|
||||
target (CDR l)
|
||||
expected "(A B . F)"
|
||||
actual (do (RPLACD target 'F) (print-str l))]
|
||||
(is (= actual expected)))
|
||||
)
|
||||
)
|
||||
(let
|
||||
[l (make-beowulf-list '(A B C D E))
|
||||
target (CDR l)
|
||||
expected "(A B)"
|
||||
actual (do (RPLACD target NIL) (print-str l))]
|
||||
(is (= actual expected)))
|
||||
(is (thrown-with-msg?
|
||||
Exception
|
||||
#"Un-ġefōg þing in RPLACD.*"
|
||||
(RPLACD (make-beowulf-list '(A B C D E)) :a))
|
||||
"You can't represent a keyword in Lisp 1.5")
|
||||
(is (thrown-with-msg?
|
||||
Exception
|
||||
#"Uncynlic miercels in RPLACD.*"
|
||||
(RPLACD "ABCDE" 'F))
|
||||
"You can't RPLACD into anything which isn't a MutableSequence.")))
|
||||
|
||||
(deftest numberp-tests
|
||||
(testing "NUMBERP"
|
||||
|
@ -59,12 +87,171 @@
|
|||
(let [expected 3.5
|
||||
actual (PLUS 1.25 9/4)]
|
||||
(is (= actual expected))
|
||||
(is (float? actual)))
|
||||
(let [expected 3.5
|
||||
actual (PLUS -2.5 6)]
|
||||
(is (= actual expected) "Negative numbers are cool.")
|
||||
(is (float? actual))))
|
||||
(testing "TIMES"
|
||||
(let [expected 6
|
||||
actual (TIMES 2 3)]
|
||||
(is (= actual expected)))
|
||||
(let [expected 2.5
|
||||
actual (TIMES 5 0.5)]
|
||||
(is (= actual expected))))
|
||||
(testing DIFFERENCE
|
||||
(testing "DIFFERENCE"
|
||||
(let [expected -1
|
||||
actual (DIFFERENCE 1 2)]
|
||||
(is (= actual expected)))
|
||||
(let [expected (float 0.1)
|
||||
actual (DIFFERENCE -0.1 -0.2)]
|
||||
(is (= actual expected))))
|
||||
(testing "ADD1"
|
||||
(let [expected -1
|
||||
actual (ADD1 -2)]
|
||||
(is (= actual expected)))
|
||||
(let [expected (float 3.5)
|
||||
actual (ADD1 2.5)]
|
||||
(is (= actual expected))))
|
||||
(testing "SUB1"
|
||||
(let [expected -3
|
||||
actual (SUB1 -2)]
|
||||
(is (= actual expected)))
|
||||
(let [expected (float 1.5)
|
||||
actual (SUB1 2.5)]
|
||||
(is (= actual expected)))))
|
||||
|
||||
(deftest laxness
|
||||
(testing "lax"
|
||||
(let [expected true
|
||||
actual (lax? 'Test)]
|
||||
(is (= actual expected) "Pass, the Queen's Cat, and all's well")))
|
||||
(testing "strict"
|
||||
(binding [*options* (assoc *options* :strict true)]
|
||||
(is (thrown-with-msg? Exception #".*ne āfand innan Lisp 1.5" (lax? 'Test))))))
|
||||
|
||||
(deftest access-tests
|
||||
(testing "primitive access"
|
||||
(let [cell (make-cons-cell 1 7)]
|
||||
(let [expected 1
|
||||
actual (CAR cell)]
|
||||
(is (= actual expected)))
|
||||
(let [expected 7
|
||||
actual (CDR cell)]
|
||||
(is (= actual expected))))
|
||||
(is (thrown-with-msg? Exception #".*Ne can tace CAR of.*" (CAR 7)))
|
||||
(is (thrown-with-msg? Exception #".*Ne can tace CDR of.*" (CDR 'A)))
|
||||
(is (thrown-with-msg? Exception #".*Ne liste.*" (CADDDR "Foo")))
|
||||
(is (thrown-with-msg? Exception #".*uaf: unexpected letter in path.*"
|
||||
(uaf (make-beowulf-list '(A B C D))
|
||||
'(\d \a \z \e \d))))))
|
||||
|
||||
(deftest misc-predicate-tests
|
||||
(testing "NULL"
|
||||
(let [expected T
|
||||
actual (NULL NIL)]
|
||||
(is (= actual expected)))
|
||||
(let [expected F
|
||||
actual (NULL (make-beowulf-list '(A B C)))]
|
||||
(is (= actual expected))))
|
||||
(testing "NILP"
|
||||
(let [expected T
|
||||
actual (NILP NIL)]
|
||||
(is (= actual expected)))
|
||||
(let [expected NIL
|
||||
actual (NILP (make-beowulf-list '(A B C)))]
|
||||
(is (= actual expected))))
|
||||
(testing "AND"
|
||||
(let [expected T
|
||||
actual (AND)]
|
||||
(is (= actual expected)))
|
||||
(let [expected T
|
||||
actual (AND T T)]
|
||||
(is (= actual expected)))
|
||||
(let [expected T
|
||||
actual (AND T T T)]
|
||||
(is (= actual expected)))
|
||||
(let [expected T
|
||||
actual (AND 1 'A (make-beowulf-list '(A B C)))]
|
||||
(is (= actual expected)))
|
||||
(let [expected F
|
||||
actual (AND NIL)]
|
||||
(is (= actual expected)))
|
||||
(let [expected F
|
||||
actual (AND T T F T)]
|
||||
(is (= actual expected))))
|
||||
(testing "OR"
|
||||
(let [expected F
|
||||
actual (OR)]
|
||||
(is (= actual expected)))
|
||||
(let [expected T
|
||||
actual (OR NIL T)]
|
||||
(is (= actual expected)))
|
||||
(let [expected T
|
||||
actual (OR T F T)]
|
||||
(is (= actual expected)))
|
||||
(let [expected T
|
||||
actual (OR 1 F (make-beowulf-list '(A B C)))]
|
||||
(is (= actual expected)))
|
||||
(let [expected F
|
||||
actual (OR NIL)]
|
||||
(is (= actual expected)))
|
||||
(let [expected F
|
||||
actual (OR NIL F)]
|
||||
(is (= actual expected))))
|
||||
(testing "FIXP"
|
||||
(let [expected F
|
||||
actual (FIXP NIL)]
|
||||
(is (= actual expected)))
|
||||
(let [expected F
|
||||
actual (FIXP 'A)]
|
||||
(is (= actual expected)))
|
||||
(let [expected F
|
||||
actual (FIXP 3.2)]
|
||||
(is (= actual expected)))
|
||||
(let [expected T
|
||||
actual (FIXP 7)]
|
||||
(is (= actual expected))))
|
||||
(testing "LESSP"
|
||||
(let [expected F
|
||||
actual (LESSP 7 3)]
|
||||
(is (= actual expected)))
|
||||
(let [expected T
|
||||
actual (LESSP -7 3.5)]
|
||||
(is (= actual expected)))
|
||||
(let [expected F
|
||||
actual (LESSP 3.14 3.14)]
|
||||
(is (= actual expected))))
|
||||
(testing "GREATERP"
|
||||
(let [expected T
|
||||
actual (GREATERP 7 3)]
|
||||
(is (= actual expected)))
|
||||
(let [expected F
|
||||
actual (GREATERP -7 3.5)]
|
||||
(is (= actual expected)))
|
||||
(let [expected F
|
||||
actual (GREATERP 3.14 3.14)]
|
||||
(is (= actual expected)))))
|
||||
|
||||
;; Really tricky to get DEFINE set up for testing here. It works OK in the
|
||||
;; REPL, but there's nonsense going on with lazy sequences. Better to
|
||||
;; reimplement in Lisp.
|
||||
;; (deftest define-tests
|
||||
;; (testing "DEFINE"
|
||||
;; (let [expected "(FF)"
|
||||
;; actual (str (doall (DEFINE
|
||||
;; (gsp "((FF LAMBDA (X) (COND ((ATOM X) X) (T (FF (CAR X))))))"))))]
|
||||
;; (is (= actual expected)))))
|
||||
|
||||
(defexpect error-without-code
|
||||
(expect (more-> clojure.lang.ExceptionInfo type
|
||||
(more-of {:keys [:phase :function :args :type :code]}
|
||||
'A1 code) ex-data)
|
||||
(ERROR)))
|
||||
|
||||
(defexpect error-with-code
|
||||
(let [x 'X1]
|
||||
(expect (more-> clojure.lang.ExceptionInfo type
|
||||
(more-of {:keys [:phase :function :args :type :code]}
|
||||
x code) ex-data)
|
||||
(ERROR x))))
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
(ns beowulf.lisp-test
|
||||
"The idea here is to test actual Lisp functions"
|
||||
(:require [clojure.test :refer [deftest testing is use-fixtures]]
|
||||
[beowulf.bootstrap :refer [EVAL]]
|
||||
(:require [beowulf.bootstrap :refer [EVAL]]
|
||||
[beowulf.cons-cell :refer [make-beowulf-list]]
|
||||
[beowulf.io :refer [SYSIN]]
|
||||
;; [beowulf.oblist :refer [NIL]]
|
||||
[beowulf.read :refer [READ]]))
|
||||
[beowulf.io :refer [SYSIN]] ;; [beowulf.oblist :refer [NIL]]
|
||||
[beowulf.oblist :refer [NIL]]
|
||||
[beowulf.read :refer [READ]]
|
||||
[clojure.test :refer [deftest is testing use-fixtures]]))
|
||||
|
||||
(defn- reps
|
||||
(defn reps
|
||||
"'Read eval print string', or 'read eval print single'.
|
||||
Reads and evaluates one input string, and returns the
|
||||
output string."
|
||||
|
@ -130,7 +130,6 @@
|
|||
actual (reps input)]
|
||||
(is (= actual expected))))))
|
||||
|
||||
|
||||
(deftest MEMBER-tests
|
||||
(testing "member"
|
||||
(let [expected "T"
|
||||
|
@ -147,17 +146,18 @@
|
|||
(is (= actual expected)))))
|
||||
|
||||
;; This is failing, and although yes, it does matter, I have not yet tracked the reason.
|
||||
;; (deftest sublis-tests
|
||||
;; (testing "sublis"
|
||||
;; (let [expected "(SHAKESPEARE WROTE (THE TEMPEST))"
|
||||
;; actual (reps
|
||||
;; "(SUBLIS
|
||||
;; '((X . SHAKESPEARE) (Y . (THE TEMPEST)))
|
||||
;; '(X WROTE Y))")]
|
||||
;; (is (= actual expected)))))
|
||||
(deftest sublis-tests
|
||||
(testing "sublis"
|
||||
(let [expected "(SHAKESPEARE WROTE (THE TEMPEST))"
|
||||
actual (reps
|
||||
"(SUBLIS
|
||||
'((X . SHAKESPEARE) (Y . (THE TEMPEST)))
|
||||
'(X WROTE Y))")]
|
||||
(is (= actual expected)))))
|
||||
|
||||
(deftest prog-tests
|
||||
(testing "PROG"
|
||||
;; (reps "(TRACE 'PROG)")
|
||||
(let [expected "5"
|
||||
actual (reps "(PROG (X)
|
||||
(SETQ X 1)
|
||||
|
@ -165,4 +165,61 @@
|
|||
(SETQ X (ADD1 X))
|
||||
(COND ((EQ X 5) (RETURN X))
|
||||
(T (GO START))))")]
|
||||
(is (= actual expected)))))
|
||||
|
||||
(deftest put-get-tests
|
||||
(let [symbol 'TESTSYMBOL
|
||||
p1 'TESTPROPONE
|
||||
p2 'TESTPROPTWO]
|
||||
(testing "GET - property should be missing"
|
||||
(let [expected "NIL"
|
||||
actual (reps "(GET 'TESTSYMBOL 'TESTPROPONE)")]
|
||||
(is (= actual expected))))
|
||||
(testing "PUT and GET: value of new property; change value of property"
|
||||
(let [prop (reps "(GENSYM)")
|
||||
val1 (reps "(GENSYM)")
|
||||
val2 (reps "(GENSYM)")
|
||||
expected1 val1
|
||||
actual1 (when (reps (str "(PUT '" symbol " '" prop " '" val1 ")"))
|
||||
(reps (str "(GET '" symbol " '" prop ")")))
|
||||
expected2 val2
|
||||
actual2 (when (reps (str "(PUT '" symbol " '" prop " '" val2 ")"))
|
||||
(reps (str "(GET '" symbol " '" prop ")")))]
|
||||
(is (not= val1 val2))
|
||||
(is (= actual1 expected1) "The value set can be retrieved.")
|
||||
(is (= actual2 expected2) "The value is changed.")))
|
||||
(testing "PUT and GET: different properties have independent values"
|
||||
(let [val1 (reps "(GENSYM)")
|
||||
val2 (reps "(GENSYM)")
|
||||
expected1 val1
|
||||
actual1 (when (reps (str "(PUT '" symbol " '" p1 " '" val1 ")"))
|
||||
(reps (str "(GET '" symbol " '" p1 ")")))
|
||||
expected2 val2
|
||||
actual2 (when (reps (str "(PUT '" symbol " '" p2 " '" val2 ")"))
|
||||
(reps (str "(GET '" symbol " '" p2 ")")))
|
||||
expected3 val1
|
||||
actual3 (reps (str "(GET '" symbol " '" p1 ")"))]
|
||||
(is (not= val1 val2))
|
||||
(is (= actual1 expected1) "The value set can be retrieved.")
|
||||
(is (= actual2 expected2) "Values are independent.")
|
||||
(is (= actual3 expected3) "Setting a second property does not obliterate the first.")))))
|
||||
|
||||
(deftest fsubr-tests
|
||||
(testing "FSUBR/CONC"
|
||||
(reps "(SETQ P (RANGE 1 4))")
|
||||
(reps "(SETQ Q (RANGE 5 8))")
|
||||
(reps "(SETQ R (RANGE 9 12))")
|
||||
(let [expected "(1 2 3 4 5 6 7 8 9 10 11 12)"
|
||||
actual (reps "(CONC P Q R)")]
|
||||
(is (= actual expected)))))
|
||||
|
||||
(deftest attrib-tests
|
||||
(testing "ATTRIB"
|
||||
(reps "(SETQ X '(A B C))")
|
||||
(reps "(SETQ Y '(D E F))")
|
||||
(let [expected "(D E F)"
|
||||
actual (reps "(ATTRIB X Y)")]
|
||||
(is (= actual expected)))
|
||||
(let [expected "(A B C D E F)"
|
||||
actual (reps "X")]
|
||||
(is (= actual expected)))))
|
Loading…
Reference in a new issue