1502 lines
122 KiB
HTML
1502 lines
122 KiB
HTML
<html>
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
|
<link rel="stylesheet" href="../coverage.css"/> <title> beowulf/bootstrap.clj </title>
|
|
</head>
|
|
<body>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
001 (ns beowulf.bootstrap
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
002 "Lisp as defined in Chapter 1 (pages 1-14) of the
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
003 `Lisp 1.5 Programmer's Manual`; that is to say, a very simple Lisp language,
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
004 which should, I believe, be sufficient in conjunction with the functions
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
005 provided by `beowulf.host`, be sufficient to bootstrap the full Lisp 1.5
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
006 interpreter..
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
007
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
008 The convention is adopted that functions in this file with names in
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
009 ALLUPPERCASE are Lisp 1.5 functions (although written in Clojure) and that
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
010 therefore all arguments must be numbers, symbols or `beowulf.cons_cell.ConsCell`
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
011 objects."
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
012 (:require [beowulf.cons-cell :refer [F make-beowulf-list make-cons-cell
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
013 pretty-print T]]
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
014 [beowulf.host :refer [ASSOC ATOM CAAR CAADR CADAR CADDR CADR CAR CDR
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
015 CONS ERROR GET LIST NUMBERP PAIRLIS traced?]]
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
016 [beowulf.oblist :refer [*options* NIL]]
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
017 [clojure.string :as s]
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
018 [clojure.tools.trace :refer [deftrace]])
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
019 (:import [beowulf.cons_cell ConsCell]
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
020 [clojure.lang Symbol]))
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
021
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
022 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
023 ;;;
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
024 ;;; Copyright (C) 2022-2023 Simon Brooke
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
025 ;;;
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
026 ;;; This program is free software; you can redistribute it and/or
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
027 ;;; modify it under the terms of the GNU General Public License
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
028 ;;; as published by the Free Software Foundation; either version 2
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
029 ;;; of the License, or (at your option) any later version.
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
030 ;;;
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
031 ;;; This program is distributed in the hope that it will be useful,
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
032 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
033 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
034 ;;; GNU General Public License for more details.
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
035 ;;;
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
036 ;;; You should have received a copy of the GNU General Public License
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
037 ;;; along with this program; if not, write to the Free Software
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
038 ;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
039 ;;;
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
040 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
041
|
|
</span><br/>
|
|
<span class="covered" title="5 out of 5 forms covered">
|
|
042 (declare APPLY EVAL EVCON prog-eval)
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
043
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
044 ;;;; The PROGram feature ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
045
|
|
</span><br/>
|
|
<span class="covered" title="2 out of 2 forms covered">
|
|
046 (def ^:dynamic
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
047 *depth*
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
048 "Stack depth. Unfortunately we need to be able to pass round depth for
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
049 functions which call EVAL/APPLY but do not know about depth."
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
050 0)
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
051
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
052 (defn- trace-indent
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 3 forms covered">
|
|
053 ([] (trace-indent *depth*))
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 6 forms covered">
|
|
054 ([d] (s/join (repeat d " "))))
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
055
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
056 (def find-target
|
|
</span><br/>
|
|
<span class="covered" title="2 out of 2 forms covered">
|
|
057 (memoize
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
058 (fn [target body]
|
|
</span><br/>
|
|
<span class="covered" title="2 out of 2 forms covered">
|
|
059 (loop [body' body]
|
|
</span><br/>
|
|
<span class="covered" title="3 out of 3 forms covered">
|
|
060 (cond
|
|
</span><br/>
|
|
<span class="partial" title="3 out of 11 forms covered">
|
|
061 (= body' NIL) (throw (ex-info (str "Mislar GO miercels: `" target "`")
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 10 forms covered">
|
|
062 {:phase :lisp
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
063 :function 'PROG
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
064 :type :lisp
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
065 :code :A6
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 1 forms covered">
|
|
066 :target target}))
|
|
</span><br/>
|
|
<span class="covered" title="4 out of 4 forms covered">
|
|
067 (= (.getCar body') target) body'
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
068 :else (recur (.getCdr body')))))))
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
069
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
070 (defn- prog-cond
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
071 "Like `EVCON`, q.v. except using `prog-eval` instead of `EVAL` and not
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
072 throwing an error if no clause matches."
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
073 [clauses vars env depth]
|
|
</span><br/>
|
|
<span class="covered" title="2 out of 2 forms covered">
|
|
074 (loop [clauses' clauses]
|
|
</span><br/>
|
|
<span class="covered" title="6 out of 6 forms covered">
|
|
075 (if-not (= clauses' NIL)
|
|
</span><br/>
|
|
<span class="covered" title="9 out of 9 forms covered">
|
|
076 (let [test (prog-eval (CAAR clauses') vars env depth)]
|
|
</span><br/>
|
|
<span class="covered" title="8 out of 8 forms covered">
|
|
077 (if (not (#{NIL F} test))
|
|
</span><br/>
|
|
<span class="covered" title="8 out of 8 forms covered">
|
|
078 (prog-eval (CADAR clauses') vars env depth)
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
079 (recur (.getCdr clauses'))))
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 1 forms covered">
|
|
080 NIL)))
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
081
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
082 (defn- merge-vars [vars env]
|
|
</span><br/>
|
|
<span class="covered" title="3 out of 3 forms covered">
|
|
083 (reduce
|
|
</span><br/>
|
|
<span class="covered" title="2 out of 2 forms covered">
|
|
084 #(make-cons-cell
|
|
</span><br/>
|
|
<span class="covered" title="8 out of 8 forms covered">
|
|
085 (make-cons-cell %2 (@vars %2))
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
086 env)
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
087 env
|
|
</span><br/>
|
|
<span class="covered" title="5 out of 5 forms covered">
|
|
088 (keys @vars)))
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
089
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
090 (defn prog-eval
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
091 "Like `EVAL`, q.v., except handling symbols, and expressions starting
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
092 `GO`, `RETURN`, `SET` and `SETQ` specially."
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
093 [expr vars env depth]
|
|
</span><br/>
|
|
<span class="partial" title="3 out of 4 forms covered">
|
|
094 (cond
|
|
</span><br/>
|
|
<span class="covered" title="4 out of 4 forms covered">
|
|
095 (number? expr) expr
|
|
</span><br/>
|
|
<span class="covered" title="8 out of 8 forms covered">
|
|
096 (symbol? expr) (@vars expr)
|
|
</span><br/>
|
|
<span class="covered" title="9 out of 9 forms covered">
|
|
097 (instance? ConsCell expr) (case (CAR expr)
|
|
</span><br/>
|
|
<span class="covered" title="5 out of 5 forms covered">
|
|
098 COND (prog-cond (CDR expr)
|
|
</span><br/>
|
|
<span class="covered" title="3 out of 3 forms covered">
|
|
099 vars env depth)
|
|
</span><br/>
|
|
<span class="covered" title="4 out of 4 forms covered">
|
|
100 GO (let [target (CADR expr)]
|
|
</span><br/>
|
|
<span class="partial" title="4 out of 5 forms covered">
|
|
101 (when (traced? 'PROG)
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 4 forms covered">
|
|
102 (println " PROG:GO: Goto " target))
|
|
</span><br/>
|
|
<span class="covered" title="3 out of 3 forms covered">
|
|
103 (make-cons-cell
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
104 '*PROGGO* target))
|
|
</span><br/>
|
|
<span class="covered" title="3 out of 3 forms covered">
|
|
105 RETURN (let [val (prog-eval
|
|
</span><br/>
|
|
<span class="covered" title="3 out of 3 forms covered">
|
|
106 (CADR expr)
|
|
</span><br/>
|
|
<span class="covered" title="3 out of 3 forms covered">
|
|
107 vars env depth)]
|
|
</span><br/>
|
|
<span class="partial" title="4 out of 5 forms covered">
|
|
108 (when (traced? 'PROG)
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 3 forms covered">
|
|
109 (println " PROG:RETURN: Returning "
|
|
</span><br/>
|
|
<span class="partial" title="2 out of 3 forms covered">
|
|
110 val))
|
|
</span><br/>
|
|
<span class="partial" title="9 out of 12 forms covered">
|
|
111 (make-cons-cell
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
112 '*PROGRETURN*
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
113 val))
|
|
</span><br/>
|
|
<span class="covered" title="6 out of 6 forms covered">
|
|
114 SET (let [var (prog-eval (CADR expr)
|
|
</span><br/>
|
|
<span class="covered" title="3 out of 3 forms covered">
|
|
115 vars env depth)
|
|
</span><br/>
|
|
<span class="covered" title="5 out of 5 forms covered">
|
|
116 val (prog-eval (CADDR expr)
|
|
</span><br/>
|
|
<span class="covered" title="5 out of 5 forms covered">
|
|
117 vars env depth)]
|
|
</span><br/>
|
|
<span class="partial" title="7 out of 10 forms covered">
|
|
118 (when (traced? 'PROG)
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 4 forms covered">
|
|
119 (println " PROG:SET: Setting "
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 2 forms covered">
|
|
120 var " to " val))
|
|
</span><br/>
|
|
<span class="covered" title="3 out of 3 forms covered">
|
|
121 (swap! vars
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
122 assoc
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
123 var
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
124 val)
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
125 val)
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 4 forms covered">
|
|
126 SETQ (let [var (CADDR expr)
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 3 forms covered">
|
|
127 val (prog-eval var
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 3 forms covered">
|
|
128 vars env depth)]
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 5 forms covered">
|
|
129 (when (traced? 'PROG)
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 6 forms covered">
|
|
130 (println " PROG:SETQ: Setting " var " to " val))
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 3 forms covered">
|
|
131 (swap! vars
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 1 forms covered">
|
|
132 assoc
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 3 forms covered">
|
|
133 (CADR expr)
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 1 forms covered">
|
|
134 val)
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 1 forms covered">
|
|
135 val)
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
136 ;; else
|
|
</span><br/>
|
|
<span class="covered" title="3 out of 3 forms covered">
|
|
137 (beowulf.bootstrap/EVAL expr
|
|
</span><br/>
|
|
<span class="covered" title="4 out of 4 forms covered">
|
|
138 (merge-vars vars env)
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
139 depth))))
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
140
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
141 (defn PROG
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
142 "The accursed `PROG` feature. See page 71 of the manual.
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
143
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
144 Lisp 1.5 introduced `PROG`, and most Lisps have been stuck with it ever
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
145 since. It introduces imperative programming into what should be a pure
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
146 functional language, and consequently it's going to be a pig to implement.
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
147
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
148 Broadly, `PROG` is a variadic pseudo function called as a `FEXPR` (or
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
149 possibly an `FSUBR`, although I'm not presently sure that would even work.)
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
150
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
151 The arguments, which are unevaluated, are a list of forms, the first of
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
152 which is expected to be a list of symbols which will be treated as names
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
153 of variables within the program, and the rest of which (the 'program body')
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
154 are either lists or symbols. Lists are treated as Lisp expressions which
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
155 may be evaulated in turn. Symbols are treated as targets for the `GO`
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
156 statement.
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
157
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
158 **GO:**
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
159 A `GO` statement takes the form of `(GO target)`, where
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
160 `target` should be one of the symbols which occur at top level among that
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
161 particular invocation of `PROG`s arguments. A `GO` statement may occur at
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
162 top level in a PROG, or in a clause of a `COND` statement in a `PROG`, but
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
163 not in a function called from the `PROG` statement. When a `GO` statement
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
164 is evaluated, execution should transfer immediately to the expression which
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
165 is the argument list immediately following the symbol which is its target.
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
166
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
167 If the target is not found, an error with the code `A6` should be thrown.
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
168
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
169 **RETURN:**
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
170 A `RETURN` statement takes the form `(RETURN value)`, where
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
171 `value` is any value. Following the evaluation of a `RETURN` statement,
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
172 the `PROG` should immediately exit without executing any further
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
173 expressions, returning the value.
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
174
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
175 **SET and SETQ:**
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
176 In addition to the above, if a `SET` or `SETQ` expression is encountered
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
177 in any expression within the `PROG` body, it should affect not the global
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
178 object list but instead only the local variables of the program.
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
179
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
180 **COND:**
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
181 In **strict** mode, when in normal execution, a `COND` statement none of
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
182 whose clauses match should not return `NIL` but should throw an error with
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
183 the code `A3`... *except* that inside a `PROG` body, it should not do so.
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
184 *sigh*.
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
185
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
186 **Flow of control:**
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
187 Apart from the exceptions specified above, expressions in the program body
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
188 are evaluated sequentially. If execution reaches the end of the program
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
189 body, `NIL` is returned.
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
190
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
191 Got all that?
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
192
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
193 Good."
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
194 [program env depth]
|
|
</span><br/>
|
|
<span class="covered" title="4 out of 4 forms covered">
|
|
195 (let [trace (traced? 'PROG)
|
|
</span><br/>
|
|
<span class="covered" title="14 out of 14 forms covered">
|
|
196 vars (atom (reduce merge (map #(assoc {} % NIL) (.getCar program))))
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
197 body (.getCdr program)
|
|
</span><br/>
|
|
<span class="covered" title="6 out of 6 forms covered">
|
|
198 targets (set (filter symbol? body))]
|
|
</span><br/>
|
|
<span class="partial" title="2 out of 4 forms covered">
|
|
199 (when trace (do
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 3 forms covered">
|
|
200 (println "Program:")
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 3 forms covered">
|
|
201 (pretty-print program))) ;; for debugging
|
|
</span><br/>
|
|
<span class="covered" title="2 out of 2 forms covered">
|
|
202 (loop [cursor body]
|
|
</span><br/>
|
|
<span class="partial" title="6 out of 7 forms covered">
|
|
203 (let [step (if (= NIL cursor) NIL (.getCar cursor))]
|
|
</span><br/>
|
|
<span class="partial" title="2 out of 8 forms covered">
|
|
204 (when trace (do (println "Executing step: " step)
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 6 forms covered">
|
|
205 (println " with vars: " @vars)))
|
|
</span><br/>
|
|
<span class="partial" title="6 out of 7 forms covered">
|
|
206 (cond (= cursor NIL) NIL
|
|
</span><br/>
|
|
<span class="covered" title="4 out of 4 forms covered">
|
|
207 (symbol? step) (recur (.getCdr cursor))
|
|
</span><br/>
|
|
<span class="covered" title="7 out of 7 forms covered">
|
|
208 :else (let [v (prog-eval (.getCar cursor) vars env depth)]
|
|
</span><br/>
|
|
<span class="partial" title="2 out of 7 forms covered">
|
|
209 (when trace (println " --> " v))
|
|
</span><br/>
|
|
<span class="covered" title="5 out of 5 forms covered">
|
|
210 (if (instance? ConsCell v)
|
|
</span><br/>
|
|
<span class="covered" title="3 out of 3 forms covered">
|
|
211 (case (.getCar v)
|
|
</span><br/>
|
|
<span class="covered" title="2 out of 2 forms covered">
|
|
212 *PROGGO* (let [target (.getCdr v)]
|
|
</span><br/>
|
|
<span class="covered" title="4 out of 4 forms covered">
|
|
213 (if (targets target)
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
214 (recur (find-target target body))
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 7 forms covered">
|
|
215 (throw (ex-info (str "Uncynlic GO miercels `"
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 1 forms covered">
|
|
216 target "`")
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 12 forms covered">
|
|
217 {:phase :lisp
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
218 :function 'PROG
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 1 forms covered">
|
|
219 :args program
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
220 :type :lisp
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
221 :code :A6
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 1 forms covered">
|
|
222 :target target
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 1 forms covered">
|
|
223 :targets targets}))))
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
224 *PROGRETURN* (.getCdr v)
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
225 ;; else
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 1 forms covered">
|
|
226 (recur (.getCdr cursor)))
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
227 (recur (.getCdr cursor)))))))))
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
228
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
229 ;;;; Tracing execution ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
230
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
231 (defn- trace-call
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
232 "Show a trace of a call to the function named by this `function-symbol`
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
233 with these `args` at this depth."
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
234 [function-symbol args depth]
|
|
</span><br/>
|
|
<span class="partial" title="4 out of 5 forms covered">
|
|
235 (when (traced? function-symbol)
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 4 forms covered">
|
|
236 (let [indent (trace-indent depth)]
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 9 forms covered">
|
|
237 (println (str indent "> " function-symbol " " args)))))
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
238
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
239 (defn- trace-response
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
240 "Show a trace of this `response` from the function named by this
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
241 `function-symbol` at this depth."
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
242 [function-symbol response depth]
|
|
</span><br/>
|
|
<span class="partial" title="4 out of 5 forms covered">
|
|
243 (when (traced? function-symbol)
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 7 forms covered">
|
|
244 (let [indent (apply str (trace-indent depth))]
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 10 forms covered">
|
|
245 (println (str "<" indent " " function-symbol " " response))))
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
246 response)
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
247
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
248 ;;;; Support functions for interpreter ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
249
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
250 (defn value
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
251 "Seek a value for this symbol `s` by checking each of these indicators in
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
252 turn."
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
253 ([s]
|
|
</span><br/>
|
|
<span class="covered" title="10 out of 10 forms covered">
|
|
254 (value s (list 'APVAL 'EXPR 'FEXPR 'SUBR 'FSUBR)))
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
255 ([s indicators]
|
|
</span><br/>
|
|
<span class="covered" title="5 out of 5 forms covered">
|
|
256 (when (symbol? s)
|
|
</span><br/>
|
|
<span class="covered" title="15 out of 15 forms covered">
|
|
257 (first (remove #(= % NIL) (map #(GET s %)
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
258 indicators))))))
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
259
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
260 (defn SASSOC
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
261 "Like `ASSOC`, but with an action to take if no value is found.
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
262
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
263 From the manual, page 60:
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
264
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
265 'The function `sassoc` searches `y`, which is a list of dotted pairs, for
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
266 a pair whose first element that is `x`. If such a pair is found, the value
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
267 of `sassoc` is this pair. Otherwise the function `u` of no arguments is
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
268 taken as the value of `sassoc`.'"
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
269 [x y u]
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 5 forms covered">
|
|
270 (let [v (ASSOC x y)]
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 7 forms covered">
|
|
271 (if-not (= v NIL) v
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 5 forms covered">
|
|
272 (APPLY u NIL NIL))))
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
273
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
274
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
275 ;;;; APPLY ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
276
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
277 (defn try-resolve-subroutine
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
278 "Attempt to resolve this `subr` with these `args`."
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
279 [subr args]
|
|
</span><br/>
|
|
<span class="covered" title="11 out of 11 forms covered">
|
|
280 (when (and subr (not= subr NIL))
|
|
</span><br/>
|
|
<span class="covered" title="6 out of 6 forms covered">
|
|
281 (try @(resolve subr)
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
282 (catch Throwable any
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 4 forms covered">
|
|
283 (throw (ex-info "þegnung (SUBR) ne āfand"
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 7 forms covered">
|
|
284 {:phase :apply
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 1 forms covered">
|
|
285 :function subr
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 1 forms covered">
|
|
286 :args args
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
287 :type :beowulf}
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 1 forms covered">
|
|
288 any))))))
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
289
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
290 (defn- apply-symbolic
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
291 "Apply this `funtion-symbol` to these `args` in this `environment` and
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
292 return the result."
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
293 [^Symbol function-symbol args ^ConsCell environment depth]
|
|
</span><br/>
|
|
<span class="covered" title="5 out of 5 forms covered">
|
|
294 (trace-call function-symbol args depth)
|
|
</span><br/>
|
|
<span class="covered" title="5 out of 5 forms covered">
|
|
295 (let [lisp-fn (value function-symbol '(EXPR FEXPR)) ;; <-- should these be handled differently? I think so!
|
|
</span><br/>
|
|
<span class="partial" title="7 out of 8 forms covered">
|
|
296 args' (cond (= NIL args) args
|
|
</span><br/>
|
|
<span class="partial" title="3 out of 4 forms covered">
|
|
297 (empty? args) NIL
|
|
</span><br/>
|
|
<span class="covered" title="5 out of 5 forms covered">
|
|
298 (instance? ConsCell args) args
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 3 forms covered">
|
|
299 :else (make-beowulf-list args))
|
|
</span><br/>
|
|
<span class="covered" title="4 out of 4 forms covered">
|
|
300 subr (value function-symbol '(SUBR FSUBR))
|
|
</span><br/>
|
|
<span class="covered" title="4 out of 4 forms covered">
|
|
301 host-fn (try-resolve-subroutine subr args')
|
|
</span><br/>
|
|
<span class="covered" title="9 out of 9 forms covered">
|
|
302 result (cond (and lisp-fn
|
|
</span><br/>
|
|
<span class="covered" title="9 out of 9 forms covered">
|
|
303 (not= lisp-fn NIL)) (APPLY lisp-fn args' environment depth)
|
|
</span><br/>
|
|
<span class="covered" title="2 out of 2 forms covered">
|
|
304 host-fn (try
|
|
</span><br/>
|
|
<span class="covered" title="10 out of 10 forms covered">
|
|
305 (apply host-fn (when (instance? ConsCell args') args'))
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
306 (catch Exception any
|
|
</span><br/>
|
|
<span class="covered" title="6 out of 6 forms covered">
|
|
307 (throw (ex-info (str "Uncynlic þegnung: "
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
308 (.getMessage any))
|
|
</span><br/>
|
|
<span class="covered" title="7 out of 7 forms covered">
|
|
309 {:phase :apply
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
310 :function function-symbol
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
311 :args args
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
312 :type :beowulf}
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
313 any))))
|
|
</span><br/>
|
|
<span class="covered" title="3 out of 3 forms covered">
|
|
314 :else (ex-info "þegnung ne āfand"
|
|
</span><br/>
|
|
<span class="covered" title="7 out of 7 forms covered">
|
|
315 {:phase :apply
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
316 :function function-symbol
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
317 :args args
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
318 :type :beowulf}))]
|
|
</span><br/>
|
|
<span class="covered" title="5 out of 5 forms covered">
|
|
319 (trace-response function-symbol result depth)
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
320 result))
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
321
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
322 ;; (LABEL ARGS
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
323 ;; (COND ((COND ((ONEP (LENGTH ARGS)) ARGS)
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
324 ;; (T (ATTRIB (CAR ARGS) (APPLY CONC (CDR ARGS) NIL))))
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
325 ;; ARGS)))
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
326 ;; ((1 2 3 4) (5 6 7 8) (9 10 11 12))
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
327 ;; NIL
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
328 ;; (def function (make-beowulf-list '(LABEL ARGS (COND
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
329 ;; ((COND ((ONEP (LENGTH ARGS)) ARGS)
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
330 ;; (T (ATTRIB (CAR ARGS)
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
331 ;; (APPLY CONC (CDR ARGS) NIL))))
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
332 ;; ARGS)))))
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
333 ;; (def args (make-beowulf-list '((1 2 3 4) (5 6 7 8) (9 10 11 12))))
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
334
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
335 ;; function
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
336 ;; (CADR function)
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
337 ;; (CADDR function)
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
338
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
339 (defn apply-label
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
340 "Apply in the special case that the first element in the function is `LABEL`."
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
341 [function args environment depth]
|
|
</span><br/>
|
|
<span class="covered" title="2 out of 2 forms covered">
|
|
342 (EVAL
|
|
</span><br/>
|
|
<span class="covered" title="3 out of 3 forms covered">
|
|
343 (CADDR function)
|
|
</span><br/>
|
|
<span class="covered" title="2 out of 2 forms covered">
|
|
344 (CONS
|
|
</span><br/>
|
|
<span class="covered" title="6 out of 6 forms covered">
|
|
345 (CONS (CADR function) args)
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
346 environment)
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
347 depth))
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
348
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
349 ;; (apply-label function args NIL 1)
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
350 ;; (APPLY function args NIL 1)
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
351
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
352 (defn- apply-lambda
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
353 "Apply in the special case that the first element in the function is `LAMBDA`."
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
354 [function args environment depth]
|
|
</span><br/>
|
|
<span class="covered" title="2 out of 2 forms covered">
|
|
355 (EVAL
|
|
</span><br/>
|
|
<span class="covered" title="3 out of 3 forms covered">
|
|
356 (CADDR function)
|
|
</span><br/>
|
|
<span class="covered" title="8 out of 8 forms covered">
|
|
357 (PAIRLIS (CADR function) args environment) depth))
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
358
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
359 (defn APPLY
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
360 "Apply this `function` to these `arguments` in this `environment` and return
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
361 the result.
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
362
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
363 For bootstrapping, at least, a version of APPLY written in Clojure.
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
364 All args are assumed to be symbols or `beowulf.cons-cell/ConsCell` objects.
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
365 See page 13 of the Lisp 1.5 Programmers Manual."
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
366 ([function args environment]
|
|
</span><br/>
|
|
<span class="covered" title="6 out of 6 forms covered">
|
|
367 (APPLY function args environment *depth*))
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
368 ([function args environment depth]
|
|
</span><br/>
|
|
<span class="covered" title="11 out of 11 forms covered">
|
|
369 (binding [*depth* (inc depth)]
|
|
</span><br/>
|
|
<span class="covered" title="9 out of 9 forms covered">
|
|
370 (trace-call 'APPLY (list function args environment) depth)
|
|
</span><br/>
|
|
<span class="covered" title="4 out of 4 forms covered">
|
|
371 (let [result (cond
|
|
</span><br/>
|
|
<span class="partial" title="3 out of 7 forms covered">
|
|
372 (= NIL function) (if (:strict *options*)
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 1 forms covered">
|
|
373 NIL
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 4 forms covered">
|
|
374 (throw (ex-info "NIL sí ne þegnung"
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 8 forms covered">
|
|
375 {:phase :apply
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
376 :function "NIL"
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 1 forms covered">
|
|
377 :args args
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
378 :type :beowulf})))
|
|
</span><br/>
|
|
<span class="covered" title="12 out of 12 forms covered">
|
|
379 (= (ATOM function) T) (apply-symbolic function args environment (inc depth))
|
|
</span><br/>
|
|
<span class="covered" title="5 out of 5 forms covered">
|
|
380 :else (case (first function)
|
|
</span><br/>
|
|
<span class="covered" title="6 out of 6 forms covered">
|
|
381 LABEL (apply-label function args environment depth)
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 10 forms covered">
|
|
382 FUNARG (APPLY (CADR function) args (CADDR function) depth)
|
|
</span><br/>
|
|
<span class="covered" title="6 out of 6 forms covered">
|
|
383 LAMBDA (apply-lambda function args environment depth)
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
384 ;; else
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
385 ;; OK, this is *not* what is says in the manual...
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
386 ;; COND (EVCON ???)
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 4 forms covered">
|
|
387 (throw (ex-info "Ungecnáwen wyrþan sí þegnung-weard"
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 7 forms covered">
|
|
388 {:phase :apply
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 1 forms covered">
|
|
389 :function function
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 1 forms covered">
|
|
390 :args args
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
391 :type :beowulf}))))]
|
|
</span><br/>
|
|
<span class="covered" title="5 out of 5 forms covered">
|
|
392 (trace-response 'APPLY result depth)
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
393 result))))
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
394
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
395 ;;;; EVAL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
396
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
397 (defn- EVCON
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
398 "Inner guts of primitive COND. All `clauses` are assumed to be
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
399 `beowulf.cons-cell/ConsCell` objects. Note that tests in Lisp 1.5
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
400 often return `F`, not `NIL`, on failure. If no clause matches,
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
401 then, strictly, we throw an error with code `:A3`.
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
402
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
403 See pages 13 and 71 of the Lisp 1.5 Programmers Manual."
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
404 [clauses env depth]
|
|
</span><br/>
|
|
<span class="covered" title="2 out of 2 forms covered">
|
|
405 (loop [clauses' clauses]
|
|
</span><br/>
|
|
<span class="covered" title="6 out of 6 forms covered">
|
|
406 (if-not (= clauses' NIL)
|
|
</span><br/>
|
|
<span class="covered" title="8 out of 8 forms covered">
|
|
407 (let [test (EVAL (CAAR clauses') env depth)]
|
|
</span><br/>
|
|
<span class="covered" title="8 out of 8 forms covered">
|
|
408 (if (not (#{NIL F} test))
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
409 ;; (and (not= test NIL) (not= test F))
|
|
</span><br/>
|
|
<span class="covered" title="7 out of 7 forms covered">
|
|
410 (EVAL (CADAR clauses') env depth)
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
411 (recur (.getCdr clauses'))))
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 4 forms covered">
|
|
412 (if (:strict *options*)
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 4 forms covered">
|
|
413 (throw (ex-info "Ne ġefōg dǣl in COND"
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 10 forms covered">
|
|
414 {:phase :eval
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
415 :function 'COND
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 3 forms covered">
|
|
416 :args (list clauses)
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
417 :type :lisp
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
418 :code :A3}))
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 1 forms covered">
|
|
419 NIL))))
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
420
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
421 (defn- EVLIS
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
422 "Map `EVAL` across this list of `args` in the context of this
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
423 `env`ironment.All args are assumed to be `beowulf.cons-cell/ConsCell` objects.
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
424 See page 13 of the Lisp 1.5 Programmers Manual."
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
425 [args env depth]
|
|
</span><br/>
|
|
<span class="covered" title="2 out of 2 forms covered">
|
|
426 (cond
|
|
</span><br/>
|
|
<span class="covered" title="4 out of 4 forms covered">
|
|
427 (= NIL args) NIL
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
428 :else
|
|
</span><br/>
|
|
<span class="covered" title="2 out of 2 forms covered">
|
|
429 (make-cons-cell
|
|
</span><br/>
|
|
<span class="covered" title="7 out of 7 forms covered">
|
|
430 (EVAL (CAR args) env depth)
|
|
</span><br/>
|
|
<span class="covered" title="7 out of 7 forms covered">
|
|
431 (EVLIS (CDR args) env depth))))
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
432
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
433 (defn- eval-symbolic
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
434 [expr env depth]
|
|
</span><br/>
|
|
<span class="covered" title="5 out of 5 forms covered">
|
|
435 (let [v (ASSOC expr env)
|
|
</span><br/>
|
|
<span class="covered" title="7 out of 7 forms covered">
|
|
436 indent (apply str (repeat depth "-"))]
|
|
</span><br/>
|
|
<span class="partial" title="4 out of 5 forms covered">
|
|
437 (when (traced? 'EVAL)
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 12 forms covered">
|
|
438 (println (str indent ": EVAL: sceald bindele: " (or v "nil"))))
|
|
</span><br/>
|
|
<span class="covered" title="5 out of 5 forms covered">
|
|
439 (if (instance? ConsCell v)
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
440 (.getCdr v)
|
|
</span><br/>
|
|
<span class="covered" title="4 out of 4 forms covered">
|
|
441 (let [v' (value expr)]
|
|
</span><br/>
|
|
<span class="partial" title="4 out of 5 forms covered">
|
|
442 (when (traced? 'EVAL)
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 15 forms covered">
|
|
443 (println (str indent ": EVAL: deóp bindele: (" expr " . " (or v' "nil") ")")))
|
|
</span><br/>
|
|
<span class="covered" title="2 out of 2 forms covered">
|
|
444 (if v'
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
445 v'
|
|
</span><br/>
|
|
<span class="covered" title="7 out of 7 forms covered">
|
|
446 (throw (ex-info (format "Ne tácen-bindele āfand: `%s`" expr)
|
|
</span><br/>
|
|
<span class="covered" title="10 out of 10 forms covered">
|
|
447 {:phase :eval
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
448 :function 'EVAL
|
|
</span><br/>
|
|
<span class="covered" title="5 out of 5 forms covered">
|
|
449 :args (list expr env depth)
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
450 :type :lisp
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
451 :code :A8})))))))
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
452
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
453 (defn EVAL
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
454 "Evaluate this `expr` and return the result. If `environment` is not passed,
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
455 it defaults to the current value of the global object list. The `depth`
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
456 argument is part of the tracing system and should not be set by user code.
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
457
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
458 All args are assumed to be numbers, symbols or `beowulf.cons-cell/ConsCell`
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
459 objects. However, if called with just a single arg, `expr`, I'll assume it's
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
460 being called from the Clojure REPL and will coerce the `expr` to `ConsCell`."
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
461 ([expr]
|
|
</span><br/>
|
|
<span class="covered" title="15 out of 15 forms covered">
|
|
462 (let [expr' (if (and (coll? expr) (not (instance? ConsCell expr)))
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 3 forms covered">
|
|
463 (make-beowulf-list expr)
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
464 expr)]
|
|
</span><br/>
|
|
<span class="covered" title="5 out of 5 forms covered">
|
|
465 (EVAL expr' NIL 0)))
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
466 ([expr env depth]
|
|
</span><br/>
|
|
<span class="covered" title="9 out of 9 forms covered">
|
|
467 (trace-call 'EVAL (list expr env depth) depth)
|
|
</span><br/>
|
|
<span class="partial" title="6 out of 7 forms covered">
|
|
468 (let [result (cond
|
|
</span><br/>
|
|
<span class="covered" title="4 out of 4 forms covered">
|
|
469 (= NIL expr) NIL ;; it was probably a mistake to make Lisp
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
470 ;; NIL distinct from Clojure nil
|
|
</span><br/>
|
|
<span class="covered" title="6 out of 6 forms covered">
|
|
471 (= (NUMBERP expr) T) expr
|
|
</span><br/>
|
|
<span class="covered" title="8 out of 8 forms covered">
|
|
472 (symbol? expr) (eval-symbolic expr env depth)
|
|
</span><br/>
|
|
<span class="partial" title="3 out of 7 forms covered">
|
|
473 (string? expr) (if (:strict *options*)
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 1 forms covered">
|
|
474 (throw
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 2 forms covered">
|
|
475 (ex-info
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 5 forms covered">
|
|
476 (str "EVAL: strings not allowed in strict mode: \"" expr "\"")
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 6 forms covered">
|
|
477 {:phase :eval
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
478 :detail :strict
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 1 forms covered">
|
|
479 :expr expr}))
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 3 forms covered">
|
|
480 (symbol expr))
|
|
</span><br/>
|
|
<span class="covered" title="12 out of 12 forms covered">
|
|
481 (= (ATOM (CAR expr)) T) (case (CAR expr)
|
|
</span><br/>
|
|
<span class="covered" title="7 out of 7 forms covered">
|
|
482 COND (EVCON (CDR expr) env depth)
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 6 forms covered">
|
|
483 FUNCTION (LIST 'FUNARG (CADR expr))
|
|
</span><br/>
|
|
<span class="covered" title="7 out of 7 forms covered">
|
|
484 PROG (PROG (CDR expr) env depth)
|
|
</span><br/>
|
|
<span class="covered" title="3 out of 3 forms covered">
|
|
485 QUOTE (CADR expr)
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
486 ;; else
|
|
</span><br/>
|
|
<span class="covered" title="2 out of 2 forms covered">
|
|
487 (APPLY
|
|
</span><br/>
|
|
<span class="covered" title="3 out of 3 forms covered">
|
|
488 (CAR expr)
|
|
</span><br/>
|
|
<span class="covered" title="7 out of 7 forms covered">
|
|
489 (EVLIS (CDR expr) env depth)
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
490 env
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
491 depth))
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 16 forms covered">
|
|
492 :else (EVAL (CONS (CDR (SASSOC (CAR expr) env (fn [] (ERROR 'A9))))
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 3 forms covered">
|
|
493 (CDR expr))
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 1 forms covered">
|
|
494 env
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 2 forms covered">
|
|
495 (inc depth)))]
|
|
</span><br/>
|
|
<span class="covered" title="5 out of 5 forms covered">
|
|
496 (trace-response 'EVAL result depth)
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
497 result)))
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
498
|
|
</span><br/>
|
|
</body>
|
|
</html>
|