compile (set! *var* val)
The analyzer punted set! as uncompilable. Add it as a special form: (set! sym val) on a var emits jolt-var-set, which updates the innermost thread binding (or the root when unbound), returning val. A local target (deftype mutable field) or an interop (.-field) target stays uncompilable for now. Also defines *warn-on-reflection* (false) so set! on it resolves. SCI load 186 -> 196/218.
This commit is contained in:
parent
86aa89c832
commit
e6ee17b055
6 changed files with 53 additions and 36 deletions
|
|
@ -34,7 +34,7 @@
|
|||
|
||||
(def ^:private handled
|
||||
#{"quote" "if" "do" "def" "fn*" "let*" "loop*" "recur" "throw" "try"
|
||||
"syntax-quote" "var" "letfn"})
|
||||
"syntax-quote" "var" "letfn" "set!"})
|
||||
|
||||
(defn- uncompilable [why]
|
||||
(throw (str "jolt/uncompilable: " why)))
|
||||
|
|
@ -323,6 +323,16 @@
|
|||
(if (= :var (:kind r))
|
||||
(the-var (:ns r) (:name r))
|
||||
(uncompilable (str "var of non-var " (form-sym-name sym)))))
|
||||
;; (set! *var* val): set the var's innermost thread binding, else its root
|
||||
;; (jolt-var-set). A local target is a deftype mutable field — not yet
|
||||
;; supported (jolt binds fields immutably); an interop (.-field) target too.
|
||||
"set!" (let [target (nth items 1)]
|
||||
(when-not (form-sym? target) (uncompilable "set! of a non-symbol target"))
|
||||
(when (local? env (form-sym-name target)) (uncompilable "set! of a local"))
|
||||
(let [r (resolve-global ctx target)]
|
||||
(when-not (= :var (:kind r)) (uncompilable "set! of a non-var"))
|
||||
{:op :set-var :the-var (the-var (:ns r) (:name r))
|
||||
:val (analyze ctx (nth items 2) env)}))
|
||||
(uncompilable (str "special form " op))))
|
||||
|
||||
;; Host interop method call (jolt-0kf5). `(.method target arg*)` — a head that
|
||||
|
|
|
|||
|
|
@ -377,6 +377,8 @@
|
|||
"` (no core on Chez yet)") {}))
|
||||
:else (str "(var-deref " (chez-str-lit (:ns node)) " " (chez-str-lit (:name node)) ")")))
|
||||
:the-var (str "(jolt-var " (chez-str-lit (:ns node)) " " (chez-str-lit (:name node)) ")")
|
||||
;; (set! *var* val) -> set the var's innermost binding (else root); returns val.
|
||||
:set-var (str "(jolt-var-set " (emit (:the-var node)) " " (emit (:val node)) ")")
|
||||
:host (throw (ex-info (str "emit: unsupported host ref `" (:name node) "`") {}))
|
||||
:host-static (str "(host-static-ref " (chez-str-lit (:class node)) " "
|
||||
(chez-str-lit (:member node)) ")")
|
||||
|
|
|
|||
|
|
@ -96,6 +96,7 @@
|
|||
(= op :do) (assoc node :statements (mapv f (get node :statements))
|
||||
:ret (f (get node :ret)))
|
||||
(= op :throw) (assoc node :expr (f (get node :expr)))
|
||||
(= op :set-var) (assoc node :val (f (get node :val)))
|
||||
(= op :invoke) (assoc node :fn (f (get node :fn))
|
||||
:args (mapv f (get node :args)))
|
||||
(= op :vector) (assoc node :items (mapv f (get node :items)))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue