Lots of new unit tests.
This commit is contained in:
parent
01e4572119
commit
7c4d3668a8
|
@ -130,19 +130,19 @@
|
|||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
042 [symbol]
|
||||
</span><br/>
|
||||
<span class="partial" title="4 out of 5 forms covered">
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
043 (when (:strict *options*)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 7 forms covered">
|
||||
<span class="covered" title="7 out of 7 forms covered">
|
||||
044 (throw (ex-info (format "%s ne āfand innan Lisp 1.5" symbol)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
045 {:type :strict
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
046 :phase :host
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
047 :function symbol})))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
|
@ -283,19 +283,19 @@
|
|||
<span class="covered" title="4 out of 4 forms covered">
|
||||
093 (empty? path) l
|
||||
</span><br/>
|
||||
<span class="partial" title="6 out of 13 forms covered">
|
||||
<span class="covered" title="13 out of 13 forms covered">
|
||||
094 (not (instance? ConsCell l)) (throw (ex-info (str "Ne liste: "
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
095 l "; " (type l))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 8 forms covered">
|
||||
<span class="covered" title="8 out of 8 forms covered">
|
||||
096 {:phase :eval
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
097 :function "universal access function"
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
098 :args [l path]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
|
@ -310,19 +310,19 @@
|
|||
<span class="covered" title="6 out of 6 forms covered">
|
||||
102 \d (uaf (.getCdr l) (butlast path))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
103 (throw (ex-info (str "uaf: unexpected letter in path (only `a` and `d` permitted): "
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
104 (last path))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 8 forms covered">
|
||||
<span class="covered" title="8 out of 8 forms covered">
|
||||
105 {:phase :eval
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
106 :function "universal access function"
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
107 :args [l path]
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
|
@ -568,7 +568,7 @@
|
|||
<span class="covered" title="1 out of 1 forms covered">
|
||||
188 (if
|
||||
</span><br/>
|
||||
<span class="partial" title="11 out of 13 forms covered">
|
||||
<span class="partial" title="12 out of 13 forms covered">
|
||||
189 (or
|
||||
</span><br/>
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
|
@ -580,7 +580,7 @@
|
|||
<span class="covered" title="3 out of 3 forms covered">
|
||||
192 (symbol? value)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
193 (= value NIL))
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
|
@ -619,13 +619,13 @@
|
|||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
205 any))))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
206 (throw (ex-info
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 9 forms covered">
|
||||
<span class="covered" title="9 out of 9 forms covered">
|
||||
207 (str "Un-ġefōg þing in RPLACD: `" value "` (" (type value) ")")
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 10 forms covered">
|
||||
<span class="covered" title="10 out of 10 forms covered">
|
||||
208 {:cause :bad-value
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
|
@ -634,19 +634,19 @@
|
|||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
210 :function :rplacd
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
211 :args (list cell value)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
212 :type :beowulf})))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
213 (throw (ex-info
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 9 forms covered">
|
||||
<span class="covered" title="9 out of 9 forms covered">
|
||||
214 (str "Uncynlic miercels in RPLACD: `" cell "` (" (type cell) ")")
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 10 forms covered">
|
||||
<span class="covered" title="10 out of 10 forms covered">
|
||||
215 {:cause :bad-cell
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
|
@ -655,7 +655,7 @@
|
|||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
217 :detail :rplacd
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
<span class="covered" title="4 out of 4 forms covered">
|
||||
218 :args (list cell value)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
|
@ -682,7 +682,7 @@
|
|||
<span class="blank" title="0 out of 0 forms covered">
|
||||
226
|
||||
</span><br/>
|
||||
<span class="partial" title="5 out of 36 forms covered">
|
||||
<span class="covered" title="36 out of 36 forms covered">
|
||||
227 (defmacro NULL
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
|
@ -691,13 +691,13 @@
|
|||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
229 [x]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
230 `(if (= ~x NIL) T F))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
231
|
||||
</span><br/>
|
||||
<span class="partial" title="5 out of 36 forms covered">
|
||||
<span class="covered" title="36 out of 36 forms covered">
|
||||
232 (defmacro NILP
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
|
@ -706,7 +706,7 @@
|
|||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
234 [x]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
235 `(if (= ~x NIL) T NIL))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
|
@ -847,13 +847,13 @@
|
|||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
281 ;; (println " filtered: " (seq (filter #{F NIL} args)))
|
||||
</span><br/>
|
||||
<span class="partial" title="5 out of 7 forms covered">
|
||||
<span class="partial" title="6 out of 7 forms covered">
|
||||
282 (cond (= NIL args) T
|
||||
</span><br/>
|
||||
<span class="covered" title="14 out of 14 forms covered">
|
||||
283 (seq? args) (if (seq (filter #{F NIL} args)) F T)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
284 :else T))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
|
@ -889,13 +889,13 @@
|
|||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
295 ;; (println " filtered: " (seq (remove #{F NIL} args)))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 7 forms covered">
|
||||
<span class="partial" title="6 out of 7 forms covered">
|
||||
296 (cond (= NIL args) F
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 14 forms covered">
|
||||
<span class="covered" title="14 out of 14 forms covered">
|
||||
297 (seq? args) (if (seq (remove #{F NIL} args)) T F)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
298 :else F))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
|
@ -1078,7 +1078,7 @@
|
|||
<span class="covered" title="5 out of 5 forms covered">
|
||||
358 (let [p (apply * args)]
|
||||
</span><br/>
|
||||
<span class="partial" title="5 out of 7 forms covered">
|
||||
<span class="covered" title="7 out of 7 forms covered">
|
||||
359 (if (integer? p) p (float p))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
|
@ -1093,7 +1093,7 @@
|
|||
<span class="covered" title="4 out of 4 forms covered">
|
||||
363 (let [d (- x y)]
|
||||
</span><br/>
|
||||
<span class="partial" title="5 out of 7 forms covered">
|
||||
<span class="covered" title="7 out of 7 forms covered">
|
||||
364 (if (integer? d) d (float d))))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
|
@ -1153,7 +1153,7 @@
|
|||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
383 [x]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
<span class="covered" title="2 out of 2 forms covered">
|
||||
384 (dec x))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
|
@ -1165,7 +1165,7 @@
|
|||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
387 [x]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
388 (if (integer? x) T F))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
|
@ -1189,7 +1189,7 @@
|
|||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
395 [x y]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
396 (if (< x y) T F))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
|
@ -1201,7 +1201,7 @@
|
|||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
399 [x y]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 6 forms covered">
|
||||
<span class="covered" title="6 out of 6 forms covered">
|
||||
400 (if (> x y) T F))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
|
@ -1237,7 +1237,7 @@
|
|||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
411 [& args]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 14 forms covered">
|
||||
<span class="covered" title="14 out of 14 forms covered">
|
||||
412 (throw (ex-info "LISP STÆFLEAHTER" {:args args
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
|
@ -1249,7 +1249,7 @@
|
|||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
415 :type :lisp
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 8 forms covered">
|
||||
<span class="covered" title="8 out of 8 forms covered">
|
||||
416 :code (or (first args) 'A1)})))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
|
@ -1334,7 +1334,7 @@
|
|||
443 [target plist]
|
||||
</span><br/>
|
||||
<span class="covered" title="13 out of 13 forms covered">
|
||||
444 (if (and (instance? ConsCell plist)(even? (count plist)))
|
||||
444 (if (and (instance? ConsCell plist) (even? (count plist)))
|
||||
</span><br/>
|
||||
<span class="partial" title="6 out of 7 forms covered">
|
||||
445 (cond (= plist NIL) NIL
|
||||
|
@ -1558,215 +1558,218 @@
|
|||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
518 [a-list indicator]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
519 (map
|
||||
<span class="not-covered" title="0 out of 2 forms covered">
|
||||
519 (doall
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 9 forms covered">
|
||||
520 #(PUT (CAR %) indicator (CDR %))
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
520 (map
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 14 forms covered">
|
||||
521 #(when (PUT (CAR %) indicator (CDR %)) (CAR %))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
521 a-list))
|
||||
522 a-list)))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
522
|
||||
523
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
523 (defn DEFINE
|
||||
524 (defn DEFINE
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
524 "Bootstrap-only version of `DEFINE` which, post boostrap, can be overwritten
|
||||
525 "Bootstrap-only version of `DEFINE` which, post boostrap, can be overwritten
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
525 in LISP.
|
||||
526 in LISP.
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
526
|
||||
527
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
527 The single argument to `DEFINE` should be an association list of symbols to
|
||||
528 The single argument to `DEFINE` should be an association list of symbols to
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
528 lambda functions. See page 58 of the manual."
|
||||
529 lambda functions. See page 58 of the manual."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
529 [a-list]
|
||||
530 [a-list]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
530 (DEFLIST a-list 'EXPR))
|
||||
531 (DEFLIST a-list 'EXPR))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
531
|
||||
532
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
532 (defn SET
|
||||
533 (defn SET
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
533 "Implementation of SET in Clojure. Add to the `oblist` a binding of the
|
||||
534 "Implementation of SET in Clojure. Add to the `oblist` a binding of the
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
534 value of `var` to the value of `val`. NOTE WELL: this is not SETQ!"
|
||||
535 value of `var` to the value of `val`. NOTE WELL: this is not SETQ!"
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
535 [symbol val]
|
||||
536 [symbol val]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
536 (PUT symbol 'APVAL val))
|
||||
537 (PUT symbol 'APVAL val))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
537
|
||||
538
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
538 ;;;; TRACE and friends ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
539 ;;;; TRACE and friends ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
539
|
||||
540
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
540 (def traced-symbols
|
||||
541 (def traced-symbols
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
541 "Symbols currently being traced."
|
||||
542 "Symbols currently being traced."
|
||||
</span><br/>
|
||||
<span class="covered" title="3 out of 3 forms covered">
|
||||
542 (atom #{}))
|
||||
543 (atom #{}))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
543
|
||||
544
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
544 (defn traced?
|
||||
545 (defn traced?
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
545 "Return `true` iff `s` is a symbol currently being traced, else `nil`."
|
||||
546 "Return `true` iff `s` is a symbol currently being traced, else `nil`."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
546 [s]
|
||||
547 [s]
|
||||
</span><br/>
|
||||
<span class="partial" title="7 out of 8 forms covered">
|
||||
547 (try (contains? @traced-symbols s)
|
||||
548 (try (contains? @traced-symbols s)
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
548 (catch Throwable _ nil)))
|
||||
549 (catch Throwable _ nil)))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
549
|
||||
550
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
550 (defn TRACE
|
||||
551 (defn TRACE
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
551 "Add this `s` to the set of symbols currently being traced. If `s`
|
||||
552 "Add this `s` to the set of symbols currently being traced. If `s`
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
552 is not a symbol or sequence of symbols, does nothing."
|
||||
553 is not a symbol or sequence of symbols, does nothing."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
553 [s]
|
||||
554 [s]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
554 (swap! traced-symbols
|
||||
555 (swap! traced-symbols
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 4 forms covered">
|
||||
555 #(cond
|
||||
556 #(cond
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 7 forms covered">
|
||||
556 (symbol? s) (conj % s)
|
||||
557 (symbol? s) (conj % s)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 17 forms covered">
|
||||
557 (and (seq? s) (every? symbol? s)) (union % (set s))
|
||||
558 (and (seq? s) (every? symbol? s)) (union % (set s))
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
558 :else %)))
|
||||
559 :else %)))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
559
|
||||
560
|
||||
</span><br/>
|
||||
<span class="partial" title="1 out of 3 forms covered">
|
||||
560 (defn UNTRACE
|
||||
561 (defn UNTRACE
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
561 "Remove this `s` from the set of symbols currently being traced. If `s`
|
||||
562 "Remove this `s` from the set of symbols currently being traced. If `s`
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
562 is not a symbol or sequence of symbols, does nothing."
|
||||
563 is not a symbol or sequence of symbols, does nothing."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
563 [s]
|
||||
564 [s]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
564 (cond
|
||||
565 (cond
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 16 forms covered">
|
||||
565 (symbol? s) (swap! traced-symbols #(set (remove (fn [x] (= s x)) %)))
|
||||
566 (symbol? s) (swap! traced-symbols #(set (remove (fn [x] (= s x)) %)))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 15 forms covered">
|
||||
566 (and (seq? s) (every? symbol? s)) (map UNTRACE s))
|
||||
567 (and (seq? s) (every? symbol? s)) (map UNTRACE s))
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 1 forms covered">
|
||||
567 @traced-symbols)
|
||||
568 @traced-symbols)
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
568
|
||||
569
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
569 ;;;; Extensions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
570 ;;;; Extensions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
570
|
||||
571
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
571 (defn DOC
|
||||
572 (defn DOC
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
572 "Open the page for this `symbol` in the Lisp 1.5 manual, if known, in the
|
||||
573 "Open the page for this `symbol` in the Lisp 1.5 manual, if known, in the
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
573 default web browser.
|
||||
574 default web browser.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
574
|
||||
575
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
575 **NOTE THAT** this is an extension function, not available in strct mode."
|
||||
576 **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">
|
||||
576 [symbol]
|
||||
577 [symbol]
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 5 forms covered">
|
||||
577 (when (lax? 'DOC)
|
||||
578 (when (lax? 'DOC)
|
||||
</span><br/>
|
||||
<span class="not-covered" title="0 out of 3 forms covered">
|
||||
578 (open-doc symbol)))
|
||||
579 (open-doc symbol)))
|
||||
</span><br/>
|
||||
<span class="blank" title="0 out of 0 forms covered">
|
||||
579
|
||||
580
|
||||
</span><br/>
|
||||
<span class="covered" title="1 out of 1 forms covered">
|
||||
580 (defn CONSP
|
||||
581 (defn CONSP
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
581 "Return `T` if object `o` is a cons cell, else `F`.
|
||||
582 "Return `T` if object `o` is a cons cell, else `F`.
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
582
|
||||
583
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
583 **NOTE THAT** this is an extension function, not available in strct mode.
|
||||
584 **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">
|
||||
584 I believe that Lisp 1.5 did not have any mechanism for testing whether an
|
||||
585 I believe that Lisp 1.5 did not have any mechanism for testing whether an
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
585 argument was, or was not, a cons cell."
|
||||
586 argument was, or was not, a cons cell."
|
||||
</span><br/>
|
||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||
586 [o]
|
||||
587 [o]
|
||||
</span><br/>
|
||||
<span class="covered" title="5 out of 5 forms covered">
|
||||
587 (when (lax? 'CONSP)
|
||||
588 (when (lax? 'CONSP)
|
||||
</span><br/>
|
||||
<span class="covered" title="7 out of 7 forms covered">
|
||||
588 (if (instance? ConsCell o) 'T 'F)))
|
||||
589 (if (instance? ConsCell o) 'T 'F)))
|
||||
</span><br/>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -67,20 +67,20 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<td><a href="beowulf/host.clj.html">beowulf.host</a></td><td class="with-bar"><div class="covered"
|
||||
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>
|
||||
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:61.97718631178707%;
|
||||
float:left;"> 163 </div><div class="partial"
|
||||
style="width:14.068441064638783%;
|
||||
float:left;"> 37 </div><div class="not-covered"
|
||||
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>
|
||||
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"
|
||||
|
@ -236,9 +236,9 @@
|
|||
</tr>
|
||||
<tr><td>Totals:</td>
|
||||
<td class="with-bar"></td>
|
||||
<td class="with-number">65.64 %</td>
|
||||
<td class="with-number">68.60 %</td>
|
||||
<td class="with-bar"></td>
|
||||
<td class="with-number">75.70 %</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
|
@ -6,4 +6,11 @@
|
|||
<li>It reads the meta-expression language <code>MEXPR</code> in addition to the symbolic expression language <code>SEXPR</code>, which I do not believe the Lisp 1.5 reader ever did;</li>
|
||||
<li>It treats everything between a double semi-colon and an end of line as a comment, as most modern Lisps do; but I do not believe Lisp 1.5 had this feature.</li>
|
||||
</ol>
|
||||
<p>Both these extensions can be disabled by using the <code>--strict</code> command line switch.</p></div></div><div class="public anchor" id="var-gsp"><h3>gsp</h3><div class="usage"><code>(gsp s)</code></div><div class="doc"><div class="markdown"><p>Shortcut macro - the internals of read; or, if you like, read-string. Argument <code>s</code> should be a string representation of a valid Lisp expression.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/beowulf/blob/master/src/beowulf/read.clj#L73">view source</a></div></div><div class="public anchor" id="var-number-lines"><h3>number-lines</h3><div class="usage"><code>(number-lines s)</code><code>(number-lines s e)</code></div><div class="doc"><div class="markdown"><p><strong>TODO</strong>: write docs</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/beowulf/blob/master/src/beowulf/read.clj#L60">view source</a></div></div><div class="public anchor" id="var-READ"><h3>READ</h3><div class="usage"><code>(READ)</code><code>(READ input)</code></div><div class="doc"><div class="markdown"><p>An implementation of a Lisp reader sufficient for bootstrapping; not necessarily the final Lisp reader. <code>input</code> should be either a string representation of a LISP expression, or else an input stream. A single form will be read.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/beowulf/blob/master/src/beowulf/read.clj#L97">view source</a></div></div><div class="public anchor" id="var-read-from-console"><h3>read-from-console</h3><div class="usage"><code>(read-from-console)</code></div><div class="doc"><div class="markdown"><p>Attempt to read a complete lisp expression from the console. NOTE that this will only really work for S-Expressions, not M-Expressions.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/beowulf/blob/master/src/beowulf/read.clj#L85">view source</a></div></div><div class="public anchor" id="var-strip-line-comments"><h3>strip-line-comments</h3><div class="usage"><code>(strip-line-comments s)</code></div><div class="doc"><div class="markdown"><p>Strip blank lines and comment lines from this string <code>s</code>, expected to be Lisp source.</p></div></div><div class="src-link"><a href="https://github.com/simon-brooke/beowulf/blob/master/src/beowulf/read.clj#L50">view source</a></div></div></div></body></html>
|
||||
<p>Both these extensions can be disabled by using the <code>--strict</code> command line switch.</p>
|
||||
</div></div><div class="public anchor" id="var-gsp"><h3>gsp</h3><div class="usage"><code>(gsp s)</code></div><div class="doc"><div class="markdown"><p>Shortcut macro - the internals of read; or, if you like, read-string. Argument <code>s</code> should be a string representation of a valid Lisp expression.</p>
|
||||
</div></div><div class="src-link"><a href="https://github.com/simon-brooke/beowulf/blob/master/src/beowulf/read.clj#L74">view source</a></div></div><div class="public anchor" id="var-number-lines"><h3>number-lines</h3><div class="usage"><code>(number-lines s)</code><code>(number-lines s e)</code></div><div class="doc"><div class="markdown"><p><strong>TODO</strong>: write docs</p>
|
||||
</div></div><div class="src-link"><a href="https://github.com/simon-brooke/beowulf/blob/master/src/beowulf/read.clj#L61">view source</a></div></div><div class="public anchor" id="var-READ"><h3>READ</h3><div class="usage"><code>(READ)</code><code>(READ input)</code></div><div class="doc"><div class="markdown"><p>An implementation of a Lisp reader sufficient for bootstrapping; not necessarily the final Lisp reader. <code>input</code> should be either a string representation of a LISP expression, or else an input stream. A single form will be read.</p>
|
||||
</div></div><div class="src-link"><a href="https://github.com/simon-brooke/beowulf/blob/master/src/beowulf/read.clj#L109">view source</a></div></div><div class="public anchor" id="var-read-from-console"><h3>read-from-console</h3><div class="usage"><code>(read-from-console prompt)</code></div><div class="doc"><div class="markdown"><p>Attempt to read a complete lisp expression from the console.</p>
|
||||
<p>There’s a major problem here that the read-chars reader messes up testing. We need to be able to disable it while testing!</p>
|
||||
</div></div><div class="src-link"><a href="https://github.com/simon-brooke/beowulf/blob/master/src/beowulf/read.clj#L99">view source</a></div></div><div class="public anchor" id="var-strip-line-comments"><h3>strip-line-comments</h3><div class="usage"><code>(strip-line-comments s)</code></div><div class="doc"><div class="markdown"><p>Strip blank lines and comment lines from this string <code>s</code>, expected to be Lisp source.</p>
|
||||
</div></div><div class="src-link"><a href="https://github.com/simon-brooke/beowulf/blob/master/src/beowulf/read.clj#L51">view source</a></div></div></div></body></html>
|
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,6 +1,6 @@
|
|||
<!DOCTYPE html PUBLIC ""
|
||||
"">
|
||||
<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><li class="depth-2"><a href="beowulf.scratch.html"><div class="inner"><span class="tree" style="top: -176px;"><span class="top" style="height: 185px;"></span><span class="bottom"></span></span><span>scratch</span></div></a></li></ul></div><div class="document" id="content"><div class="doc"><div class="markdown"><h1><a href="#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><li class="depth-2"><a href="beowulf.scratch.html"><div class="inner"><span class="tree" style="top: -176px;"><span class="top" style="height: 185px;"></span><span class="bottom"></span></span><span>scratch</span></div></a></li></ul></div><div class="document" id="content"><div class="doc"><div class="markdown"><h1><a href="#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>
|
||||
|
@ -8,10 +8,12 @@
|
|||
<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>
|
||||
<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>
|
||||
</blockquote>
|
||||
</li>
|
||||
</ol>
|
||||
</div></div></div></body></html>
|
File diff suppressed because one or more lines are too long
|
@ -1,10 +1,10 @@
|
|||
<!DOCTYPE html PUBLIC ""
|
||||
"">
|
||||
<html><head><meta charset="UTF-8" /><title>beowulf</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><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 "><a href="further_reading.html"><div class="inner"><span>Further Reading</span></div></a></li><li class="depth-1 current"><a href="intro.html"><div class="inner"><span>beowulf</span></div></a></li><li class="depth-1 "><a href="mexpr.html"><div class="inner"><span>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><li class="depth-2"><a href="beowulf.scratch.html"><div class="inner"><span class="tree" style="top: -176px;"><span class="top" style="height: 185px;"></span><span class="bottom"></span></span><span>scratch</span></div></a></li></ul></div><div class="document" id="content"><div class="doc"><div class="markdown"><h1><a href="#beowulf" name="beowulf"></a>beowulf</h1>
|
||||
<h2><a href="#þý-liste-cræfte-spræc" name="þý-liste-cræfte-spræc"></a>Þý liste cræfte spræc</h2>
|
||||
<html><head><meta charset="UTF-8" /><title>beowulf</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><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 "><a href="further_reading.html"><div class="inner"><span>Further Reading</span></div></a></li><li class="depth-1 current"><a href="intro.html"><div class="inner"><span>beowulf</span></div></a></li><li class="depth-1 "><a href="mexpr.html"><div class="inner"><span>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><li class="depth-2"><a href="beowulf.scratch.html"><div class="inner"><span class="tree" style="top: -176px;"><span class="top" style="height: 185px;"></span><span class="bottom"></span></span><span>scratch</span></div></a></li></ul></div><div class="document" id="content"><div class="doc"><div class="markdown"><h1><a href="#beowulf" id="beowulf"></a>beowulf</h1>
|
||||
<h2><a href="#þý-liste-cræfte-spræc" id="þý-liste-cræfte-spræc"></a>Þý liste cræfte spræc</h2>
|
||||
<p>LISP 1.5 is to all Lisp dialects as Beowulf is to English literature.</p>
|
||||
<p><img src="https://simon-brooke.github.io/beowulf/docs/img/beowulf_logo_med.png" alt="Beowulf logo" /></p>
|
||||
<h2><a href="#contents" name="contents"></a>Contents</h2>
|
||||
<h2><a href="#contents" id="contents"></a>Contents</h2>
|
||||
<ul>
|
||||
<li><a href="#what-this-is">What this is</a>
|
||||
<ul>
|
||||
|
@ -39,26 +39,26 @@
|
|||
</li>
|
||||
<li><a href="#license">License</a></li>
|
||||
</ul>
|
||||
<small><i><a href="http://ecotrust-canada.github.io/markdown-toc/">Table of contents generated with markdown-toc</a></i></small>
|
||||
<h2><a href="#what-this-is" name="what-this-is"></a>What this is</h2>
|
||||
<p><small><i><a href="http://ecotrust-canada.github.io/markdown-toc/">Table of contents generated with markdown-toc</a></i></small></p>
|
||||
<h2><a href="#what-this-is" id="what-this-is"></a>What this is</h2>
|
||||
<p>A work-in-progress towards an implementation of Lisp 1.5 in Clojure. The objective is to build a complete and accurate implementation of Lisp 1.5 as described in the manual, with, in so far as is possible, exactly the same bahaviour - except as documented below.</p>
|
||||
<h3><a href="#but-why-" name="but-why-"></a>BUT WHY?!!?!</h3>
|
||||
<h3><a href="#but-why" id="but-why"></a>BUT WHY?!!?!</h3>
|
||||
<p>Because.</p>
|
||||
<p>Because Lisp is the only computer language worth learning, and if a thing is worth learning, it’s worth learning properly; which means going back to the beginning and trying to understand that.</p>
|
||||
<p>Because there is, so far as I know, no working implementation of Lisp 1.5 for modern machines.</p>
|
||||
<p>Because I’m barking mad, and this is therapy.</p>
|
||||
<h3><a href="#status" name="status"></a>Status</h3>
|
||||
<h3><a href="#status" id="status"></a>Status</h3>
|
||||
<p>Working Lisp interpreter, but some key features not yet implemented.</p>
|
||||
<ul>
|
||||
<li><a href="https://simon-brooke.github.io/beowulf/">Project website</a>.</li>
|
||||
<li><a href="https://simon-brooke.github.io/beowulf/docs/codox/index.html">Source code documentation</a>.</li>
|
||||
</ul>
|
||||
<h3><a href="#project-target" name="project-target"></a>Project Target</h3>
|
||||
<h3><a href="#project-target" id="project-target"></a>Project Target</h3>
|
||||
<p>The project target is to be able to run the <a href="https://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf#page=52">Wang algorithm for the propositional calculus</a> given in chapter 8 of the <em>Lisp 1.5 Programmer’s Manual</em>. When that runs, the project is as far as I am concerned feature complete. I may keep tinkering with it after that and I’ll certainly accept pull requests which are in the spirit of the project (i.e. making Beowulf more usable, and/or implementing parts of Lisp 1.5 which I have not implemented), but this isn’t intended to be a new language for doing real work; it’s an educational and archaeological project, not serious engineering.</p>
|
||||
<p>Some <code>readline</code>-like functionality would be really useful, but my attempt to integrate <a href="https://github.com/jline/jline3">JLine</a> has not (yet) been successful.</p>
|
||||
<p>An in-core structure editor would be an extremely nice thing, and I may well implement one.</p>
|
||||
<p>You are of course welcome to fork the project and do whatever you like with it!</p>
|
||||
<h3><a href="#invoking" name="invoking"></a>Invoking</h3>
|
||||
<h3><a href="#invoking" id="invoking"></a>Invoking</h3>
|
||||
<p>Invoke with</p>
|
||||
<pre><code>java -jar target/uberjar/beowulf-0.3.0-standalone.jar --help
|
||||
</code></pre>
|
||||
|
@ -72,717 +72,123 @@
|
|||
without extensions.
|
||||
</code></pre>
|
||||
<p>To end a session, type <code>STOP</code> at the command prompt.</p>
|
||||
<h3><a href="#building-and-invoking" name="building-and-invoking"></a>Building and Invoking</h3>
|
||||
<h3><a href="#building-and-invoking" id="building-and-invoking"></a>Building and Invoking</h3>
|
||||
<p>Build with</p>
|
||||
<pre><code>lein uberjar
|
||||
</code></pre>
|
||||
<h3><a href="#reader-macros" name="reader-macros"></a>Reader macros</h3>
|
||||
<h3><a href="#reader-macros" id="reader-macros"></a>Reader macros</h3>
|
||||
<p>Currently <code>SETQ</code> and <code>DEFUN</code> are implemented as reader macros, sort of. It would now be possible to reimplement them as <code>FEXPRs</code> and so the reader macro functionality will probably go away.</p>
|
||||
<h3><a href="#functions-and-symbols-implemented" name="functions-and-symbols-implemented"></a>Functions and symbols implemented</h3>
|
||||
<h3><a href="#functions-and-symbols-implemented" id="functions-and-symbols-implemented"></a>Functions and symbols implemented</h3>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Function </th>
|
||||
<th>Type </th>
|
||||
<th>Signature </th>
|
||||
<th>Implementation </th>
|
||||
<th>Documentation </th>
|
||||
</tr>
|
||||
<tr><th> Function </th><th> Type </th><th> Signature </th><th> Implementation </th><th> Documentation </th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>NIL </td>
|
||||
<td>Lisp variable </td>
|
||||
<td>? </td>
|
||||
<td> </td>
|
||||
<td>see manual pages <a href="#page22">22</a>, <a href="#page69">69</a> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>T </td>
|
||||
<td>Lisp variable </td>
|
||||
<td>? </td>
|
||||
<td> </td>
|
||||
<td>see manual pages <a href="#page22">22</a>, <a href="#page69">69</a> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>F </td>
|
||||
<td>Lisp variable </td>
|
||||
<td>? </td>
|
||||
<td> </td>
|
||||
<td>see manual pages <a href="#page22">22</a>, <a href="#page69">69</a> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>ADD1 </td>
|
||||
<td>Host lambda function </td>
|
||||
<td>? </td>
|
||||
<td> </td>
|
||||
<td>? </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>AND </td>
|
||||
<td>Host lambda function </td>
|
||||
<td>? </td>
|
||||
<td>PREDICATE </td>
|
||||
<td><code>T</code> if and only if none of my <code>args</code> evaluate to either <code>F</code> or <code>NIL</code>, else <code>F</code>. In <code>beowulf.host</code> principally because I don’t yet feel confident to define varargs functions in Lisp. </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>APPEND </td>
|
||||
<td>Lisp lambda function </td>
|
||||
<td>? </td>
|
||||
<td> </td>
|
||||
<td>see manual pages <a href="#page11">11</a>, <a href="#page61">61</a> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>APPLY </td>
|
||||
<td>Host lambda function </td>
|
||||
<td>? </td>
|
||||
<td> </td>
|
||||
<td>Apply this <code>function</code> to these <code>arguments</code> in this <code>environment</code> and return the result. For bootstrapping, at least, a version of APPLY written in Clojure. All args are assumed to be symbols or <code>beowulf.cons-cell/ConsCell</code> objects. See page 13 of the Lisp 1.5 Programmers Manual. </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>ASSOC </td>
|
||||
<td>Lisp lambda function, Host lambda function </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
<td>If a is an association list such as the one formed by PAIRLIS in the above example, then assoc will produce the first pair whose first term is x. Thus it is a table searching function. All args are assumed to be <code>beowulf.cons-cell/ConsCell</code> objects. See page 12 of the Lisp 1.5 Programmers Manual. <strong>NOTE THAT</strong> this function is overridden by an implementation in Lisp, but is currently still present for bootstrapping. </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>ATOM </td>
|
||||
<td>Host lambda function </td>
|
||||
<td>? </td>
|
||||
<td>PREDICATE </td>
|
||||
<td>Returns <code>T</code> if and only if the argument <code>x</code> is bound to an atom; else <code>F</code>. It is not clear to me from the documentation whether <code>(ATOM 7)</code> should return <code>T</code> or <code>F</code>. I’m going to assume <code>T</code>. </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>CAR </td>
|
||||
<td>Host lambda function </td>
|
||||
<td>? </td>
|
||||
<td> </td>
|
||||
<td>Return the item indicated by the first pointer of a pair. NIL is treated specially: the CAR of NIL is NIL. </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>CAAAAR </td>
|
||||
<td>Lisp lambda function </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>CAAADR </td>
|
||||
<td>Lisp lambda function </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>CAAAR </td>
|
||||
<td>Lisp lambda function </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>CAADAR </td>
|
||||
<td>Lisp lambda function </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>CAADDR </td>
|
||||
<td>Lisp lambda function </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>CAADR </td>
|
||||
<td>Lisp lambda function </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>CAAR </td>
|
||||
<td>Lisp lambda function </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>CADAAR </td>
|
||||
<td>Lisp lambda function </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>CADADR </td>
|
||||
<td>Lisp lambda function </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>CADAR </td>
|
||||
<td>Lisp lambda function </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>CADDAR </td>
|
||||
<td>Lisp lambda function </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>CADDDR </td>
|
||||
<td>Lisp lambda function </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>CADDR </td>
|
||||
<td>Lisp lambda function </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>CADR </td>
|
||||
<td>Lisp lambda function </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>CDAAAR </td>
|
||||
<td>Lisp lambda function </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>CDAADR </td>
|
||||
<td>Lisp lambda function </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>CDAAR </td>
|
||||
<td>Lisp lambda function </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>CDADAR </td>
|
||||
<td>Lisp lambda function </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>CDADDR </td>
|
||||
<td>Lisp lambda function </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>CDADR </td>
|
||||
<td>Lisp lambda function </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>CDAR </td>
|
||||
<td>Lisp lambda function </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>CDDAAR </td>
|
||||
<td>Lisp lambda function </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>CDDADR </td>
|
||||
<td>Lisp lambda function </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>CDDAR </td>
|
||||
<td>Lisp lambda function </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>CDDDAR </td>
|
||||
<td>Lisp lambda function </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>CDDDDR </td>
|
||||
<td>Lisp lambda function </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>CDDDR </td>
|
||||
<td>Lisp lambda function </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>CDDR </td>
|
||||
<td>Lisp lambda function </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>CDR </td>
|
||||
<td>Host lambda function </td>
|
||||
<td>? </td>
|
||||
<td> </td>
|
||||
<td>Return the item indicated by the second pointer of a pair. NIL is treated specially: the CDR of NIL is NIL. </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>CONS </td>
|
||||
<td>Host lambda function </td>
|
||||
<td>? </td>
|
||||
<td> </td>
|
||||
<td>Construct a new instance of cons cell with this <code>car</code> and <code>cdr</code>. </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>CONSP </td>
|
||||
<td>Host lambda function </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
<td>Return <code>T</code> if object <code>o</code> is a cons cell, else <code>F</code>. <strong>NOTE THAT</strong> this is an extension function, not available in strct mode. I believe that Lisp 1.5 did not have any mechanism for testing whether an argument was, or was not, a cons cell. </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>COPY </td>
|
||||
<td>Lisp lambda function </td>
|
||||
<td>? </td>
|
||||
<td> </td>
|
||||
<td>see manual pages <a href="#page62">62</a> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>DEFINE </td>
|
||||
<td>Host lambda function </td>
|
||||
<td>? </td>
|
||||
<td>PSEUDO-FUNCTION </td>
|
||||
<td>Bootstrap-only version of <code>DEFINE</code> which, post boostrap, can be overwritten in LISP. The single argument to <code>DEFINE</code> should be an association list of symbols to lambda functions. See page 58 of the manual. </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>DIFFERENCE </td>
|
||||
<td>Host lambda function </td>
|
||||
<td>? </td>
|
||||
<td> </td>
|
||||
<td>? </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>DIVIDE </td>
|
||||
<td>Lisp lambda function </td>
|
||||
<td>? </td>
|
||||
<td> </td>
|
||||
<td>see manual pages <a href="#page26">26</a>, <a href="#page64">64</a> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>DOC </td>
|
||||
<td>Host lambda function </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
<td>Open the page for this <code>symbol</code> in the Lisp 1.5 manual, if known, in the default web browser. <strong>NOTE THAT</strong> this is an extension function, not available in strct mode. </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>EFFACE </td>
|
||||
<td>Lisp lambda function </td>
|
||||
<td>? </td>
|
||||
<td>PSEUDO-FUNCTION </td>
|
||||
<td>see manual pages <a href="#page63">63</a> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>ERROR </td>
|
||||
<td>Host lambda function </td>
|
||||
<td>? </td>
|
||||
<td>PSEUDO-FUNCTION </td>
|
||||
<td>Throw an error </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>EQ </td>
|
||||
<td>Host lambda function </td>
|
||||
<td>? </td>
|
||||
<td>PREDICATE </td>
|
||||
<td>Returns <code>T</code> if and only if both <code>x</code> and <code>y</code> are bound to the same atom, else <code>NIL</code>. </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>EQUAL </td>
|
||||
<td>Host lambda function </td>
|
||||
<td>? </td>
|
||||
<td>PREDICATE </td>
|
||||
<td>This is a predicate that is true if its two arguments are identical S-expressions, and false if they are different. (The elementary predicate <code>EQ</code> is defined only for atomic arguments.) The definition of <code>EQUAL</code> is an example of a conditional expression inside a conditional expression. NOTE: returns <code>F</code> on failure, not <code>NIL</code> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>EVAL </td>
|
||||
<td>Host lambda function </td>
|
||||
<td>? </td>
|
||||
<td> </td>
|
||||
<td>Evaluate this <code>expr</code> and return the result. If <code>environment</code> is not passed, it defaults to the current value of the global object list. The <code>depth</code> argument is part of the tracing system and should not be set by user code. All args are assumed to be numbers, symbols or <code>beowulf.cons-cell/ConsCell</code> objects. However, if called with just a single arg, <code>expr</code>, I’ll assume it’s being called from the Clojure REPL and will coerce the <code>expr</code> to <code>ConsCell</code>. </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>FACTORIAL </td>
|
||||
<td>Lisp lambda function </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>FIXP </td>
|
||||
<td>Host lambda function </td>
|
||||
<td>? </td>
|
||||
<td>PREDICATE </td>
|
||||
<td>? </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>GENSYM </td>
|
||||
<td>Host lambda function </td>
|
||||
<td>? </td>
|
||||
<td> </td>
|
||||
<td>Generate a unique symbol. </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>GET </td>
|
||||
<td>Host lambda function </td>
|
||||
<td>? </td>
|
||||
<td> </td>
|
||||
<td>From the manual: ‘<code>get</code> is somewhat like <code>prop</code>; however its value is car of the rest of the list if the <code>indicator</code> is found, and NIL otherwise.’ It’s clear that <code>GET</code> is expected to be defined in terms of <code>PROP</code>, but we can’t implement <code>PROP</code> here because we lack <code>EVAL</code>; and we can’t have <code>EVAL</code> here because both it and <code>APPLY</code> depends on <code>GET</code>. OK, It’s worse than that: the statement of the definition of <code>GET</code> (and of) <code>PROP</code> on page 59 says that the first argument to each must be a list; But the in the definition of <code>ASSOC</code> on page 70, when <code>GET</code> is called its first argument is always an atom. Since it’s <code>ASSOC</code> and <code>EVAL</code> which I need to make work, I’m going to assume that page 59 is wrong. </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>GREATERP </td>
|
||||
<td>Host lambda function </td>
|
||||
<td>? </td>
|
||||
<td>PREDICATE </td>
|
||||
<td>? </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>INTEROP </td>
|
||||
<td>Host lambda function </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>INTERSECTION </td>
|
||||
<td>Lisp lambda function </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>LENGTH </td>
|
||||
<td>Lisp lambda function </td>
|
||||
<td>? </td>
|
||||
<td> </td>
|
||||
<td>see manual pages <a href="#page62">62</a> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>LESSP </td>
|
||||
<td>Host lambda function </td>
|
||||
<td>? </td>
|
||||
<td>PREDICATE </td>
|
||||
<td>? </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>MAPLIST </td>
|
||||
<td>Lisp lambda function </td>
|
||||
<td>? </td>
|
||||
<td>FUNCTIONAL </td>
|
||||
<td>see manual pages <a href="#page20">20</a>, <a href="#page21">21</a>, <a href="#page63">63</a> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>MEMBER </td>
|
||||
<td>Lisp lambda function </td>
|
||||
<td>? </td>
|
||||
<td>PREDICATE </td>
|
||||
<td>see manual pages <a href="#page11">11</a>, <a href="#page62">62</a> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>MINUSP </td>
|
||||
<td>Lisp lambda function </td>
|
||||
<td>? </td>
|
||||
<td>PREDICATE </td>
|
||||
<td>see manual pages <a href="#page26">26</a>, <a href="#page64">64</a> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>NOT </td>
|
||||
<td>Lisp lambda function </td>
|
||||
<td>? </td>
|
||||
<td>PREDICATE </td>
|
||||
<td>see manual pages <a href="#page21">21</a>, <a href="#page23">23</a>, <a href="#page58">58</a> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>NULL </td>
|
||||
<td>Lisp lambda function </td>
|
||||
<td>? </td>
|
||||
<td>PREDICATE </td>
|
||||
<td>see manual pages <a href="#page11">11</a>, <a href="#page57">57</a> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>NUMBERP </td>
|
||||
<td>Host lambda function </td>
|
||||
<td>? </td>
|
||||
<td>PREDICATE </td>
|
||||
<td>? </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>OBLIST </td>
|
||||
<td>Host lambda function </td>
|
||||
<td>? </td>
|
||||
<td> </td>
|
||||
<td>Return a list of the symbols currently bound on the object list. <strong>NOTE THAT</strong> in the Lisp 1.5 manual, footnote at the bottom of page 69, it implies that an argument can be passed but I’m not sure of the semantics of this. </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>ONEP </td>
|
||||
<td>Lisp lambda function </td>
|
||||
<td>? </td>
|
||||
<td>PREDICATE </td>
|
||||
<td>see manual pages <a href="#page26">26</a>, <a href="#page64">64</a> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>OR </td>
|
||||
<td>Host lambda function </td>
|
||||
<td>? </td>
|
||||
<td>PREDICATE </td>
|
||||
<td><code>T</code> if and only if at least one of my <code>args</code> evaluates to something other than either <code>F</code> or <code>NIL</code>, else <code>F</code>. In <code>beowulf.host</code> principally because I don’t yet feel confident to define varargs functions in Lisp. </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>PAIR </td>
|
||||
<td>Lisp lambda function </td>
|
||||
<td>? </td>
|
||||
<td> </td>
|
||||
<td>see manual pages <a href="#page60">60</a> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>PAIRLIS </td>
|
||||
<td>Lisp lambda function, Host lambda function </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
<td>This function gives the list of pairs of corresponding elements of the lists <code>x</code> and <code>y</code>, and APPENDs this to the list <code>a</code>. The resultant list of pairs, which is like a table with two columns, is called an association list. Eessentially, it builds the environment on the stack, implementing shallow binding. All args are assumed to be <code>beowulf.cons-cell/ConsCell</code> objects. See page 12 of the Lisp 1.5 Programmers Manual. <strong>NOTE THAT</strong> this function is overridden by an implementation in Lisp, but is currently still present for bootstrapping. </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>PLUS </td>
|
||||
<td>Host lambda function </td>
|
||||
<td>? </td>
|
||||
<td> </td>
|
||||
<td>? </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>PRETTY </td>
|
||||
<td> </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>PRINT </td>
|
||||
<td> </td>
|
||||
<td>? </td>
|
||||
<td>PSEUDO-FUNCTION </td>
|
||||
<td>see manual pages <a href="#page65">65</a>, <a href="#page84">84</a> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>PROG </td>
|
||||
<td>Host nlambda function </td>
|
||||
<td>? </td>
|
||||
<td> </td>
|
||||
<td>The accursed <code>PROG</code> feature. See page 71 of the manual. Lisp 1.5 introduced <code>PROG</code>, and most Lisps have been stuck with it ever since. It introduces imperative programming into what should be a pure functional language, and consequently it’s going to be a pig to implement. Broadly, <code>PROG</code> is a variadic pseudo function called as a <code>FEXPR</code> (or possibly an <code>FSUBR</code>, although I’m not presently sure that would even work.) The arguments, which are unevaluated, are a list of forms, the first of which is expected to be a list of symbols which will be treated as names of variables within the program, and the rest of which (the ‘program body’) are either lists or symbols. Lists are treated as Lisp expressions which may be evaulated in turn. Symbols are treated as targets for the <code>GO</code> statement. <strong>GO:</strong> A <code>GO</code> statement takes the form of <code>(GO target)</code>, where <code>target</code> should be one of the symbols which occur at top level among that particular invocation of <code>PROG</code>s arguments. A <code>GO</code> statement may occur at top level in a PROG, or in a clause of a <code>COND</code> statement in a <code>PROG</code>, but not in a function called from the <code>PROG</code> statement. When a <code>GO</code> statement is evaluated, execution should transfer immediately to the expression which is the argument list immediately following the symbol which is its target. If the target is not found, an error with the code <code>A6</code> should be thrown. <strong>RETURN:</strong> A <code>RETURN</code> statement takes the form <code>(RETURN value)</code>, where <code>value</code> is any value. Following the evaluation of a <code>RETURN</code> statement, the <code>PROG</code> should immediately exit without executing any further expressions, returning the value. <strong>SET and SETQ:</strong> In addition to the above, if a <code>SET</code> or <code>SETQ</code> expression is encountered in any expression within the <code>PROG</code> body, it should affect not the global object list but instead only the local variables of the program. <strong>COND:</strong> In <strong>strict</strong> mode, when in normal execution, a <code>COND</code> statement none of whose clauses match should not return <code>NIL</code> but should throw an error with the code <code>A3</code>… <em>except</em> that inside a <code>PROG</code> body, it should not do so. <em>sigh</em>. <strong>Flow of control:</strong> Apart from the exceptions specified above, expressions in the program body are evaluated sequentially. If execution reaches the end of the program body, <code>NIL</code> is returned. Got all that? Good. </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>PROP </td>
|
||||
<td>Lisp lambda function </td>
|
||||
<td>? </td>
|
||||
<td>FUNCTIONAL </td>
|
||||
<td>see manual pages <a href="#page59">59</a> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>QUOTE </td>
|
||||
<td>Lisp lambda function </td>
|
||||
<td>? </td>
|
||||
<td> </td>
|
||||
<td>see manual pages <a href="#page10">10</a>, <a href="#page22">22</a>, <a href="#page71">71</a> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>QUOTIENT </td>
|
||||
<td>Host lambda function </td>
|
||||
<td>? </td>
|
||||
<td> </td>
|
||||
<td>I’m not certain from the documentation whether Lisp 1.5 <code>QUOTIENT</code> returned the integer part of the quotient, or a realnum representing the whole quotient. I am for now implementing the latter. </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>RANGE </td>
|
||||
<td>Lisp lambda function </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>READ </td>
|
||||
<td>Host lambda function </td>
|
||||
<td>? </td>
|
||||
<td>PSEUDO-FUNCTION </td>
|
||||
<td>An implementation of a Lisp reader sufficient for bootstrapping; not necessarily the final Lisp reader. <code>input</code> should be either a string representation of a LISP expression, or else an input stream. A single form will be read. </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>REMAINDER </td>
|
||||
<td>Host lambda function </td>
|
||||
<td>? </td>
|
||||
<td> </td>
|
||||
<td>? </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>REPEAT </td>
|
||||
<td>Lisp lambda function </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>RPLACA </td>
|
||||
<td>Host lambda function </td>
|
||||
<td>? </td>
|
||||
<td>PSEUDO-FUNCTION </td>
|
||||
<td>Replace the CAR pointer of this <code>cell</code> with this <code>value</code>. Dangerous, should really not exist, but does in Lisp 1.5 (and was important for some performance hacks in early Lisps) </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>RPLACD </td>
|
||||
<td>Host lambda function </td>
|
||||
<td>? </td>
|
||||
<td>PSEUDO-FUNCTION </td>
|
||||
<td>Replace the CDR pointer of this <code>cell</code> with this <code>value</code>. Dangerous, should really not exist, but does in Lisp 1.5 (and was important for some performance hacks in early Lisps) </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>SEARCH </td>
|
||||
<td>Lisp lambda function </td>
|
||||
<td>? </td>
|
||||
<td>FUNCTIONAL </td>
|
||||
<td>see manual pages <a href="#page63">63</a> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>SET </td>
|
||||
<td>Host lambda function </td>
|
||||
<td>? </td>
|
||||
<td>PSEUDO-FUNCTION </td>
|
||||
<td>Implementation of SET in Clojure. Add to the <code>oblist</code> a binding of the value of <code>var</code> to the value of <code>val</code>. NOTE WELL: this is not SETQ! </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>SUB1 </td>
|
||||
<td>Lisp lambda function, Host lambda function </td>
|
||||
<td>? </td>
|
||||
<td> </td>
|
||||
<td>? </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>SUB2 </td>
|
||||
<td>Lisp lambda function </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>SUBLIS </td>
|
||||
<td>Lisp lambda function </td>
|
||||
<td>? </td>
|
||||
<td> </td>
|
||||
<td>see manual pages <a href="#page12">12</a>, <a href="#page61">61</a> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>SUBST </td>
|
||||
<td>Lisp lambda function </td>
|
||||
<td>? </td>
|
||||
<td> </td>
|
||||
<td>see manual pages <a href="#page11">11</a>, <a href="#page61">61</a> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>SYSIN </td>
|
||||
<td>Host lambda function </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
<td>Read the contents of the file at this <code>filename</code> into the object list. If the file is not a valid Beowulf sysout file, this will probably corrupt the system, you have been warned. File paths will be considered relative to the filepath set when starting Lisp. It is intended that sysout files can be read both from resources within the jar file, and from the file system. If a named file exists in both the file system and the resources, the file system will be preferred. <strong>NOTE THAT</strong> if the provided <code>filename</code> does not end with <code>.lsp</code> (which, if you’re writing it from the Lisp REPL, it won’t), the extension <code>.lsp</code> will be appended. <strong>NOTE THAT</strong> this is an extension function, not available in strct mode. </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>SYSOUT </td>
|
||||
<td>Host lambda function </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
<td>Dump the current content of the object list to file. If no <code>filepath</code> is specified, a file name will be constructed of the symbol <code>Sysout</code> and the current date. File paths will be considered relative to the filepath set when starting Lisp. <strong>NOTE THAT</strong> this is an extension function, not available in strct mode. </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>TERPRI </td>
|
||||
<td> </td>
|
||||
<td>? </td>
|
||||
<td>PSEUDO-FUNCTION </td>
|
||||
<td>see manual pages <a href="#page65">65</a>, <a href="#page84">84</a> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>TIMES </td>
|
||||
<td>Host lambda function </td>
|
||||
<td>? </td>
|
||||
<td> </td>
|
||||
<td>? </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>TRACE </td>
|
||||
<td>Host lambda function </td>
|
||||
<td>? </td>
|
||||
<td>PSEUDO-FUNCTION </td>
|
||||
<td>Add this <code>s</code> to the set of symbols currently being traced. If <code>s</code> is not a symbol or sequence of symbols, does nothing. </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>UNION </td>
|
||||
<td>Lisp lambda function </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
<td>? </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>UNTRACE </td>
|
||||
<td>Host lambda function </td>
|
||||
<td>? </td>
|
||||
<td>PSEUDO-FUNCTION </td>
|
||||
<td>Remove this <code>s</code> from the set of symbols currently being traced. If <code>s</code> is not a symbol or sequence of symbols, does nothing. </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>ZEROP </td>
|
||||
<td>Lisp lambda function </td>
|
||||
<td>? </td>
|
||||
<td>PREDICATE </td>
|
||||
<td>see manual pages <a href="#page26">26</a>, <a href="#page64">64</a> </td>
|
||||
</tr>
|
||||
<tr><td> NIL </td><td> Lisp variable </td><td> ? </td><td> </td><td> see manual pages <a href="#page22">22</a>, <a href="#page69">69</a> </td></tr>
|
||||
<tr><td> T </td><td> Lisp variable </td><td> ? </td><td> </td><td> see manual pages <a href="#page22">22</a>, <a href="#page69">69</a> </td></tr>
|
||||
<tr><td> F </td><td> Lisp variable </td><td> ? </td><td> </td><td> see manual pages <a href="#page22">22</a>, <a href="#page69">69</a> </td></tr>
|
||||
<tr><td> ADD1 </td><td> Host lambda function </td><td> ? </td><td> </td><td> ? </td></tr>
|
||||
<tr><td> AND </td><td> Host lambda function </td><td> ? </td><td> PREDICATE </td><td> <code>T</code> if and only if none of my <code>args</code> evaluate to either <code>F</code> or <code>NIL</code>, else <code>F</code>. In <code>beowulf.host</code> principally because I don’t yet feel confident to define varargs functions in Lisp. </td></tr>
|
||||
<tr><td> APPEND </td><td> Lisp lambda function </td><td> ? </td><td> </td><td> see manual pages <a href="#page11">11</a>, <a href="#page61">61</a> </td></tr>
|
||||
<tr><td> APPLY </td><td> Host lambda function </td><td> ? </td><td> </td><td> Apply this <code>function</code> to these <code>arguments</code> in this <code>environment</code> and return the result. For bootstrapping, at least, a version of APPLY written in Clojure. All args are assumed to be symbols or <code>beowulf.cons-cell/ConsCell</code> objects. See page 13 of the Lisp 1.5 Programmers Manual. </td></tr>
|
||||
<tr><td> ASSOC </td><td> Lisp lambda function, Host lambda function </td><td> ? </td><td> ? </td><td> If a is an association list such as the one formed by PAIRLIS in the above example, then assoc will produce the first pair whose first term is x. Thus it is a table searching function. All args are assumed to be <code>beowulf.cons-cell/ConsCell</code> objects. See page 12 of the Lisp 1.5 Programmers Manual. <strong>NOTE THAT</strong> this function is overridden by an implementation in Lisp, but is currently still present for bootstrapping. </td></tr>
|
||||
<tr><td> ATOM </td><td> Host lambda function </td><td> ? </td><td> PREDICATE </td><td> Returns <code>T</code> if and only if the argument <code>x</code> is bound to an atom; else <code>F</code>. It is not clear to me from the documentation whether <code>(ATOM 7)</code> should return <code>T</code> or <code>F</code>. I’m going to assume <code>T</code>. </td></tr>
|
||||
<tr><td> CAR </td><td> Host lambda function </td><td> ? </td><td> </td><td> Return the item indicated by the first pointer of a pair. NIL is treated specially: the CAR of NIL is NIL. </td></tr>
|
||||
<tr><td> CAAAAR </td><td> Lisp lambda function </td><td> ? </td><td> ? </td><td> ? </td></tr>
|
||||
<tr><td> CAAADR </td><td> Lisp lambda function </td><td> ? </td><td> ? </td><td> ? </td></tr>
|
||||
<tr><td> CAAAR </td><td> Lisp lambda function </td><td> ? </td><td> ? </td><td> ? </td></tr>
|
||||
<tr><td> CAADAR </td><td> Lisp lambda function </td><td> ? </td><td> ? </td><td> ? </td></tr>
|
||||
<tr><td> CAADDR </td><td> Lisp lambda function </td><td> ? </td><td> ? </td><td> ? </td></tr>
|
||||
<tr><td> CAADR </td><td> Lisp lambda function </td><td> ? </td><td> ? </td><td> ? </td></tr>
|
||||
<tr><td> CAAR </td><td> Lisp lambda function </td><td> ? </td><td> ? </td><td> ? </td></tr>
|
||||
<tr><td> CADAAR </td><td> Lisp lambda function </td><td> ? </td><td> ? </td><td> ? </td></tr>
|
||||
<tr><td> CADADR </td><td> Lisp lambda function </td><td> ? </td><td> ? </td><td> ? </td></tr>
|
||||
<tr><td> CADAR </td><td> Lisp lambda function </td><td> ? </td><td> ? </td><td> ? </td></tr>
|
||||
<tr><td> CADDAR </td><td> Lisp lambda function </td><td> ? </td><td> ? </td><td> ? </td></tr>
|
||||
<tr><td> CADDDR </td><td> Lisp lambda function </td><td> ? </td><td> ? </td><td> ? </td></tr>
|
||||
<tr><td> CADDR </td><td> Lisp lambda function </td><td> ? </td><td> ? </td><td> ? </td></tr>
|
||||
<tr><td> CADR </td><td> Lisp lambda function </td><td> ? </td><td> ? </td><td> ? </td></tr>
|
||||
<tr><td> CDAAAR </td><td> Lisp lambda function </td><td> ? </td><td> ? </td><td> ? </td></tr>
|
||||
<tr><td> CDAADR </td><td> Lisp lambda function </td><td> ? </td><td> ? </td><td> ? </td></tr>
|
||||
<tr><td> CDAAR </td><td> Lisp lambda function </td><td> ? </td><td> ? </td><td> ? </td></tr>
|
||||
<tr><td> CDADAR </td><td> Lisp lambda function </td><td> ? </td><td> ? </td><td> ? </td></tr>
|
||||
<tr><td> CDADDR </td><td> Lisp lambda function </td><td> ? </td><td> ? </td><td> ? </td></tr>
|
||||
<tr><td> CDADR </td><td> Lisp lambda function </td><td> ? </td><td> ? </td><td> ? </td></tr>
|
||||
<tr><td> CDAR </td><td> Lisp lambda function </td><td> ? </td><td> ? </td><td> ? </td></tr>
|
||||
<tr><td> CDDAAR </td><td> Lisp lambda function </td><td> ? </td><td> ? </td><td> ? </td></tr>
|
||||
<tr><td> CDDADR </td><td> Lisp lambda function </td><td> ? </td><td> ? </td><td> ? </td></tr>
|
||||
<tr><td> CDDAR </td><td> Lisp lambda function </td><td> ? </td><td> ? </td><td> ? </td></tr>
|
||||
<tr><td> CDDDAR </td><td> Lisp lambda function </td><td> ? </td><td> ? </td><td> ? </td></tr>
|
||||
<tr><td> CDDDDR </td><td> Lisp lambda function </td><td> ? </td><td> ? </td><td> ? </td></tr>
|
||||
<tr><td> CDDDR </td><td> Lisp lambda function </td><td> ? </td><td> ? </td><td> ? </td></tr>
|
||||
<tr><td> CDDR </td><td> Lisp lambda function </td><td> ? </td><td> ? </td><td> ? </td></tr>
|
||||
<tr><td> CDR </td><td> Host lambda function </td><td> ? </td><td> </td><td> Return the item indicated by the second pointer of a pair. NIL is treated specially: the CDR of NIL is NIL. </td></tr>
|
||||
<tr><td> CONS </td><td> Host lambda function </td><td> ? </td><td> </td><td> Construct a new instance of cons cell with this <code>car</code> and <code>cdr</code>. </td></tr>
|
||||
<tr><td> CONSP </td><td> Host lambda function </td><td> ? </td><td> ? </td><td> Return <code>T</code> if object <code>o</code> is a cons cell, else <code>F</code>. <strong>NOTE THAT</strong> this is an extension function, not available in strct mode. I believe that Lisp 1.5 did not have any mechanism for testing whether an argument was, or was not, a cons cell. </td></tr>
|
||||
<tr><td> COPY </td><td> Lisp lambda function </td><td> ? </td><td> </td><td> see manual pages <a href="#page62">62</a> </td></tr>
|
||||
<tr><td> DEFINE </td><td> Host lambda function </td><td> ? </td><td> PSEUDO-FUNCTION </td><td> Bootstrap-only version of <code>DEFINE</code> which, post boostrap, can be overwritten in LISP. The single argument to <code>DEFINE</code> should be an association list of symbols to lambda functions. See page 58 of the manual. </td></tr>
|
||||
<tr><td> DIFFERENCE </td><td> Host lambda function </td><td> ? </td><td> </td><td> ? </td></tr>
|
||||
<tr><td> DIVIDE </td><td> Lisp lambda function </td><td> ? </td><td> </td><td> see manual pages <a href="#page26">26</a>, <a href="#page64">64</a> </td></tr>
|
||||
<tr><td> DOC </td><td> Host lambda function </td><td> ? </td><td> ? </td><td> Open the page for this <code>symbol</code> in the Lisp 1.5 manual, if known, in the default web browser. <strong>NOTE THAT</strong> this is an extension function, not available in strct mode. </td></tr>
|
||||
<tr><td> EFFACE </td><td> Lisp lambda function </td><td> ? </td><td> PSEUDO-FUNCTION </td><td> see manual pages <a href="#page63">63</a> </td></tr>
|
||||
<tr><td> ERROR </td><td> Host lambda function </td><td> ? </td><td> PSEUDO-FUNCTION </td><td> Throw an error </td></tr>
|
||||
<tr><td> EQ </td><td> Host lambda function </td><td> ? </td><td> PREDICATE </td><td> Returns <code>T</code> if and only if both <code>x</code> and <code>y</code> are bound to the same atom, else <code>NIL</code>. </td></tr>
|
||||
<tr><td> EQUAL </td><td> Host lambda function </td><td> ? </td><td> PREDICATE </td><td> This is a predicate that is true if its two arguments are identical S-expressions, and false if they are different. (The elementary predicate <code>EQ</code> is defined only for atomic arguments.) The definition of <code>EQUAL</code> is an example of a conditional expression inside a conditional expression. NOTE: returns <code>F</code> on failure, not <code>NIL</code> </td></tr>
|
||||
<tr><td> EVAL </td><td> Host lambda function </td><td> ? </td><td> </td><td> Evaluate this <code>expr</code> and return the result. If <code>environment</code> is not passed, it defaults to the current value of the global object list. The <code>depth</code> argument is part of the tracing system and should not be set by user code. All args are assumed to be numbers, symbols or <code>beowulf.cons-cell/ConsCell</code> objects. However, if called with just a single arg, <code>expr</code>, I’ll assume it’s being called from the Clojure REPL and will coerce the <code>expr</code> to <code>ConsCell</code>. </td></tr>
|
||||
<tr><td> FACTORIAL </td><td> Lisp lambda function </td><td> ? </td><td> ? </td><td> ? </td></tr>
|
||||
<tr><td> FIXP </td><td> Host lambda function </td><td> ? </td><td> PREDICATE </td><td> ? </td></tr>
|
||||
<tr><td> GENSYM </td><td> Host lambda function </td><td> ? </td><td> </td><td> Generate a unique symbol. </td></tr>
|
||||
<tr><td> GET </td><td> Host lambda function </td><td> ? </td><td> </td><td> From the manual: ‘<code>get</code> is somewhat like <code>prop</code>; however its value is car of the rest of the list if the <code>indicator</code> is found, and NIL otherwise.’ It’s clear that <code>GET</code> is expected to be defined in terms of <code>PROP</code>, but we can’t implement <code>PROP</code> here because we lack <code>EVAL</code>; and we can’t have <code>EVAL</code> here because both it and <code>APPLY</code> depends on <code>GET</code>. OK, It’s worse than that: the statement of the definition of <code>GET</code> (and of) <code>PROP</code> on page 59 says that the first argument to each must be a list; But the in the definition of <code>ASSOC</code> on page 70, when <code>GET</code> is called its first argument is always an atom. Since it’s <code>ASSOC</code> and <code>EVAL</code> which I need to make work, I’m going to assume that page 59 is wrong. </td></tr>
|
||||
<tr><td> GREATERP </td><td> Host lambda function </td><td> ? </td><td> PREDICATE </td><td> ? </td></tr>
|
||||
<tr><td> INTEROP </td><td> Host lambda function </td><td> ? </td><td> ? </td><td> ? </td></tr>
|
||||
<tr><td> INTERSECTION </td><td> Lisp lambda function </td><td> ? </td><td> ? </td><td> ? </td></tr>
|
||||
<tr><td> LENGTH </td><td> Lisp lambda function </td><td> ? </td><td> </td><td> see manual pages <a href="#page62">62</a> </td></tr>
|
||||
<tr><td> LESSP </td><td> Host lambda function </td><td> ? </td><td> PREDICATE </td><td> ? </td></tr>
|
||||
<tr><td> MAPLIST </td><td> Lisp lambda function </td><td> ? </td><td> FUNCTIONAL </td><td> see manual pages <a href="#page20">20</a>, <a href="#page21">21</a>, <a href="#page63">63</a> </td></tr>
|
||||
<tr><td> MEMBER </td><td> Lisp lambda function </td><td> ? </td><td> PREDICATE </td><td> see manual pages <a href="#page11">11</a>, <a href="#page62">62</a> </td></tr>
|
||||
<tr><td> MINUSP </td><td> Lisp lambda function </td><td> ? </td><td> PREDICATE </td><td> see manual pages <a href="#page26">26</a>, <a href="#page64">64</a> </td></tr>
|
||||
<tr><td> NOT </td><td> Lisp lambda function </td><td> ? </td><td> PREDICATE </td><td> see manual pages <a href="#page21">21</a>, <a href="#page23">23</a>, <a href="#page58">58</a> </td></tr>
|
||||
<tr><td> NULL </td><td> Lisp lambda function </td><td> ? </td><td> PREDICATE </td><td> see manual pages <a href="#page11">11</a>, <a href="#page57">57</a> </td></tr>
|
||||
<tr><td> NUMBERP </td><td> Host lambda function </td><td> ? </td><td> PREDICATE </td><td> ? </td></tr>
|
||||
<tr><td> OBLIST </td><td> Host lambda function </td><td> ? </td><td> </td><td> Return a list of the symbols currently bound on the object list. <strong>NOTE THAT</strong> in the Lisp 1.5 manual, footnote at the bottom of page 69, it implies that an argument can be passed but I’m not sure of the semantics of this. </td></tr>
|
||||
<tr><td> ONEP </td><td> Lisp lambda function </td><td> ? </td><td> PREDICATE </td><td> see manual pages <a href="#page26">26</a>, <a href="#page64">64</a> </td></tr>
|
||||
<tr><td> OR </td><td> Host lambda function </td><td> ? </td><td> PREDICATE </td><td> <code>T</code> if and only if at least one of my <code>args</code> evaluates to something other than either <code>F</code> or <code>NIL</code>, else <code>F</code>. In <code>beowulf.host</code> principally because I don’t yet feel confident to define varargs functions in Lisp. </td></tr>
|
||||
<tr><td> PAIR </td><td> Lisp lambda function </td><td> ? </td><td> </td><td> see manual pages <a href="#page60">60</a> </td></tr>
|
||||
<tr><td> PAIRLIS </td><td> Lisp lambda function, Host lambda function </td><td> ? </td><td> ? </td><td> This function gives the list of pairs of corresponding elements of the lists <code>x</code> and <code>y</code>, and APPENDs this to the list <code>a</code>. The resultant list of pairs, which is like a table with two columns, is called an association list. Eessentially, it builds the environment on the stack, implementing shallow binding. All args are assumed to be <code>beowulf.cons-cell/ConsCell</code> objects. See page 12 of the Lisp 1.5 Programmers Manual. <strong>NOTE THAT</strong> this function is overridden by an implementation in Lisp, but is currently still present for bootstrapping. </td></tr>
|
||||
<tr><td> PLUS </td><td> Host lambda function </td><td> ? </td><td> </td><td> ? </td></tr>
|
||||
<tr><td> PRETTY </td><td> </td><td> ? </td><td> ? </td><td> ? </td></tr>
|
||||
<tr><td> PRINT </td><td> </td><td> ? </td><td> PSEUDO-FUNCTION </td><td> see manual pages <a href="#page65">65</a>, <a href="#page84">84</a> </td></tr>
|
||||
<tr><td> PROG </td><td> Host nlambda function </td><td> ? </td><td> </td><td> The accursed <code>PROG</code> feature. See page 71 of the manual. Lisp 1.5 introduced <code>PROG</code>, and most Lisps have been stuck with it ever since. It introduces imperative programming into what should be a pure functional language, and consequently it’s going to be a pig to implement. Broadly, <code>PROG</code> is a variadic pseudo function called as a <code>FEXPR</code> (or possibly an <code>FSUBR</code>, although I’m not presently sure that would even work.) The arguments, which are unevaluated, are a list of forms, the first of which is expected to be a list of symbols which will be treated as names of variables within the program, and the rest of which (the ‘program body’) are either lists or symbols. Lists are treated as Lisp expressions which may be evaulated in turn. Symbols are treated as targets for the <code>GO</code> statement. <strong>GO:</strong> A <code>GO</code> statement takes the form of <code>(GO target)</code>, where <code>target</code> should be one of the symbols which occur at top level among that particular invocation of <code>PROG</code>s arguments. A <code>GO</code> statement may occur at top level in a PROG, or in a clause of a <code>COND</code> statement in a <code>PROG</code>, but not in a function called from the <code>PROG</code> statement. When a <code>GO</code> statement is evaluated, execution should transfer immediately to the expression which is the argument list immediately following the symbol which is its target. If the target is not found, an error with the code <code>A6</code> should be thrown. <strong>RETURN:</strong> A <code>RETURN</code> statement takes the form <code>(RETURN value)</code>, where <code>value</code> is any value. Following the evaluation of a <code>RETURN</code> statement, the <code>PROG</code> should immediately exit without executing any further expressions, returning the value. <strong>SET and SETQ:</strong> In addition to the above, if a <code>SET</code> or <code>SETQ</code> expression is encountered in any expression within the <code>PROG</code> body, it should affect not the global object list but instead only the local variables of the program. <strong>COND:</strong> In <strong>strict</strong> mode, when in normal execution, a <code>COND</code> statement none of whose clauses match should not return <code>NIL</code> but should throw an error with the code <code>A3</code>… <em>except</em> that inside a <code>PROG</code> body, it should not do so. <em>sigh</em>. <strong>Flow of control:</strong> Apart from the exceptions specified above, expressions in the program body are evaluated sequentially. If execution reaches the end of the program body, <code>NIL</code> is returned. Got all that? Good. </td></tr>
|
||||
<tr><td> PROP </td><td> Lisp lambda function </td><td> ? </td><td> FUNCTIONAL </td><td> see manual pages <a href="#page59">59</a> </td></tr>
|
||||
<tr><td> QUOTE </td><td> Lisp lambda function </td><td> ? </td><td> </td><td> see manual pages <a href="#page10">10</a>, <a href="#page22">22</a>, <a href="#page71">71</a> </td></tr>
|
||||
<tr><td> QUOTIENT </td><td> Host lambda function </td><td> ? </td><td> </td><td> I’m not certain from the documentation whether Lisp 1.5 <code>QUOTIENT</code> returned the integer part of the quotient, or a realnum representing the whole quotient. I am for now implementing the latter. </td></tr>
|
||||
<tr><td> RANGE </td><td> Lisp lambda function </td><td> ? </td><td> ? </td><td> ? </td></tr>
|
||||
<tr><td> READ </td><td> Host lambda function </td><td> ? </td><td> PSEUDO-FUNCTION </td><td> An implementation of a Lisp reader sufficient for bootstrapping; not necessarily the final Lisp reader. <code>input</code> should be either a string representation of a LISP expression, or else an input stream. A single form will be read. </td></tr>
|
||||
<tr><td> REMAINDER </td><td> Host lambda function </td><td> ? </td><td> </td><td> ? </td></tr>
|
||||
<tr><td> REPEAT </td><td> Lisp lambda function </td><td> ? </td><td> ? </td><td> ? </td></tr>
|
||||
<tr><td> RPLACA </td><td> Host lambda function </td><td> ? </td><td> PSEUDO-FUNCTION </td><td> Replace the CAR pointer of this <code>cell</code> with this <code>value</code>. Dangerous, should really not exist, but does in Lisp 1.5 (and was important for some performance hacks in early Lisps) </td></tr>
|
||||
<tr><td> RPLACD </td><td> Host lambda function </td><td> ? </td><td> PSEUDO-FUNCTION </td><td> Replace the CDR pointer of this <code>cell</code> with this <code>value</code>. Dangerous, should really not exist, but does in Lisp 1.5 (and was important for some performance hacks in early Lisps) </td></tr>
|
||||
<tr><td> SEARCH </td><td> Lisp lambda function </td><td> ? </td><td> FUNCTIONAL </td><td> see manual pages <a href="#page63">63</a> </td></tr>
|
||||
<tr><td> SET </td><td> Host lambda function </td><td> ? </td><td> PSEUDO-FUNCTION </td><td> Implementation of SET in Clojure. Add to the <code>oblist</code> a binding of the value of <code>var</code> to the value of <code>val</code>. NOTE WELL: this is not SETQ! </td></tr>
|
||||
<tr><td> SUB1 </td><td> Lisp lambda function, Host lambda function </td><td> ? </td><td> </td><td> ? </td></tr>
|
||||
<tr><td> SUB2 </td><td> Lisp lambda function </td><td> ? </td><td> ? </td><td> ? </td></tr>
|
||||
<tr><td> SUBLIS </td><td> Lisp lambda function </td><td> ? </td><td> </td><td> see manual pages <a href="#page12">12</a>, <a href="#page61">61</a> </td></tr>
|
||||
<tr><td> SUBST </td><td> Lisp lambda function </td><td> ? </td><td> </td><td> see manual pages <a href="#page11">11</a>, <a href="#page61">61</a> </td></tr>
|
||||
<tr><td> SYSIN </td><td> Host lambda function </td><td> ? </td><td> ? </td><td> Read the contents of the file at this <code>filename</code> into the object list. If the file is not a valid Beowulf sysout file, this will probably corrupt the system, you have been warned. File paths will be considered relative to the filepath set when starting Lisp. It is intended that sysout files can be read both from resources within the jar file, and from the file system. If a named file exists in both the file system and the resources, the file system will be preferred. <strong>NOTE THAT</strong> if the provided <code>filename</code> does not end with <code>.lsp</code> (which, if you’re writing it from the Lisp REPL, it won’t), the extension <code>.lsp</code> will be appended. <strong>NOTE THAT</strong> this is an extension function, not available in strct mode. </td></tr>
|
||||
<tr><td> SYSOUT </td><td> Host lambda function </td><td> ? </td><td> ? </td><td> Dump the current content of the object list to file. If no <code>filepath</code> is specified, a file name will be constructed of the symbol <code>Sysout</code> and the current date. File paths will be considered relative to the filepath set when starting Lisp. <strong>NOTE THAT</strong> this is an extension function, not available in strct mode. </td></tr>
|
||||
<tr><td> TERPRI </td><td> </td><td> ? </td><td> PSEUDO-FUNCTION </td><td> see manual pages <a href="#page65">65</a>, <a href="#page84">84</a> </td></tr>
|
||||
<tr><td> TIMES </td><td> Host lambda function </td><td> ? </td><td> </td><td> ? </td></tr>
|
||||
<tr><td> TRACE </td><td> Host lambda function </td><td> ? </td><td> PSEUDO-FUNCTION </td><td> Add this <code>s</code> to the set of symbols currently being traced. If <code>s</code> is not a symbol or sequence of symbols, does nothing. </td></tr>
|
||||
<tr><td> UNION </td><td> Lisp lambda function </td><td> ? </td><td> ? </td><td> ? </td></tr>
|
||||
<tr><td> UNTRACE </td><td> Host lambda function </td><td> ? </td><td> PSEUDO-FUNCTION </td><td> Remove this <code>s</code> from the set of symbols currently being traced. If <code>s</code> is not a symbol or sequence of symbols, does nothing. </td></tr>
|
||||
<tr><td> ZEROP </td><td> Lisp lambda function </td><td> ? </td><td> PREDICATE </td><td> see manual pages <a href="#page26">26</a>, <a href="#page64">64</a> </td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>Functions described as ‘Lisp function’ above are defined in the default sysout file, <code>resources/lisp1.5.lsp</code>, which will be loaded by default unless you specify another initfile on the command line.</p>
|
||||
<p>Functions described as ‘Host function’ are implemented in Clojure, but if you’re brave you can redefine them in Lisp and the Lisp definitions will take precedence over the Clojure implementations.</p>
|
||||
<h3><a href="#architectural-plan" name="architectural-plan"></a>Architectural plan</h3>
|
||||
<h3><a href="#architectural-plan" id="architectural-plan"></a>Architectural plan</h3>
|
||||
<p>Not everything documented in this section is yet built. It indicates the direction of travel and intended destination, not the current state.</p>
|
||||
<h4><a href="#resources-lisp1-5-lsp" name="resources-lisp1-5-lsp"></a>resources/lisp1.5.lsp</h4>
|
||||
<h4><a href="#resourceslisp15lsp" id="resourceslisp15lsp"></a>resources/lisp1.5.lsp</h4>
|
||||
<p>The objective is to have within <code>resources/lisp1.5.lsp</code>, all those functions defined in the Lisp 1.5 Programmer’s Manual which can be implemented in Lisp.</p>
|
||||
<p>This means that, while Beowulf is hosted on Clojure, all that would be required to rehost Lisp 1.5 on a different platform would be to reimplement</p>
|
||||
<ul>
|
||||
|
@ -791,45 +197,46 @@
|
|||
<li>read.clj</li>
|
||||
</ul>
|
||||
<p>The objective this is to make it fairly easy to implement Lisp 1.5 on top of any of the many <a href="https://github.com/kanaka/mal">Make A Lisp</a> implementations.</p>
|
||||
<h4><a href="#beowulf-boostrap-clj" name="beowulf-boostrap-clj"></a>beowulf/boostrap.clj</h4>
|
||||
<h4><a href="#beowulfboostrapclj" id="beowulfboostrapclj"></a>beowulf/boostrap.clj</h4>
|
||||
<p>This file is essentially Lisp as defined in Chapter 1 (pages 1-14) of the Lisp 1.5 Programmer’s Manual; that is to say, a very simple Lisp language, which should, I believe, be sufficient in conjunction with the functions provided by <code>beowulf.host</code>, to bootstrap the full Lisp 1.5 interpreter.</p>
|
||||
<p>In addition it contains the function <code>INTEROP</code>, which allows host language functions to be called from Lisp.</p>
|
||||
<h4><a href="#beowulf-host-clj" name="beowulf-host-clj"></a>beowulf/host.clj</h4>
|
||||
<h4><a href="#beowulfhostclj" id="beowulfhostclj"></a>beowulf/host.clj</h4>
|
||||
<p>This file provides Lisp 1.5 functions which can’t be (or can’t efficiently be) implemented in Lisp 1.5, which therefore need to be implemented in the host language, in this case Clojure.</p>
|
||||
<h4><a href="#beowulf-read-clj" name="beowulf-read-clj"></a>beowulf/read.clj</h4>
|
||||
<h4><a href="#beowulfreadclj" id="beowulfreadclj"></a>beowulf/read.clj</h4>
|
||||
<p>This file provides the reader required for boostrapping. It’s not a bad reader - it provides feedback on errors found in the input - but it isn’t the real Lisp reader.</p>
|
||||
<p>Intended deviations from the behaviour of the real Lisp reader are as follows:</p>
|
||||
<ol>
|
||||
<li>It reads the meta-expression language <code>MEXPR</code> in addition to the symbolic expression language <code>SEXPR</code>, which I do not believe the Lisp 1.5 reader ever did;</li>
|
||||
<li>It treats everything between a double semi-colon and an end of line as a comment, as most modern Lisps do; but I do not believe Lisp 1.5 had this feature.</li>
|
||||
</ol>
|
||||
<h3><a href="#commentary" name="commentary"></a>Commentary</h3>
|
||||
<h3><a href="#commentary" id="commentary"></a>Commentary</h3>
|
||||
<p>What’s surprised me in working on this is how much more polished Lisp 1.5 is than legend had led me to believe. The language is remarkably close to <a href="http://www.softwarepreservation.org/projects/LISP/standard_lisp_family/#Portable_Standard_LISP_">Portable Standard Lisp</a> which is in my opinion one of the best and most usable early Lisp implementations.</p>
|
||||
<p>What’s even more surprising is how faithful a reimplementation of Lisp 1.5 the first Lisp dialect I learned, <a href="https://en.wikipedia.org/wiki/Acornsoft_LISP">Acornsoft Lisp</a>, turns out to have been.</p>
|
||||
<p>I’m convinced you could still use Lisp 1.5 for interesting and useful software (which isn’t to say that modern Lisps aren’t better, but this is software which is almost sixty years old).</p>
|
||||
<h2><a href="#installation" name="installation"></a>Installation</h2>
|
||||
<h2><a href="#installation" id="installation"></a>Installation</h2>
|
||||
<p>Download the latest <a href="https://github.com/simon-brooke/beowulf/releases">release ‘uberjar’</a> and run it using:</p>
|
||||
<pre><code class="bash"> java -jar <path name of uberjar>
|
||||
<pre><code class="language-bash"> java -jar <path name of uberjar>
|
||||
</code></pre>
|
||||
<p>Or clone the source and build it using:</p>
|
||||
<pre><code class="bash"> lein uberjar`
|
||||
<pre><code class="language-bash"> lein uberjar`
|
||||
</code></pre>
|
||||
<p>To build it you will require to have <a href="https://leiningen.org/">Leiningen</a> installed.</p>
|
||||
<h3><a href="#input-output" name="input-output"></a>Input/output</h3>
|
||||
<h3><a href="#inputoutput" id="inputoutput"></a>Input/output</h3>
|
||||
<p>Lisp 1.5 greatly predates modern computers. It had a facility to print to a line printer, or to punch cards on a punch-card machine, and it had a facility to read system images in from tape; but there’s no file I/O as we would currently understand it, and, because there are no character strings and the valid characters within an atom are limited, it isn’t easy to compose a sensible filename.</p>
|
||||
<p>I’ve provided two functions to work around this problem.</p>
|
||||
<h4><a href="#sysout" name="sysout"></a>SYSOUT</h4>
|
||||
<h4><a href="#sysout" id="sysout"></a>SYSOUT</h4>
|
||||
<p><code>SYSOUT</code> dumps the global object list to disk as a single S Expression (specifically: an association list). This allows you to persist your session, with all your current work, to disk. The function takes one argument, expected to be a symbol, and, if that argument is provided, writes a file whose name is that symbol with <code>.lsp</code> appended. If no argument is provided, it will construct a filename comprising the token <code>Sysout</code>, followed by the current date, followed by <code>.lsp</code>. In either case the file will be written to the directory given in the FILEPATH argument at startup time, or by default the current directory.</p>
|
||||
<p>Obviously, <code>SYSOUT</code> may be called interactively (and this is the expected practice).</p>
|
||||
<h4><a href="#sysin" name="sysin"></a>SYSIN</h4>
|
||||
<h4><a href="#sysin" id="sysin"></a>SYSIN</h4>
|
||||
<p><code>SYSIN</code> reads a file from disk and overwrites the global object list with its contents. The expected practice is that this will be a file created by <code>SYSOUT</code>. A command line flag <code>--read</code> is provided so that you can specify</p>
|
||||
<h2><a href="#learning-lisp-1-5" name="learning-lisp-1-5"></a>Learning Lisp 1.5</h2>
|
||||
<h2><a href="#learning-lisp-15" id="learning-lisp-15"></a>Learning Lisp 1.5</h2>
|
||||
<p>The <code>Lisp 1.5 Programmer's Manual</code> is still <a href="https://mitpress.mit.edu/books/lisp-15-programmers-manual">in print, ISBN 13 978-0-262-13011-0</a>; but it’s also <a href="http://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf">available online</a>.</p>
|
||||
<h2><a href="#other-lisp-1-5-resources" name="other-lisp-1-5-resources"></a>Other Lisp 1.5 resources</h2>
|
||||
<h2><a href="#other-lisp-15-resources" id="other-lisp-15-resources"></a>Other Lisp 1.5 resources</h2>
|
||||
<p>The main resource I’m aware of is the Software Preservation Society’s site, <a href="http://www.softwarepreservation.org/projects/LISP/lisp1.5">here</a>. It has lots of fascinating stuff including full assembler listings for various obsolete processors, but I failed to find the Lisp source of Lisp functions as a text file, which is why <code>resources/lisp1.5.lsp</code> is largely copytyped and reconstructed from the manual.</p>
|
||||
<h3><a href="#other-implementations" name="other-implementations"></a>Other implementations</h3>
|
||||
<h3><a href="#other-implementations" id="other-implementations"></a>Other implementations</h3>
|
||||
<p>There’s an online (browser native) Lisp 1.5 implementation <a href="https://pages.zick.run/ichigo/">here</a> (source code <a href="https://github.com/zick/IchigoLisp">here</a>). It even has a working compiler!</p>
|
||||
<h3><a href="#history-resources" name="history-resources"></a>History resources</h3>
|
||||
<h3><a href="#history-resources" id="history-resources"></a>History resources</h3>
|
||||
<p>I’m compiling a <a href="https://simon-brooke.github.io/beowulf/docs/further_reading.html">list of links to historical documents on Lisp 1.5</a>.</p>
|
||||
<h2><a href="#license" name="license"></a>License</h2>
|
||||
<p>Copyright © 2019 Simon Brooke. Licensed under the GNU General Public License, version 2.0 or (at your option) any later version.</p></div></div></div></body></html>
|
||||
<h2><a href="#license" id="license"></a>License</h2>
|
||||
<p>Copyright © 2019 Simon Brooke. Licensed under the GNU General Public License, version 2.0 or (at your option) any later version.</p>
|
||||
</div></div></div></body></html>
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -19,11 +19,12 @@
|
|||
[environ "1.2.0"]
|
||||
[instaparse "1.4.12"]
|
||||
[org.jline/jline "3.23.0"]
|
||||
[rhizome "0.2.9"] ;; not needed in production builds
|
||||
[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}
|
||||
|
|
|
@ -516,9 +516,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]
|
||||
(doall
|
||||
(map
|
||||
#(PUT (CAR %) indicator (CDR %))
|
||||
a-list))
|
||||
#(when (PUT (CAR %) indicator (CDR %)) (CAR %))
|
||||
a-list)))
|
||||
|
||||
(defn DEFINE
|
||||
"Bootstrap-only version of `DEFINE` which, post boostrap, can be overwritten
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
(ns beowulf.host-test
|
||||
(:require [beowulf.cons-cell :refer [F make-beowulf-list T]]
|
||||
[beowulf.host :refer [CDR DIFFERENCE GENSYM GET NUMBERP PLUS PUT
|
||||
RPLACA RPLACD TIMES]]
|
||||
(: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 [NIL]]
|
||||
[beowulf.oblist :refer [*options* NIL]]
|
||||
[beowulf.read :refer [gsp]]
|
||||
[clojure.test :refer [deftest is testing use-fixtures]]))
|
||||
[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")
|
||||
|
@ -34,17 +37,30 @@
|
|||
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"
|
||||
"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))]
|
||||
(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"
|
||||
|
@ -71,13 +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"
|
||||
(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))))
|
||||
|
|
Loading…
Reference in a new issue