Merge branch 'feature/6' into develop
This commit is contained in:
commit
01e4572119
|
@ -331,13 +331,13 @@
|
|||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
109 ;; else
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
110 (beowulf.bootstrap/EVAL expr
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
<span class="partial" title="7 out of 11 forms covered">
|
||||
111 (merge-vars vars env)
|
||||
</span><br/>
|
||||
<span class="partial" title="4 out of 8 forms covered">
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
112 depth))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
|
@ -352,13 +352,13 @@
|
|||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
116
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
117 Lisp 1.5 introduced `PROG`, and most Lisps have been stuck with it ever
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
<span class="partial" title="3 out of 7 forms covered">
|
||||
118 since. It introduces imperative programming into what should be a pure
|
||||
</span><br/>
|
||||
<span class="partial" title="3 out of 7 forms covered">
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
119 functional language, and consequently it's going to be a pig to implement.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
|
@ -757,7 +757,7 @@
|
|||
<span class="covered" title="5 out of 5 forms covered">
|
||||
251 (let [lisp-fn (value function-symbol '(EXPR FEXPR))
|
||||
</span><br/>
|
||||
<span class="partial" title="6 out of 8 forms covered">
|
||||
<span class="partial" title="7 out of 8 forms covered">
|
||||
252 args' (cond (= NIL args) args
|
||||
</span><br/>
|
||||
<span class="partial" title="3 out of 4 forms covered">
|
||||
|
|
|
@ -259,7 +259,7 @@
|
|||
<span class="covered" title="1 out of 1 forms covered">
|
||||
085 (if
|
||||
</span><br/>
|
||||
<span class="partial" title="10 out of 13 forms covered">
|
||||
<span class="partial" title="11 out of 13 forms covered">
|
||||
086 (or
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
|
@ -445,22 +445,22 @@
|
|||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
147 clojure.lang.Counted
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
148 (count [this] (loop [cell this
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
149 result 1]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
150 (if
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 11 forms covered">
|
||||
<span class="covered" title="11 out of 11 forms covered">
|
||||
151 (and (coll? (.getCdr cell)) (not= NIL (.getCdr cell)))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
152 (recur (.getCdr cell) (inc result))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
153 result)))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
|
|
|
@ -154,10 +154,10 @@
|
|||
<span class="covered" title="1 out of 1 forms covered">
|
||||
050 :default default-sysout
|
||||
</span><br/>
|
||||
<span class="partial" title="3 out of 8 forms covered">
|
||||
<span class="partial" title="7 out of 8 forms covered">
|
||||
051 :validate [#(and
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
<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">
|
||||
|
@ -170,40 +170,40 @@
|
|||
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."]])
|
||||
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">
|
||||
057
|
||||
058
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
058 (defn- re
|
||||
059 (defn- re
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
059 "Like REPL, but it isn't a loop and doesn't print."
|
||||
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">
|
||||
060 [input]
|
||||
061 [input]
|
||||
</span><br/>
|
||||
<span class="covered" title="7 out of 7 forms covered">
|
||||
061 (EVAL (READ input) NIL 0))
|
||||
062 (EVAL (READ input) NIL 0))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
062
|
||||
063
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
063 (defn repl
|
||||
064 (defn repl
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
064 "Read/eval/print loop."
|
||||
065 "Read/eval/print loop."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
065 [prompt]
|
||||
066 [prompt]
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
066 (loop []
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
067 (print prompt)
|
||||
067 (loop []
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
068 (flush)
|
||||
|
@ -211,8 +211,8 @@
|
|||
<span class="covered" title="1 out of 1 forms covered">
|
||||
069 (try
|
||||
</span><br/>
|
||||
<span class="covered" title="9 out of 9 forms covered">
|
||||
070 (if-let [input (trim (read-from-console))]
|
||||
<span class="covered" title="10 out of 10 forms covered">
|
||||
070 (if-let [input (trim (read-from-console prompt))]
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
071 (if (= input stop-word)
|
||||
|
@ -259,7 +259,7 @@
|
|||
<span class="covered" title="1 out of 1 forms covered">
|
||||
085 data
|
||||
</span><br/>
|
||||
<span class="partial" title="5 out of 6 forms covered">
|
||||
<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">
|
||||
|
@ -316,13 +316,13 @@
|
|||
<span class="covered" title="6 out of 6 forms covered">
|
||||
104 (str "Síðe " (System/getProperty "beowulf.version") "\n"))
|
||||
</span><br/>
|
||||
<span class="partial" title="1 out of 2 forms covered">
|
||||
<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="not-covered" title="0 out of 3 forms covered">
|
||||
<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">
|
||||
|
@ -358,8 +358,8 @@
|
|||
<span class="covered" title="1 out of 1 forms covered">
|
||||
118 (try
|
||||
</span><br/>
|
||||
<span class="covered" title="10 out of 10 forms covered">
|
||||
119 (repl (str (:prompt (:options args)) " "))
|
||||
<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
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -334,13 +334,13 @@
|
|||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
110 reference."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
<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="partial" title="1 out of 6 forms covered">
|
||||
<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">
|
||||
|
|
|
@ -133,8 +133,8 @@
|
|||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
043 "Command line options from invocation."
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
044 {})
|
||||
<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
|
||||
|
|
|
@ -50,283 +50,319 @@
|
|||
015 switch."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
016 (:require ;; [beowulf.reader.char-reader :refer [read-chars]]
|
||||
016 (:require [beowulf.oblist :refer [*options*]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
017 [beowulf.reader.generate :refer [generate]]
|
||||
017 [beowulf.reader.char-reader :refer [read-chars]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
018 [beowulf.reader.parser :refer [parse]]
|
||||
018 [beowulf.reader.generate :refer [generate]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
019 [beowulf.reader.simplify :refer [simplify]]
|
||||
019 [beowulf.reader.parser :refer [parse]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
020 [clojure.string :refer [join split starts-with? trim]])
|
||||
020 [beowulf.reader.simplify :refer [simplify]]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
021 (:import [java.io InputStream]
|
||||
021 [clojure.string :refer [join split starts-with? trim]])
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
022 [instaparse.gll Failure]))
|
||||
022 (:import [instaparse.gll Failure]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
023 [java.io InputStream]))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
023
|
||||
024
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
024 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
025 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
025 ;;;
|
||||
026 ;;;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
026 ;;; This file provides the reader required for boostrapping. It's not a bad
|
||||
027 ;;; This file provides the reader required for boostrapping. It's not a bad
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
027 ;;; reader - it provides feedback on errors found in the input - but it isn't
|
||||
028 ;;; reader - it provides feedback on errors found in the input - but it isn't
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
028 ;;; the real Lisp reader.
|
||||
029 ;;; the real Lisp reader.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
029 ;;;
|
||||
030 ;;;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
030 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
031 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
031 ;;;
|
||||
032 ;;;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
032 ;;; Copyright (C) 2022-2023 Simon Brooke
|
||||
033 ;;; Copyright (C) 2022-2023 Simon Brooke
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
033 ;;;
|
||||
034 ;;;
|
||||
</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
|
||||
035 ;;; 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
|
||||
036 ;;; 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
|
||||
037 ;;; 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.
|
||||
038 ;;; of the License, or (at your option) any later version.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
038 ;;;
|
||||
039 ;;;
|
||||
</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,
|
||||
040 ;;; 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
|
||||
041 ;;; 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
|
||||
042 ;;; 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.
|
||||
043 ;;; GNU General Public License for more details.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
043 ;;;
|
||||
044 ;;;
|
||||
</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
|
||||
045 ;;; 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
|
||||
046 ;;; 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.
|
||||
047 ;;; 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 ;;;
|
||||
048 ;;;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
048 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
049 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
049
|
||||
050
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
050 (defn strip-line-comments
|
||||
051 (defn strip-line-comments
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
051 "Strip blank lines and comment lines from this string `s`, expected to
|
||||
052 "Strip blank lines and comment lines from this string `s`, expected to
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
052 be Lisp source."
|
||||
053 be Lisp source."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
053 [^String s]
|
||||
054 [^String s]
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
054 (join "\n"
|
||||
055 (join "\n"
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
055 (remove
|
||||
056 (remove
|
||||
</span><br/>
|
||||
<span class="covered" title="9 out of 9 forms covered">
|
||||
056 #(or (empty? %)
|
||||
057 #(or (empty? %)
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
057 (starts-with? (trim %) ";;"))
|
||||
058 (starts-with? (trim %) ";;"))
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
058 (split s #"\n"))))
|
||||
059 (split s #"\n"))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
059
|
||||
060
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
060 (defn number-lines
|
||||
061 (defn number-lines
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
061 ([^String s]
|
||||
062 ([^String s]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
062 (number-lines s nil))
|
||||
063 (number-lines s nil))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
063 ([^String s ^Failure e]
|
||||
064 ([^String s ^Failure e]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
064 (let [l (-> e :line)
|
||||
065 (let [l (-> e :line)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
065 c (-> e :column)]
|
||||
066 c (-> e :column)]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
066 (join "\n"
|
||||
067 (join "\n"
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 11 forms covered">
|
||||
067 (map #(str (format "%5d %s" (inc %1) %2)
|
||||
068 (map #(str (format "%5d %s" (inc %1) %2)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
068 (when (= l (inc %1))
|
||||
069 (when (= l (inc %1))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 11 forms covered">
|
||||
069 (str "\n" (apply str (repeat c " ")) "^")))
|
||||
070 (str "\n" (apply str (repeat c " ")) "^")))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
070 (range)
|
||||
071 (range)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
071 (split s #"\n"))))))
|
||||
072 (split s #"\n"))))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
072
|
||||
073
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
073 (defn gsp
|
||||
074 (defn gsp
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
074 "Shortcut macro - the internals of read; or, if you like, read-string.
|
||||
075 "Shortcut macro - the internals of read; or, if you like, read-string.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
075 Argument `s` should be a string representation of a valid Lisp
|
||||
076 Argument `s` should be a string representation of a valid Lisp
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
076 expression."
|
||||
077 expression."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
077 [s]
|
||||
078 [s]
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
078 (let [source (strip-line-comments s)
|
||||
079 (let [source (strip-line-comments s)
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
079 parse-tree (parse source)]
|
||||
080 parse-tree (parse source)]
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
080 (if (instance? Failure parse-tree)
|
||||
081 (if (instance? Failure parse-tree)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 8 forms covered">
|
||||
081 (doall (println (number-lines source parse-tree))
|
||||
082 (doall (println (number-lines source parse-tree))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 9 forms covered">
|
||||
082 (throw (ex-info "Ne can forstande " (assoc parse-tree :source source))))
|
||||
083 (throw (ex-info "Ne can forstande " (assoc parse-tree :source source))))
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
083 (generate (simplify parse-tree)))))
|
||||
084 (generate (simplify parse-tree)))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
084
|
||||
085
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
085 (defn read-from-console
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
086 "Attempt to read a complete lisp expression from the console. NOTE that this
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
087 will only really work for S-Expressions, not M-Expressions."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
088 []
|
||||
086 (defn- dummy-read-chars [prompt]
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
089 (loop [r (read-line)]
|
||||
087 (loop [r "" p prompt]
|
||||
</span><br/>
|
||||
<span class="partial" title="11 out of 12 forms covered">
|
||||
090 (if (and (= (count (re-seq #"\(" r))
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
091 (count (re-seq #"\)" r)))
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
092 (= (count (re-seq #"\[" r))
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
093 (count (re-seq #"\]" r))))
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
094 r
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
095 (recur (str r "\n" (read-line))))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
096
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
097 (defn READ
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
098 "An implementation of a Lisp reader sufficient for bootstrapping; not necessarily
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
099 the final Lisp reader. `input` should be either a string representation of a LISP
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
100 expression, or else an input stream. A single form will be read."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
101 ([]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
102 (gsp (read-from-console)))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
103 ([input]
|
||||
</span><br/>
|
||||
<span class="partial" title="2 out of 4 forms covered">
|
||||
104 (cond
|
||||
</span><br/>
|
||||
<span class="partial" title="3 out of 5 forms covered">
|
||||
105 (empty? input) (READ)
|
||||
<span class="partial" title="12 out of 13 forms covered">
|
||||
088 (if (and (seq r)
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
106 (string? input) (gsp input)
|
||||
089 (= (count (re-seq #"\(" r))
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
090 (count (re-seq #"\)" r)))
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
091 (= (count (re-seq #"\[" r))
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
092 (count (re-seq #"\]" r))))
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
093 r
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
094 (do
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
095 (print (str p " "))
|
||||
</span><br/>
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
096 (flush)
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
097 (recur (str r "\n" (read-line)) "::")))))
|
||||
</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 read-from-console
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
100 "Attempt to read a complete lisp expression from the console.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
101
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
102 There's a major problem here that the read-chars reader messes up testing.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
103 We need to be able to disable it while testing!"
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
104 [prompt]
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
105 (if (:testing *options*)
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
106 (dummy-read-chars prompt)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
107 (read-chars prompt)))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
108
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
109 (defn READ
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
110 "An implementation of a Lisp reader sufficient for bootstrapping; not necessarily
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
111 the final Lisp reader. `input` should be either a string representation of a LISP
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
112 expression, or else an input stream. A single form will be read."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
113 ([]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 7 forms covered">
|
||||
114 (gsp (read-from-console (:prompt *options*))))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
115 ([input]
|
||||
</span><br/>
|
||||
<span class="partial" title="2 out of 4 forms covered">
|
||||
116 (cond
|
||||
</span><br/>
|
||||
<span class="partial" title="3 out of 5 forms covered">
|
||||
117 (empty? input) (READ)
|
||||
</span><br/>
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
118 (string? input) (gsp input)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 9 forms covered">
|
||||
107 (instance? InputStream input) (READ (slurp input))
|
||||
119 (instance? InputStream input) (READ (slurp input))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
108 :else (throw (ex-info "READ: `input` should be a string or an input stream" {})))))
|
||||
120 :else (throw (ex-info "READ: `input` should be a string or an input stream" {})))))
|
||||
</span><br/>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -71,163 +71,259 @@
|
|||
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 ;; (:import [org.jline.reader LineReader LineReaderBuilder]
|
||||
023 (:require [beowulf.oblist :refer [*options* oblist]])
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
024 ;; [org.jline.terminal TerminalBuilder])
|
||||
024 (:import [org.jline.reader.impl.completer StringsCompleter]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
025 )
|
||||
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">
|
||||
026
|
||||
029
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
027 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
030 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
028 ;;;
|
||||
031 ;;;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
029 ;;; Copyright (C) 2022-2023 Simon Brooke
|
||||
032 ;;; Copyright (C) 2022-2023 Simon Brooke
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
030 ;;;
|
||||
033 ;;;
|
||||
</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
|
||||
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">
|
||||
032 ;;; modify it under the terms of the GNU General Public License
|
||||
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">
|
||||
033 ;;; as published by the Free Software Foundation; either version 2
|
||||
036 ;;; 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.
|
||||
037 ;;; of the License, or (at your option) any later version.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
035 ;;;
|
||||
038 ;;;
|
||||
</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,
|
||||
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">
|
||||
037 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
040 ;;; 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
|
||||
041 ;;; 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.
|
||||
042 ;;; GNU General Public License for more details.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
040 ;;;
|
||||
043 ;;;
|
||||
</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
|
||||
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">
|
||||
042 ;;; along with this program; if not, write to the Free Software
|
||||
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">
|
||||
043 ;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
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">
|
||||
044 ;;;
|
||||
047 ;;;
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
045 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
048 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
046
|
||||
049
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
047 ;; It looks from the example given [here](https://github.com/jline/jline3/blob/master/demo/src/main/java/org/jline/demo/Repl.java)
|
||||
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">
|
||||
048 ;; as though JLine could be used to build a perfect line-reader for Beowulf; but it also
|
||||
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">
|
||||
049 ;; looks as though you'd need a DPhil in JLine to write it, and I don't have
|
||||
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">
|
||||
050 ;; the time.
|
||||
053 ;; the time.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
051
|
||||
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">
|
||||
052 ;; (def get-reader
|
||||
056 "Build a completer which takes tokens from the oblist.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
053 ;; "Return a reader, first constructing it if necessary.
|
||||
057
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
054
|
||||
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">
|
||||
055 ;; **NOTE THAT** this is not settled API. The existence and call signature of
|
||||
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">
|
||||
056 ;; this function is not guaranteed in future versions."
|
||||
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">
|
||||
057 ;; (memoize (fn []
|
||||
061 []
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
058 ;; (let [term (.build (.system (TerminalBuilder/builder) true))]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
059 ;; (.build (.terminal (LineReaderBuilder/builder) term))))))
|
||||
<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">
|
||||
060
|
||||
063
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
061 ;; (defn read-chars
|
||||
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">
|
||||
062 ;; "A drop-in replacement for `clojure.core/read-line`, except that line editing
|
||||
065 ;; why not.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
063 ;; and history should be enabled.
|
||||
066 ;; (defn build-parser
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
064
|
||||
067 ;; []
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
065 ;; **NOTE THAT** this does not work yet, but it is in the API because I hope
|
||||
068 ;; (println "Building parser")
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
066 ;; that it will work later!"
|
||||
069 ;; (let [parser (DefaultParser.)]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
067 ;; []
|
||||
070 ;; (doall
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
068 ;; (let [eddie (get-reader)]
|
||||
071 ;; (.setEofOnUnclosedBracket
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
069 ;; (loop [s (.readLine eddie)]
|
||||
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">
|
||||
070 ;; (if (and (= (count (re-seq #"\(" s))
|
||||
075 "Return a reader, first constructing it if necessary.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
071 ;; (count (re-seq #"\)" s)))
|
||||
076
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
072 ;; (= (count (re-seq #"\[]" s))
|
||||
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">
|
||||
073 ;; (count (re-seq #"\]" s))))
|
||||
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">
|
||||
074 ;; s
|
||||
084 ;; #(.parser % (build-parser))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
075 ;; (recur (str s " " (.readLine eddie)))))))
|
||||
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>
|
||||
|
|
|
@ -16,11 +16,11 @@
|
|||
</tr></thead>
|
||||
<tr>
|
||||
<td><a href="beowulf/bootstrap.clj.html">beowulf.bootstrap</a></td><td class="with-bar"><div class="covered"
|
||||
style="width:63.9344262295082%;
|
||||
float:left;"> 624 </div><div class="not-covered"
|
||||
style="width:36.0655737704918%;
|
||||
float:left;"> 352 </div></td>
|
||||
<td class="with-number">63.93 %</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:59.48275862068966%;
|
||||
float:left;"> 138 </div><div class="partial"
|
||||
|
@ -33,54 +33,54 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<td><a href="beowulf/cons_cell.clj.html">beowulf.cons-cell</a></td><td class="with-bar"><div class="covered"
|
||||
style="width:72.34927234927235%;
|
||||
float:left;"> 348 </div><div class="not-covered"
|
||||
style="width:27.65072765072765%;
|
||||
float:left;"> 133 </div></td>
|
||||
<td class="with-number">72.35 %</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:75.17241379310344%;
|
||||
float:left;"> 109 </div><div class="partial"
|
||||
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:18.620689655172413%;
|
||||
float:left;"> 27 </div></td>
|
||||
<td class="with-number">81.38 %</td>
|
||||
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:69.47368421052632%;
|
||||
float:left;"> 198 </div><div class="not-covered"
|
||||
style="width:30.526315789473685%;
|
||||
float:left;"> 87 </div></td>
|
||||
<td class="with-number">69.47 %</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:72.46376811594203%;
|
||||
float:left;"> 50 </div><div class="partial"
|
||||
style="width:5.797101449275362%;
|
||||
float:left;"> 4 </div><div class="not-covered"
|
||||
style="width:21.73913043478261%;
|
||||
float:left;"> 15 </div></td>
|
||||
<td class="with-number">78.26 %</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:42.77384423157018%;
|
||||
float:left;"> 1027 </div><div class="not-covered"
|
||||
style="width:57.22615576842982%;
|
||||
float:left;"> 1374 </div></td>
|
||||
<td class="with-number">42.77 %</td>
|
||||
style="width:46.61776691116545%;
|
||||
float:left;"> 1144 </div><div class="not-covered"
|
||||
style="width:53.38223308883455%;
|
||||
float:left;"> 1310 </div></td>
|
||||
<td class="with-number">46.62 %</td>
|
||||
<td class="with-bar"><div class="covered"
|
||||
style="width:53.72549019607843%;
|
||||
float:left;"> 137 </div><div class="partial"
|
||||
style="width:14.509803921568627%;
|
||||
style="width:61.97718631178707%;
|
||||
float:left;"> 163 </div><div class="partial"
|
||||
style="width:14.068441064638783%;
|
||||
float:left;"> 37 </div><div class="not-covered"
|
||||
style="width:31.764705882352942%;
|
||||
float:left;"> 81 </div></td>
|
||||
<td class="with-number">68.24 %</td>
|
||||
<td class="with-number">571</td><td class="with-number">66</td><td class="with-number">255</td>
|
||||
style="width:23.954372623574145%;
|
||||
float:left;"> 63 </div></td>
|
||||
<td class="with-number">76.05 %</td>
|
||||
<td class="with-number">588</td><td class="with-number">67</td><td class="with-number">263</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="beowulf/interop.clj.html">beowulf.interop</a></td><td class="with-bar"><div class="covered"
|
||||
|
@ -107,14 +107,14 @@
|
|||
float:left;"> 181 </div></td>
|
||||
<td class="with-number">43.96 %</td>
|
||||
<td class="with-bar"><div class="covered"
|
||||
style="width:46.478873239436616%;
|
||||
style="width:45.833333333333336%;
|
||||
float:left;"> 33 </div><div class="partial"
|
||||
style="width:8.450704225352112%;
|
||||
style="width:8.333333333333334%;
|
||||
float:left;"> 6 </div><div class="not-covered"
|
||||
style="width:45.070422535211264%;
|
||||
float:left;"> 32 </div></td>
|
||||
<td class="with-number">54.93 %</td>
|
||||
<td class="with-number">171</td><td class="with-number">12</td><td class="with-number">71</td>
|
||||
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"
|
||||
|
@ -134,7 +134,7 @@
|
|||
<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;"> 9 </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%;
|
||||
|
@ -144,31 +144,35 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<td><a href="beowulf/read.clj.html">beowulf.read</a></td><td class="with-bar"><div class="covered"
|
||||
style="width:49.43181818181818%;
|
||||
float:left;"> 87 </div><div class="not-covered"
|
||||
style="width:50.56818181818182%;
|
||||
float:left;"> 89 </div></td>
|
||||
<td class="with-number">49.43 %</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:53.84615384615385%;
|
||||
float:left;"> 21 </div><div class="partial"
|
||||
style="width:7.6923076923076925%;
|
||||
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:38.46153846153846%;
|
||||
style="width:31.914893617021278%;
|
||||
float:left;"> 15 </div></td>
|
||||
<td class="with-number">61.54 %</td>
|
||||
<td class="with-number">108</td><td class="with-number">9</td><td class="with-number">39</td>
|
||||
<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:100.0%;
|
||||
float:left;"> 1 </div></td>
|
||||
<td class="with-number">100.00 %</td>
|
||||
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:100.0%;
|
||||
float:left;"> 1 </div></td>
|
||||
<td class="with-number">100.00 %</td>
|
||||
<td class="with-number">75</td><td class="with-number">4</td><td class="with-number">1</td>
|
||||
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"
|
||||
|
@ -232,9 +236,9 @@
|
|||
</tr>
|
||||
<tr><td>Totals:</td>
|
||||
<td class="with-bar"></td>
|
||||
<td class="with-number">64.63 %</td>
|
||||
<td class="with-number">65.64 %</td>
|
||||
<td class="with-bar"></td>
|
||||
<td class="with-number">74.41 %</td>
|
||||
<td class="with-number">75.70 %</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
|
|
|
@ -170,6 +170,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
|
||||
|
|
|
@ -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."
|
||||
|
|
|
@ -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)))
|
||||
|
@ -433,6 +432,21 @@
|
|||
"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 PUT
|
||||
"Put this `value` as the value of the property indicated by this `indicator`
|
||||
of this `symbol`. Return `value` on success.
|
||||
|
@ -440,22 +454,25 @@
|
|||
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)
|
||||
(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:
|
||||
|
|
|
@ -41,5 +41,5 @@
|
|||
|
||||
(def ^:dynamic *options*
|
||||
"Command line options from invocation."
|
||||
{})
|
||||
{:testing true})
|
||||
|
||||
|
|
|
@ -83,16 +83,28 @@
|
|||
(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."
|
||||
[prompt]
|
||||
(loop [r (read-chars prompt)]
|
||||
(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-chars ""))))))
|
||||
(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
|
||||
|
|
|
@ -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,9 +1,21 @@
|
|||
(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]]
|
||||
(:require [beowulf.cons-cell :refer [F make-beowulf-list T]]
|
||||
[beowulf.host :refer [CDR DIFFERENCE GENSYM GET NUMBERP PLUS PUT
|
||||
RPLACA RPLACD TIMES]]
|
||||
[beowulf.io :refer [SYSIN]]
|
||||
[beowulf.oblist :refer [NIL]]
|
||||
[beowulf.read :refer [gsp]]))
|
||||
[beowulf.read :refer [gsp]]
|
||||
[clojure.test :refer [deftest is testing use-fixtures]]))
|
||||
|
||||
(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"
|
||||
|
@ -64,7 +76,8 @@
|
|||
(let [expected 6
|
||||
actual (TIMES 2 3)]
|
||||
(is (= actual expected))))
|
||||
(testing DIFFERENCE
|
||||
(testing "DIFFERENCE"
|
||||
(let [expected -1
|
||||
actual (DIFFERENCE 1 2)]
|
||||
(is (= actual expected)))))
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
(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
|
||||
"'Read eval print string', or 'read eval print single'.
|
||||
|
@ -165,4 +165,42 @@
|
|||
(SETQ X (ADD1 X))
|
||||
(COND ((EQ X 5) (RETURN X))
|
||||
(T (GO START))))")]
|
||||
(is (= actual expected)))))
|
||||
(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.")))))
|
Loading…
Reference in a new issue