feat: compiler-path IFn dispatch via jolt-call (vector/map/set/keyword/record callable in :compile? mode); fix compiled set literals (->make-phs) and char consts
This commit is contained in:
parent
b0cb3afbf2
commit
7dbccb60c0
4 changed files with 41 additions and 3 deletions
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
(use ./types)
|
||||
(use ./core)
|
||||
(use ./phm)
|
||||
|
||||
(def- core-renames
|
||||
@{"+" "core-+"
|
||||
|
|
@ -504,7 +505,12 @@
|
|||
{:op :vector :items items})
|
||||
|
||||
(struct? form)
|
||||
{:op :map :form form}
|
||||
(cond
|
||||
(= :jolt/set (form :jolt/type))
|
||||
{:op :set :items (map |(analyze-form $ bindings ctx) (form :value))}
|
||||
(= :jolt/char (form :jolt/type))
|
||||
{:op :const :val form}
|
||||
{:op :map :form form})
|
||||
|
||||
{:op :const :val form}))
|
||||
|
||||
|
|
@ -642,6 +648,11 @@
|
|||
|
||||
(defn- emit-map-str [form buf] (buffer/push buf (string form)))
|
||||
|
||||
(defn- emit-set-str [items buf]
|
||||
(buffer/push buf "(make-phs")
|
||||
(each it items (buffer/push buf " ") (emit-ast it buf))
|
||||
(buffer/push buf ")"))
|
||||
|
||||
(defn- raw-form->janet
|
||||
"Convert a Jolt reader form to a Janet data structure for quoting."
|
||||
[form]
|
||||
|
|
@ -689,6 +700,7 @@
|
|||
:invoke (emit-invoke-str (ast :fn) (ast :args) buf)
|
||||
:vector (emit-vector-str (ast :items) buf)
|
||||
:map (emit-map-str (ast :form) buf)
|
||||
:set (emit-set-str (ast :items) buf)
|
||||
:quote (emit-quote-str (ast :expr) buf)
|
||||
(buffer/push buf (string "/* unhandled op: " (ast :op) " */")))))
|
||||
|
||||
|
|
@ -779,7 +791,9 @@
|
|||
(tuple/slice (tuple ;exprs)))
|
||||
|
||||
(defn- emit-invoke-expr [f-ast args]
|
||||
(def exprs @[(emit-expr f-ast)])
|
||||
# Embed the jolt-call function value directly (like core symbols) so compiled
|
||||
# invocations dispatch real fns AND IFn collections at runtime.
|
||||
(def exprs @[jolt-call (emit-expr f-ast)])
|
||||
(each arg args (array/push exprs (emit-expr arg)))
|
||||
(tuple/slice (tuple ;exprs)))
|
||||
|
||||
|
|
@ -790,6 +804,9 @@
|
|||
|
||||
(defn- emit-map-expr [form] form)
|
||||
|
||||
(defn- emit-set-expr [items]
|
||||
(tuple/slice (tuple make-phs ;(map emit-expr items))))
|
||||
|
||||
(defn- emit-quote-expr [expr]
|
||||
['quote (raw-form->janet expr)])
|
||||
|
||||
|
|
@ -813,6 +830,7 @@
|
|||
:invoke (emit-invoke-expr (ast :fn) (ast :args))
|
||||
:vector (emit-vector-expr (ast :items))
|
||||
:map (emit-map-expr (ast :form))
|
||||
:set (emit-set-expr (ast :items))
|
||||
:quote (emit-quote-expr (ast :expr))
|
||||
(error (string "Unhandled op: " (ast :op))))))
|
||||
|
||||
|
|
|
|||
|
|
@ -255,6 +255,25 @@
|
|||
(in m k)
|
||||
default))))))
|
||||
|
||||
# Runtime invoke dispatch for COMPILED code (interpreter uses evaluator's
|
||||
# jolt-invoke). Handles real functions plus Clojure IFn collections.
|
||||
(defn jolt-call [f & args]
|
||||
(cond
|
||||
(or (function? f) (cfunction? f)) (apply f args)
|
||||
(keyword? f) (core-get (get args 0) f (get args 1))
|
||||
(and (struct? f) (= :symbol (f :jolt/type))) (core-get (get args 0) f (get args 1))
|
||||
(phm? f) (phm-get f (get args 0) (get args 1))
|
||||
(set? f) (if (phs-contains? f (get args 0)) (get args 0) (get args 1))
|
||||
(or (tuple? f) (array? f))
|
||||
(let [k (get args 0)]
|
||||
(if (and (number? k) (= k (math/floor k)) (>= k 0) (< k (length f)))
|
||||
(in f k)
|
||||
(error (string "Index " k " out of bounds for vector of length " (length f)))))
|
||||
(or (struct? f) (and (table? f) (get f :jolt/deftype)))
|
||||
(let [v (get f (get args 0) :jolt/not-found)]
|
||||
(if (= v :jolt/not-found) (get args 1) v))
|
||||
(error (string "Cannot call " (type f) " as a function"))))
|
||||
|
||||
(defn core-get-in [m ks &opt default]
|
||||
(default default nil)
|
||||
(var current m)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue