My monster, it lives!
I'm not confident this is yet tidy, so I'm not yet closing the feature branch - but it's working.
This commit is contained in:
		
							parent
							
								
									5b5ddb9444
								
							
						
					
					
						commit
						20b8f45db1
					
				
					 3 changed files with 176 additions and 122 deletions
				
			
		| 
						 | 
					@ -9,10 +9,9 @@
 | 
				
			||||||
  ALLUPPERCASE are Lisp 1.5 functions (although written in Clojure) and that
 | 
					  ALLUPPERCASE are Lisp 1.5 functions (although written in Clojure) and that
 | 
				
			||||||
  therefore all arguments must be numbers, symbols or `beowulf.cons_cell.ConsCell`
 | 
					  therefore all arguments must be numbers, symbols or `beowulf.cons_cell.ConsCell`
 | 
				
			||||||
  objects."
 | 
					  objects."
 | 
				
			||||||
  (:require [beowulf.cons-cell :refer [make-cons-cell T]]
 | 
					  (:require [beowulf.cons-cell :refer [make-beowulf-list make-cons-cell T]]
 | 
				
			||||||
            [beowulf.host :refer [ATOM CAAR CADAR CADDR CADR CAR CDR GET LIST
 | 
					            [beowulf.host :refer [ASSOC ATOM CAAR CADAR CADDR CADR CAR CDR GET
 | 
				
			||||||
                                  NUMBERP PAIRLIS traced?]]
 | 
					                                  LIST NUMBERP PAIRLIS traced?]]
 | 
				
			||||||
            [beowulf.interop :refer [to-clojure]]
 | 
					 | 
				
			||||||
            [beowulf.oblist :refer [*options* NIL oblist]])
 | 
					            [beowulf.oblist :refer [*options* NIL oblist]])
 | 
				
			||||||
  (:import [beowulf.cons_cell ConsCell]
 | 
					  (:import [beowulf.cons_cell ConsCell]
 | 
				
			||||||
           [clojure.lang Symbol]))
 | 
					           [clojure.lang Symbol]))
 | 
				
			||||||
| 
						 | 
					@ -39,51 +38,67 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(declare APPLY EVAL)
 | 
					(declare APPLY EVAL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(defmacro QUOTE
 | 
					(defn try-resolve-subroutine
 | 
				
			||||||
  "Quote, but in upper case for LISP 1.5"
 | 
					  "Attempt to resolve this `subr` with these `arg`."
 | 
				
			||||||
  [f]
 | 
					  [subr args]
 | 
				
			||||||
  `(quote ~f))
 | 
					  (when (and subr (not= subr NIL))
 | 
				
			||||||
 | 
					    (try @(resolve subr)
 | 
				
			||||||
 | 
					         (catch Throwable any
 | 
				
			||||||
 | 
					           (throw (ex-info "Failed to resolve subroutine"
 | 
				
			||||||
 | 
					                           {:phase :apply
 | 
				
			||||||
 | 
					                            :function subr
 | 
				
			||||||
 | 
					                            :args args
 | 
				
			||||||
 | 
					                            :type :beowulf}
 | 
				
			||||||
 | 
					                           any))))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(defn- traced-apply
 | 
					(defn- trace-call
 | 
				
			||||||
  "Like `APPLY`, but with trace output to console."
 | 
					  "Show a trace of a call to the function named by this `function-symbol` 
 | 
				
			||||||
  [function-symbol args lisp-fn environment depth]
 | 
					  with these `args` at this depth."
 | 
				
			||||||
 | 
					  [function-symbol args depth]
 | 
				
			||||||
 | 
					  (when (traced? function-symbol)
 | 
				
			||||||
    (let [indent (apply str (repeat depth "-"))]
 | 
					    (let [indent (apply str (repeat depth "-"))]
 | 
				
			||||||
    (println (str indent "> " function-symbol " " args))
 | 
					      (println (str indent "> " function-symbol " " args)))))
 | 
				
			||||||
    (let [r (APPLY lisp-fn args environment depth)]
 | 
					 | 
				
			||||||
      (println (str "<" indent " " r))
 | 
					 | 
				
			||||||
      r)))
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
(defn- safe-apply
 | 
					(defn- trace-response
 | 
				
			||||||
  "We've a real problem with varargs functions when `args` is `NIL`, because
 | 
					  "Show a trace of this `response` from the function named by this
 | 
				
			||||||
   Clojure does not see `NIL` as an empty sequence."
 | 
					   `function-symbol` at this depth."
 | 
				
			||||||
  [clj-fn args]
 | 
					  [function-symbol response depth]
 | 
				
			||||||
  (let [args' (when (instance? ConsCell args) args)]
 | 
					  (when (traced? function-symbol)
 | 
				
			||||||
    (apply clj-fn args')))
 | 
					    (let [indent (apply str (repeat depth "-"))]
 | 
				
			||||||
 | 
					      (println (str "<" indent " " function-symbol " " response))))
 | 
				
			||||||
 | 
					  response)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(defn- value
 | 
				
			||||||
 | 
					  "Seek a value for this symbol `s` by checking each of these indicators in
 | 
				
			||||||
 | 
					   turn."
 | 
				
			||||||
 | 
					  ([s]
 | 
				
			||||||
 | 
					   (value s (list 'APVAL 'EXPR 'FEXPR 'SUBR 'FSUBR)))
 | 
				
			||||||
 | 
					  ([s indicators]
 | 
				
			||||||
 | 
					   (when (symbol? s)
 | 
				
			||||||
 | 
					     (first (remove #(= % NIL) (map #(GET s %)
 | 
				
			||||||
 | 
					                                    indicators))))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(defn- apply-symbolic
 | 
					(defn- apply-symbolic
 | 
				
			||||||
  "Apply this `funtion-symbol` to these `args` in this `environment` and 
 | 
					  "Apply this `funtion-symbol` to these `args` in this `environment` and 
 | 
				
			||||||
   return the result."
 | 
					   return the result."
 | 
				
			||||||
  [^Symbol function-symbol args ^ConsCell environment depth]
 | 
					  [^Symbol function-symbol args ^ConsCell environment depth]
 | 
				
			||||||
  (let [lisp-fn (try (EVAL function-symbol environment depth)
 | 
					  (trace-call function-symbol args depth)
 | 
				
			||||||
                     (catch Throwable any (when (:trace *options*)
 | 
					  (let [lisp-fn ;; (try 
 | 
				
			||||||
                                            (println any))))]
 | 
					        (value function-symbol '(EXPR FEXPR))
 | 
				
			||||||
    (if (and lisp-fn
 | 
					                    ;; (catch Exception any (when (traced? function-symbol)
 | 
				
			||||||
             (not= lisp-fn NIL)) (if (traced? function-symbol)
 | 
					                    ;;                        (println any))))
 | 
				
			||||||
                                   (traced-apply function-symbol
 | 
					        subr (value function-symbol '(SUBR FSUBR))
 | 
				
			||||||
                                                 args
 | 
					        host-fn (try-resolve-subroutine subr args)
 | 
				
			||||||
                                                 lisp-fn
 | 
					        result (cond (and lisp-fn
 | 
				
			||||||
                                                 environment
 | 
					                          (not= lisp-fn NIL)) (APPLY lisp-fn args environment depth)
 | 
				
			||||||
                                                 depth)
 | 
					                     host-fn (apply host-fn (when (instance? ConsCell args) args))
 | 
				
			||||||
                                   (APPLY lisp-fn args environment depth))
 | 
					                     :else (ex-info "No function found"
 | 
				
			||||||
        (if function-symbol
 | 
					                                    {:phase :apply
 | 
				
			||||||
          (let [f (GET function-symbol 'SUBR)]
 | 
					 | 
				
			||||||
            (when f
 | 
					 | 
				
			||||||
              (apply @(resolve f) (to-clojure args))))
 | 
					 | 
				
			||||||
        ;; else
 | 
					 | 
				
			||||||
          (ex-info "No function found"
 | 
					 | 
				
			||||||
                   {:context "APPLY"
 | 
					 | 
				
			||||||
                                     :function function-symbol
 | 
					                                     :function function-symbol
 | 
				
			||||||
                    :args args})))))
 | 
					                                     :args args
 | 
				
			||||||
 | 
					                                     :type :beowulf}))]
 | 
				
			||||||
 | 
					    (trace-response function-symbol result depth)
 | 
				
			||||||
 | 
					    result))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(defn APPLY
 | 
					(defn APPLY
 | 
				
			||||||
  "Apply this `function` to these `arguments` in this `environment` and return
 | 
					  "Apply this `function` to these `arguments` in this `environment` and return
 | 
				
			||||||
| 
						 | 
					@ -93,13 +108,15 @@
 | 
				
			||||||
   All args are assumed to be symbols or `beowulf.cons-cell/ConsCell` objects.
 | 
					   All args are assumed to be symbols or `beowulf.cons-cell/ConsCell` objects.
 | 
				
			||||||
   See page 13 of the Lisp 1.5 Programmers Manual."
 | 
					   See page 13 of the Lisp 1.5 Programmers Manual."
 | 
				
			||||||
  [function args environment depth]
 | 
					  [function args environment depth]
 | 
				
			||||||
  (cond
 | 
					  (trace-call 'APPLY (list function args environment) depth)
 | 
				
			||||||
 | 
					  (let [result (cond
 | 
				
			||||||
                 (= NIL function) (if (:strict *options*)
 | 
					                 (= NIL function) (if (:strict *options*)
 | 
				
			||||||
                                    NIL
 | 
					                                    NIL
 | 
				
			||||||
                                    (throw (ex-info "NIL is not a function"
 | 
					                                    (throw (ex-info "NIL is not a function"
 | 
				
			||||||
                                       {:context "APPLY"
 | 
					                                                    {:phase :apply
 | 
				
			||||||
                                                     :function "NIL"
 | 
					                                                     :function "NIL"
 | 
				
			||||||
                                        :args args})))
 | 
					                                                     :args args
 | 
				
			||||||
 | 
					                                                     :type :beowulf})))
 | 
				
			||||||
                 (= (ATOM function) T) (apply-symbolic function args environment (inc depth))
 | 
					                 (= (ATOM function) T) (apply-symbolic function args environment (inc depth))
 | 
				
			||||||
                 :else (case (first function)
 | 
					                 :else (case (first function)
 | 
				
			||||||
                         LABEL (APPLY
 | 
					                         LABEL (APPLY
 | 
				
			||||||
| 
						 | 
					@ -119,7 +136,9 @@
 | 
				
			||||||
                                         {:phase :apply
 | 
					                                         {:phase :apply
 | 
				
			||||||
                                          :function function
 | 
					                                          :function function
 | 
				
			||||||
                                          :args args
 | 
					                                          :args args
 | 
				
			||||||
                             :type :beowulf})))))
 | 
					                                          :type :beowulf}))))]
 | 
				
			||||||
 | 
					    (trace-response 'APPLY result depth)
 | 
				
			||||||
 | 
					    result))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(defn- EVCON
 | 
					(defn- EVCON
 | 
				
			||||||
  "Inner guts of primitive COND. All `clauses` are assumed to be
 | 
					  "Inner guts of primitive COND. All `clauses` are assumed to be
 | 
				
			||||||
| 
						 | 
					@ -146,13 +165,25 @@
 | 
				
			||||||
     (EVAL (CAR args) env depth)
 | 
					     (EVAL (CAR args) env depth)
 | 
				
			||||||
     (EVLIS (CDR args) env depth))))
 | 
					     (EVLIS (CDR args) env depth))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
;; (defn- eval-symbolic [^Symbol s env]
 | 
					(defn- eval-symbolic
 | 
				
			||||||
;;   (let [binding (ASSOC s env)]
 | 
					  [expr env depth]
 | 
				
			||||||
;;     (if (= binding NIL)
 | 
					  (let [v (value expr (list 'APVAL))
 | 
				
			||||||
;;       (throw (ex-info (format "No binding for symbol `%s`" s)
 | 
					        indent (apply str (repeat depth "-"))]
 | 
				
			||||||
;;                       {:phase :eval
 | 
					    (when (traced? 'EVAL)
 | 
				
			||||||
;;                        :symbol s}))
 | 
					      (println (str indent ": EVAL: deep binding (" expr " . " (or v "nil") ")")))
 | 
				
			||||||
;;       (CDR binding))))
 | 
					    (if (and v (not= v NIL))
 | 
				
			||||||
 | 
					      v
 | 
				
			||||||
 | 
					      (let [v' (ASSOC expr env)]
 | 
				
			||||||
 | 
					        (when (traced? 'EVAL)
 | 
				
			||||||
 | 
					          (println (str indent ": EVAL: shallow binding: " (or v' "nil"))))
 | 
				
			||||||
 | 
					        (if (and v' (not= v' NIL))
 | 
				
			||||||
 | 
					          (.getCdr v')
 | 
				
			||||||
 | 
					          (throw (ex-info "No binding for symbol found"
 | 
				
			||||||
 | 
					                          {:phase :eval
 | 
				
			||||||
 | 
					                           :function 'EVAL
 | 
				
			||||||
 | 
					                           :args (list expr env depth)
 | 
				
			||||||
 | 
					                           :type :lisp
 | 
				
			||||||
 | 
					                           :code :A8})))))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(defn EVAL
 | 
					(defn EVAL
 | 
				
			||||||
  "Evaluate this `expr` and return the result. If `environment` is not passed,
 | 
					  "Evaluate this `expr` and return the result. If `environment` is not passed,
 | 
				
			||||||
| 
						 | 
					@ -160,13 +191,18 @@
 | 
				
			||||||
   argument is part of the tracing system and should not be set by user 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 `beowulf.cons-cell/ConsCell` 
 | 
					   All args are assumed to be numbers, symbols or `beowulf.cons-cell/ConsCell` 
 | 
				
			||||||
   objects."
 | 
					   objects. However, if called with just a single arg, `expr`, I'll assume it's
 | 
				
			||||||
 | 
					   being called from the Clojure REPL and will coerce the `expr` to `ConsCell`."
 | 
				
			||||||
  ([expr]
 | 
					  ([expr]
 | 
				
			||||||
   (EVAL expr @oblist 0))
 | 
					   (let [expr' (if (and (coll? expr) (not (instance? ConsCell expr)))
 | 
				
			||||||
 | 
					                 (make-beowulf-list expr)
 | 
				
			||||||
 | 
					                 expr)]
 | 
				
			||||||
 | 
					     (EVAL expr' @oblist 0)))
 | 
				
			||||||
  ([expr env depth]
 | 
					  ([expr env depth]
 | 
				
			||||||
   (cond
 | 
					   (trace-call 'EVAL (list expr env depth) depth)
 | 
				
			||||||
 | 
					   (let [result (cond
 | 
				
			||||||
                  (= (NUMBERP expr) T) expr
 | 
					                  (= (NUMBERP expr) T) expr
 | 
				
			||||||
     (symbol? expr) (GET expr 'APVAL)
 | 
					                  (symbol? expr) (eval-symbolic expr env depth)
 | 
				
			||||||
                  (string? expr) (if (:strict *options*)
 | 
					                  (string? expr) (if (:strict *options*)
 | 
				
			||||||
                                   (throw
 | 
					                                   (throw
 | 
				
			||||||
                                    (ex-info
 | 
					                                    (ex-info
 | 
				
			||||||
| 
						 | 
					@ -189,5 +225,7 @@
 | 
				
			||||||
                         (CAR expr)
 | 
					                         (CAR expr)
 | 
				
			||||||
                         (EVLIS (CDR expr) env depth)
 | 
					                         (EVLIS (CDR expr) env depth)
 | 
				
			||||||
                         env
 | 
					                         env
 | 
				
			||||||
            depth))))
 | 
					                         depth))]
 | 
				
			||||||
 | 
					     (trace-response 'EVAL result depth)
 | 
				
			||||||
 | 
					     result)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,8 +2,8 @@
 | 
				
			||||||
  "Essentially, the `-main` function and the bootstrap read-eval-print loop."
 | 
					  "Essentially, the `-main` function and the bootstrap read-eval-print loop."
 | 
				
			||||||
  (:require [beowulf.bootstrap :refer [EVAL]]
 | 
					  (:require [beowulf.bootstrap :refer [EVAL]]
 | 
				
			||||||
            [beowulf.io :refer [default-sysout SYSIN]]
 | 
					            [beowulf.io :refer [default-sysout SYSIN]]
 | 
				
			||||||
 | 
					            [beowulf.oblist :refer [*options* NIL]]
 | 
				
			||||||
            [beowulf.read :refer [READ read-from-console]]
 | 
					            [beowulf.read :refer [READ read-from-console]]
 | 
				
			||||||
            [beowulf.oblist :refer [*options* oblist]]
 | 
					 | 
				
			||||||
            [clojure.java.io :as io]
 | 
					            [clojure.java.io :as io]
 | 
				
			||||||
            [clojure.pprint :refer [pprint]]
 | 
					            [clojure.pprint :refer [pprint]]
 | 
				
			||||||
            [clojure.string :refer [trim]]
 | 
					            [clojure.string :refer [trim]]
 | 
				
			||||||
| 
						 | 
					@ -55,7 +55,7 @@
 | 
				
			||||||
(defn- re 
 | 
					(defn- re 
 | 
				
			||||||
  "Like REPL, but it isn't a loop and doesn't print."
 | 
					  "Like REPL, but it isn't a loop and doesn't print."
 | 
				
			||||||
  [input]
 | 
					  [input]
 | 
				
			||||||
  (EVAL (READ input) @oblist 0))
 | 
					  (EVAL (READ input) NIL 0))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(defn repl
 | 
					(defn repl
 | 
				
			||||||
  "Read/eval/print loop."
 | 
					  "Read/eval/print loop."
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,14 +2,12 @@
 | 
				
			||||||
  "provides Lisp 1.5 functions which can't be (or can't efficiently
 | 
					  "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
 | 
					   be) implemented in Lisp 1.5, which therefore need to be implemented in the
 | 
				
			||||||
   host language, in this case Clojure."
 | 
					   host language, in this case Clojure."
 | 
				
			||||||
  (:require [clojure.string :refer [upper-case]]
 | 
					  (:require [beowulf.cons-cell :refer [F make-beowulf-list make-cons-cell T]] ;; note hyphen - this is Clojure...
 | 
				
			||||||
            [beowulf.cons-cell :refer [F make-cons-cell make-beowulf-list
 | 
					 | 
				
			||||||
                                       pretty-print T]]
 | 
					 | 
				
			||||||
            ;; note hyphen - this is Clojure...
 | 
					 | 
				
			||||||
            [beowulf.gendoc :refer [open-doc]]
 | 
					            [beowulf.gendoc :refer [open-doc]]
 | 
				
			||||||
            [beowulf.oblist :refer [*options* oblist NIL]])
 | 
					            [beowulf.oblist :refer [*options* NIL oblist]]
 | 
				
			||||||
  (:import [beowulf.cons_cell ConsCell]
 | 
					            [clojure.set :refer [union]]
 | 
				
			||||||
           ;; note underscore - same namespace, but Java.
 | 
					            [clojure.string :refer [upper-case]])
 | 
				
			||||||
 | 
					  (:import [beowulf.cons_cell ConsCell] ;; note underscore - same namespace, but Java.
 | 
				
			||||||
           ))
 | 
					           ))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | 
					;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | 
				
			||||||
| 
						 | 
					@ -290,9 +288,20 @@
 | 
				
			||||||
   In `beowulf.host` principally because I don't yet feel confident to define
 | 
					   In `beowulf.host` principally because I don't yet feel confident to define
 | 
				
			||||||
   varargs functions in Lisp."
 | 
					   varargs functions in Lisp."
 | 
				
			||||||
  [& args]
 | 
					  [& args]
 | 
				
			||||||
  (if (empty? (filter #(or (= 'F %) (= NIL %) (nil? %)) args))
 | 
					  (cond (= NIL args) T
 | 
				
			||||||
    'T
 | 
					        (not (#{NIL F} (.getCar args))) (AND (.getCdr args))
 | 
				
			||||||
    'F))
 | 
					        :else T))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(defn OR
 | 
				
			||||||
 | 
					  "`T` if and only if at least one of my `args` evaluates to something other
 | 
				
			||||||
 | 
					  than either `F` or `NIL`, else `F`.
 | 
				
			||||||
 | 
					   
 | 
				
			||||||
 | 
					   In `beowulf.host` principally because I don't yet feel confident to define
 | 
				
			||||||
 | 
					   varargs functions in Lisp."
 | 
				
			||||||
 | 
					  [& args]
 | 
				
			||||||
 | 
					  (cond (= NIL args) F
 | 
				
			||||||
 | 
					        (not (#{NIL F} (.getCar args))) T
 | 
				
			||||||
 | 
					        :else (OR (.getCdr args))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
;;;; Operations on lists ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | 
					;;;; Operations on lists ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | 
				
			||||||
;;
 | 
					;;
 | 
				
			||||||
| 
						 | 
					@ -516,19 +525,26 @@
 | 
				
			||||||
  "Return `true` iff `s` is a symbol currently being traced, else `nil`."
 | 
					  "Return `true` iff `s` is a symbol currently being traced, else `nil`."
 | 
				
			||||||
  [s]
 | 
					  [s]
 | 
				
			||||||
  (try (contains? @traced-symbols s)
 | 
					  (try (contains? @traced-symbols s)
 | 
				
			||||||
       (catch Throwable _)))
 | 
					       (catch Throwable _ nil)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(defn TRACE
 | 
					(defn TRACE
 | 
				
			||||||
  "Add this symbol `s` to the set of symbols currently being traced. If `s`
 | 
					  "Add this `s` to the set of symbols currently being traced. If `s`
 | 
				
			||||||
   is not a symbol, does nothing."
 | 
					   is not a symbol or sequence of symbols, does nothing."
 | 
				
			||||||
  [s]
 | 
					  [s]
 | 
				
			||||||
  (when (symbol? s)
 | 
					  (swap! traced-symbols
 | 
				
			||||||
    (swap! traced-symbols #(conj % s))))
 | 
					         #(cond
 | 
				
			||||||
 | 
					            (symbol? s) (conj % s)
 | 
				
			||||||
 | 
					            (and (seq? s) (every? symbol? s)) (union % (set s))
 | 
				
			||||||
 | 
					            :else %)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(defn UNTRACE
 | 
					(defn UNTRACE
 | 
				
			||||||
 | 
					  "Remove this `s` from the set of symbols currently being traced. If `s`
 | 
				
			||||||
 | 
					   is not a symbol or sequence of symbols, does nothing."
 | 
				
			||||||
  [s]
 | 
					  [s]
 | 
				
			||||||
  (when (symbol? s)
 | 
					  (cond
 | 
				
			||||||
    (swap! traced-symbols #(set (remove (fn [x] (= s x)) %)))))
 | 
					    (symbol? s) (swap! traced-symbols #(set (remove (fn [x] (= s x)) %)))
 | 
				
			||||||
 | 
					    (and (seq? s) (every? symbol? s)) (map UNTRACE s))
 | 
				
			||||||
 | 
					  @traced-symbols)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
;;;; Extensions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | 
					;;;; Extensions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue