Chez Phase 1 (increment 3h): host-interop method-call emit
(.method target arg*) now analyzes to a :host-call IR node instead of punting at analyze. The Chez back end lowers it to a jolt-host-call dispatch for the methods the RT shims (.write -> port display, .isDirectory -> file-directory?, .listFiles -> directory-list); any other method stays out of subset (clean emit-time reject, so it can't read as a compiled-but-broken corpus divergence). The Janet back end punts ALL :host-call to the interpreter, same shape as letfn: compiles on Chez, interprets on Janet, zero change to the main language. Closes the io tier's print-method defmethods and file-seq: prelude emit reach 348 -> 354/355 (50-io 20/20). The one remaining gap is the regex literal in parse-uuid (needs a regex engine on Chez; deferred). emit-test 122/122; Chez subset 672/672, 0 divergences; full gate green.
This commit is contained in:
parent
0f7d2753a8
commit
b1cdfd1c9b
9 changed files with 96 additions and 13 deletions
|
|
@ -283,6 +283,10 @@
|
|||
(defn- stdlib-var? [n]
|
||||
(and (= :var (get n :op)) (string/has-prefix? "clojure." (or (get n :ns) ""))))
|
||||
|
||||
# Host interop methods with a Chez RT shim (rt.ss jolt-host-call). A `.method`
|
||||
# call on any other method is out of subset until shimmed — keep this in sync.
|
||||
(def- supported-host-methods {"write" true "isDirectory" true "listFiles" true})
|
||||
|
||||
# jolt's comparison ops are vacuously true at arity 1 and DON'T inspect the arg
|
||||
# (so (< :kw) is true), but Scheme's < demands a number even there — special-case.
|
||||
(def- cmp1-ops {"<" true ">" true "<=" true ">=" true})
|
||||
|
|
@ -365,6 +369,18 @@
|
|||
:throw (string "(jolt-throw " (emit (get node :expr)) ")")
|
||||
:try (emit-try node)
|
||||
:quote (emit-quoted (get node :form))
|
||||
# host interop (jolt-0kf5): (.method target arg*) -> (jolt-host-call "method"
|
||||
# target arg*). Only the methods the RT dispatcher (rt.ss) actually shims are
|
||||
# IN the subset; any other method is out of subset (a clean emit-time reject,
|
||||
# like an unimplemented stdlib fn), so it doesn't masquerade as a compiled-but-
|
||||
# broken divergence. The Janet back end punts ALL :host-call to the interpreter.
|
||||
:host-call (let [m (get node :method)]
|
||||
(unless (get supported-host-methods m)
|
||||
(errorf "emit: unsupported host method `.%s` (no Chez shim yet)" m))
|
||||
(let [target (emit (get node :target))
|
||||
args (map emit (vv (get node :args)))]
|
||||
(string "(jolt-host-call " (string/format "%j" m) " "
|
||||
target (if (empty? args) "" (string " " (string/join args " "))) ")")))
|
||||
:fn (emit-fn node)
|
||||
# (def name) with no init (declare): reserve the var cell (declare-var!
|
||||
# doesn't clobber an existing root) so a forward reference resolves.
|
||||
|
|
|
|||
|
|
@ -39,6 +39,20 @@
|
|||
jolt-kw-data data
|
||||
jolt-kw-cause (if (null? more) jolt-nil (car more))))
|
||||
|
||||
;; --- host interop (jolt-0kf5) ------------------------------------------------
|
||||
;; (.method target arg*) lowers to (jolt-host-call "method" target arg*). JVM
|
||||
;; interop has no general Chez analog, but the few methods jolt-core's io tier
|
||||
;; calls map onto Chez equivalents: a writer's .write is a port display; a File's
|
||||
;; .isDirectory / .listFiles work over a path string (Chez has no File type, so
|
||||
;; file-seq's File branch is unreachable here — these keep the forms honest). An
|
||||
;; unsupported method raises rather than silently returning nil.
|
||||
(define (jolt-host-call method target . args)
|
||||
(cond
|
||||
((string=? method "write") (display (car args) target) jolt-nil)
|
||||
((string=? method "isDirectory") (if (file-directory? target) #t #f))
|
||||
((string=? method "listFiles") (list->cseq (directory-list target)))
|
||||
(else (error 'jolt-host-call (string-append "unsupported host method: ." method)))))
|
||||
|
||||
;; --- var cells: late-bound global roots (Clojure vars) -----------------------
|
||||
;; A var is a mutable cell keyed by "ns/name". A `:def` sets the root; a `:var`
|
||||
;; reference reads it at use time (late binding), so a forward/mutually-recursive
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue