From 98bf389f82c412adf1706f6bc37203e47c82f9ab Mon Sep 17 00:00:00 2001 From: Yogthos Date: Sat, 6 Jun 2026 09:48:52 -0400 Subject: [PATCH] compiler: resolve :as aliases in macro detection; fix analyzer compile-ns MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - compiler/resolve-macro now resolves :as aliases (like resolve-var), so aliased macro calls (t/is) are recognized and compiled via expansion instead of falling back. Compile-mode suite holds at 3932. - host/current-ns reads a backend-stashed :compile-ns rather than ctx-current-ns: the interpreter rebinds current-ns to a fn's defining ns while it runs, so the interpreted analyzer (defined in jolt.analyzer) would otherwise mis-resolve the user's compile ns. Fixes def/intern targeting the wrong namespace. Analyzer stays interpreted (compiling it needs qualified-ref compilation, which regresses the clojure.test shim — jolt-4xc). Self-host pipeline correct (218/218), full suite green. --- src/jolt/backend.janet | 16 +++++++++++----- src/jolt/compiler.janet | 7 ++++++- src/jolt/host_iface.janet | 6 +++++- 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/jolt/backend.janet b/src/jolt/backend.janet index c17d4f3..0958752 100644 --- a/src/jolt/backend.janet +++ b/src/jolt/backend.janet @@ -157,10 +157,10 @@ (defn- ensure-analyzer [ctx] # Load jolt.analyzer (and transitively jolt.ir) once; jolt.host is pre-installed - # by host/install! so its require is a no-op. The analyzer currently runs - # INTERPRETED — compiling it via the bootstrap is blocked by bootstrap - # miscompilation bugs on the constructs it uses (tracked); correctness is fine, - # speed is the open item. + # by host/install! so its require is a no-op. The analyzer runs INTERPRETED: + # compiling it via the bootstrap needs qualified-ref compilation, which + # regresses compile mode (the clojure.test shim breaks) — tracked in jolt-4xc. + # Correctness is unaffected (218/218 conformance); speed is the open item. (when (= 0 (length ((ctx-find-ns ctx "jolt.analyzer") :mappings))) (eval-form ctx @{} (r/parse-string "(require '[jolt.analyzer])")))) @@ -169,8 +169,14 @@ returning host-neutral IR." [ctx form] (ensure-analyzer ctx) + # Capture the real compile ns: the analyzer runs interpreted (defined in + # jolt.analyzer), and the interpreter rebinds current-ns to a fn's defining ns + # while it runs — so h/current-ns must read this instead of ctx-current-ns. + (put (ctx :env) :compile-ns (ctx-current-ns ctx)) (def av (ns-find (ctx-find-ns ctx "jolt.analyzer") "analyze")) - ((var-get av) ctx form)) + (def r ((var-get av) ctx form)) + (put (ctx :env) :compile-ns nil) + r) (defn compile-and-eval "Self-hosted compile path: analyze (portable Clojure) -> IR -> Janet -> eval. diff --git a/src/jolt/compiler.janet b/src/jolt/compiler.janet index 7cdb13b..d13536a 100644 --- a/src/jolt/compiler.janet +++ b/src/jolt/compiler.janet @@ -184,7 +184,12 @@ (let [name (sym-s :name) ns-sym (sym-s :ns)] (if ns-sym - (let [target-ns (ctx-find-ns ctx ns-sym) + # Resolve :as aliases (e.g. (t/is …) where t aliases clojure.test) so + # aliased macros are recognized as macros — matching the interpreter's + # resolve-var — rather than miscompiled as a value ref to the macro var. + (let [cur (ctx-find-ns ctx (ctx-current-ns ctx)) + aliased (ns-import-lookup cur ns-sym) + target-ns (ctx-find-ns ctx (or aliased ns-sym)) v (ns-find target-ns name)] (if (and v (var-macro? v)) v)) (let [current-ns-name (ctx-current-ns ctx) diff --git a/src/jolt/host_iface.janet b/src/jolt/host_iface.janet index eca0e65..75cccb8 100644 --- a/src/jolt/host_iface.janet +++ b/src/jolt/host_iface.janet @@ -74,7 +74,11 @@ (defn h-special? [name] (if (get special-names name) true false)) -(defn h-current-ns [ctx] (ctx-current-ns ctx)) +# The namespace being compiled. NOT ctx-current-ns directly: the interpreter +# rebinds current-ns to a fn's defining ns while that fn runs, so an interpreted +# analyzer (defined in jolt.analyzer) would otherwise see jolt.analyzer. The back +# end stashes the real compile ns in :compile-ns before invoking the analyzer. +(defn h-current-ns [ctx] (or (get (ctx :env) :compile-ns) (ctx-current-ns ctx))) (defn h-macro? [ctx sym] (let [v (resolve-var ctx @{} sym)]