core: Stage 2 tier 6b — ns-introspection fns compile as ordinary invokes
create-ns/remove-ns/find-ns/all-ns/the-ns/ns-interns/ns-aliases/ns-imports/ ns-resolve/resolve/refer become ctx-capturing clojure.core fns (install-stateful-fns!) with evaluated-arg Clojure semantics, replacing interpreter special arms that were loose: the-ns/ns-interns/ns-aliases/ ns-imports ignored their argument (always current ns), create-ns/remove-ns/ ns-resolve took theirs unevaluated. The optional-arg forms still default to the current ns, preserving the prior 0-arg behavior. refer previously had a special-names entry but NO interpreter arm — it errored everywhere; it now refers the named ns's public vars (use-impl), :only/:exclude filters not yet honored. ns-resolve does its lookup directly: types/ns-resolve keys ns-find with the symbol struct instead of its name string and never finds anything. Removed all of them from the evaluator arms, host_iface special-names, and compiler uncompilable-heads (use/ns/require/in-ns stay punted in the bootstrap compiler — it builds analyzer.clj, whose ns forms need the interpreter). Gate: conformance 285x3 (+8 ns-fn cases), fallback-zero 62/3, fixpoint, self-host, sci, staged, suite 4049>=4034 (+2 passes), all specs+unit.
This commit is contained in:
parent
d18ca7abad
commit
b11a072ea3
5 changed files with 84 additions and 27 deletions
|
|
@ -161,16 +161,20 @@
|
||||||
# var-get/var-set/var?/alter-var-root/alter-meta!/reset-meta!/
|
# var-get/var-set/var?/alter-var-root/alter-meta!/reset-meta!/
|
||||||
# find-var/intern are plain clojure.core fns now (core-bindings +
|
# find-var/intern are plain clojure.core fns now (core-bindings +
|
||||||
# install-stateful-fns!) — ordinary invokes, no punt (Stage 2 tier 6).
|
# install-stateful-fns!) — ordinary invokes, no punt (Stage 2 tier 6).
|
||||||
|
# create-ns/remove-ns/find-ns/all-ns/the-ns/resolve/ns-resolve/
|
||||||
|
# ns-aliases/ns-imports/ns-interns are ctx-capturing core fns now
|
||||||
|
# (tier 6b) — ordinary invokes, no punt.
|
||||||
"satisfies?" "instance?" "set!" "var"
|
"satisfies?" "instance?" "set!" "var"
|
||||||
"ns" "in-ns" "require" "create-ns" "remove-ns"
|
"ns" "in-ns" "require"
|
||||||
"find-ns" "all-ns" "the-ns" "resolve"
|
|
||||||
"ns-resolve" "ns-aliases" "ns-imports" "ns-interns"
|
|
||||||
"locking" "new"
|
"locking" "new"
|
||||||
# Definitional/host macros that mutate context or build runtime
|
# Definitional/host macros that mutate context or build runtime
|
||||||
# values the emitter doesn't model.
|
# values the emitter doesn't model.
|
||||||
"defrecord" "defprotocol" "definterface" "reify" "proxy"
|
"defrecord" "defprotocol" "definterface" "reify" "proxy"
|
||||||
"extend-type" "extend-protocol" "extend" "gen-class" "import"
|
"extend-type" "extend-protocol" "extend" "gen-class" "import"
|
||||||
"use" "refer" "monitor-enter" "monitor-exit" "binding" "."
|
# refer is a ctx-capturing core fn now (tier 6b); use stays — the
|
||||||
|
# bootstrap compiles analyzer.clj/ir.clj, whose ns/use forms must
|
||||||
|
# fall back to the interpreter that expands the ns macro.
|
||||||
|
"use" "monitor-enter" "monitor-exit" "binding" "."
|
||||||
# letfn needs all its fns in scope simultaneously (mutual
|
# letfn needs all its fns in scope simultaneously (mutual
|
||||||
# recursion); the sequential let* the compiler would build can't
|
# recursion); the sequential let* the compiler would build can't
|
||||||
# express that, so interpret it.
|
# express that, so interpret it.
|
||||||
|
|
|
||||||
|
|
@ -957,6 +957,55 @@
|
||||||
(fn [ns-name sym-name &opt val]
|
(fn [ns-name sym-name &opt val]
|
||||||
(def ns (ctx-find-ns ctx (if (struct? ns-name) (ns-name :name) ns-name)))
|
(def ns (ctx-find-ns ctx (if (struct? ns-name) (ns-name :name) ns-name)))
|
||||||
(ns-intern ns (if (struct? sym-name) (sym-name :name) sym-name) val)))
|
(ns-intern ns (if (struct? sym-name) (sym-name :name) sym-name) val)))
|
||||||
|
# --- ns introspection (Stage 2 tier 6b) — evaluated-arg Clojure semantics.
|
||||||
|
# A namespace designator is an ns object (passes through) or a symbol/string
|
||||||
|
# naming one. find-ns is a pure lookup (nil when absent); create-ns creates
|
||||||
|
# (ctx-find-ns is create-on-demand). The optional-arg forms default to the
|
||||||
|
# current ns, preserving the prior 0-arg interpreter behavior.
|
||||||
|
(def ns-name-of (fn [x]
|
||||||
|
(cond
|
||||||
|
(and (struct? x) (= :symbol (x :jolt/type))) (x :name)
|
||||||
|
(string? x) x
|
||||||
|
(keyword? x) (string x)
|
||||||
|
nil)))
|
||||||
|
(def ns-of (fn [x]
|
||||||
|
(if (and (table? x) (not (nil? (x :mappings))))
|
||||||
|
x
|
||||||
|
(let [nm (ns-name-of x)]
|
||||||
|
(if nm (get (get (ctx :env) :namespaces) nm) nil)))))
|
||||||
|
(def ns-or-current (fn [x]
|
||||||
|
(if (nil? x)
|
||||||
|
(ctx-find-ns ctx (ctx-current-ns ctx))
|
||||||
|
(or (ns-of x) (error (string "No namespace: " (ns-name-of x)))))))
|
||||||
|
(ns-intern core "find-ns" (fn [x] (ns-of x)))
|
||||||
|
(ns-intern core "create-ns" (fn [x] (ctx-find-ns ctx (ns-name-of x))))
|
||||||
|
(ns-intern core "remove-ns" (fn [x] (remove-ns ctx (ns-name-of x))))
|
||||||
|
(ns-intern core "all-ns" (fn [] (all-ns ctx)))
|
||||||
|
(ns-intern core "the-ns" (fn [&opt x] (ns-or-current x)))
|
||||||
|
(ns-intern core "ns-interns" (fn [&opt x] ((ns-or-current x) :mappings)))
|
||||||
|
(ns-intern core "ns-aliases" (fn [&opt x] ((ns-or-current x) :aliases)))
|
||||||
|
(ns-intern core "ns-imports" (fn [&opt x] ((ns-or-current x) :imports)))
|
||||||
|
# (ns-resolve ns sym) -> the var or nil. Unqualified syms look in ns's own
|
||||||
|
# mappings; ns-qualified syms resolve through ns's aliases. (types/ns-resolve
|
||||||
|
# keys ns-find with the symbol struct instead of its name string, so it never
|
||||||
|
# finds anything — do the lookup here.)
|
||||||
|
(ns-intern core "ns-resolve"
|
||||||
|
(fn [ns-d sym]
|
||||||
|
(def ns (ns-or-current ns-d))
|
||||||
|
(def nm (if (struct? sym) (sym :name) (string sym)))
|
||||||
|
(def nsp (if (struct? sym) (sym :ns) nil))
|
||||||
|
(if nsp
|
||||||
|
(let [alias-ns (get (ns :aliases) nsp)]
|
||||||
|
(when alias-ns (ns-find alias-ns nm)))
|
||||||
|
(ns-find ns nm))))
|
||||||
|
(ns-intern core "resolve"
|
||||||
|
(fn [sym]
|
||||||
|
(when (and (struct? sym) (= :symbol (sym :jolt/type)))
|
||||||
|
(def r (protect (resolve-var ctx @{} sym)))
|
||||||
|
(if (r 0) (r 1) nil))))
|
||||||
|
# refer: bring another ns's public vars into the current ns. Reuses use-impl's
|
||||||
|
# refer-all behavior; the :only/:exclude/:rename filters are not yet honored.
|
||||||
|
(ns-intern core "refer" (fn [ns-sym & filters] (use-impl ctx ns-sym)))
|
||||||
core)
|
core)
|
||||||
|
|
||||||
# Dispatch a special form by its string name.
|
# Dispatch a special form by its string name.
|
||||||
|
|
@ -1105,22 +1154,11 @@
|
||||||
# special-form arm; an (ns ...) head falls through to the macro-expansion path.
|
# special-form arm; an (ns ...) head falls through to the macro-expansion path.
|
||||||
# require / in-ns are now ordinary clojure.core fns (install-stateful-fns!) —
|
# require / in-ns are now ordinary clojure.core fns (install-stateful-fns!) —
|
||||||
# no special-form arm; they compile + interpret as plain invokes.
|
# no special-form arm; they compile + interpret as plain invokes.
|
||||||
"all-ns" (all-ns ctx)
|
# all-ns/the-ns/create-ns/remove-ns/ns-interns/ns-aliases/ns-imports/
|
||||||
"the-ns" (the-ns ctx)
|
# ns-resolve/resolve/find-ns/refer are ctx-capturing clojure.core fns now
|
||||||
"create-ns" (create-ns ctx (sym-name-str (in form 1)))
|
# (install-stateful-fns!) with evaluated-arg Clojure semantics — they fall
|
||||||
"remove-ns" (remove-ns ctx (sym-name-str (in form 1)))
|
# through to the function-call default and compile as plain invokes
|
||||||
"ns-interns" (let [ns (ctx-find-ns ctx (ctx-current-ns ctx))] (ns :mappings))
|
# (Stage 2 tier 6b).
|
||||||
"ns-aliases" (let [ns (ctx-find-ns ctx (ctx-current-ns ctx))] (ns :aliases))
|
|
||||||
"ns-imports" (let [ns (ctx-find-ns ctx (ctx-current-ns ctx))] (ns :imports))
|
|
||||||
"ns-resolve" (ns-resolve (ctx-find-ns ctx (ctx-current-ns ctx)) (in form 1))
|
|
||||||
"resolve" (let [sym (eval-form ctx bindings (in form 1))]
|
|
||||||
(if (and (struct? sym) (= :symbol (sym :jolt/type)))
|
|
||||||
(let [r (protect (resolve-var ctx bindings sym))]
|
|
||||||
(if (= (r 0) true) (r 1) nil))
|
|
||||||
nil))
|
|
||||||
"find-ns" (let [sym (eval-form ctx bindings (in form 1))
|
|
||||||
nm (if (and (struct? sym) (= :symbol (sym :jolt/type))) (sym :name) (string sym))]
|
|
||||||
(get (get (ctx :env) :namespaces) nm))
|
|
||||||
"fn*" (let [# optional name: (fn* name [args] ...) / (fn* name ([args] ...)...)
|
"fn*" (let [# optional name: (fn* name [args] ...) / (fn* name ([args] ...)...)
|
||||||
named? (and (struct? (in form 1)) (= :symbol ((in form 1) :jolt/type)))
|
named? (and (struct? (in form 1)) (= :symbol ((in form 1) :jolt/type)))
|
||||||
fn-name (if named? ((in form 1) :name) nil)
|
fn-name (if named? ((in form 1) :name) nil)
|
||||||
|
|
|
||||||
|
|
@ -82,13 +82,11 @@
|
||||||
# fns (compile as plain invokes).
|
# fns (compile as plain invokes).
|
||||||
"prefer-method"
|
"prefer-method"
|
||||||
"remove-method" "remove-all-methods" "get-method" "methods"
|
"remove-method" "remove-all-methods" "get-method" "methods"
|
||||||
# ns-management forms dispatched by the interpreter (not core vars)
|
# create-ns/remove-ns/find-ns/all-ns/the-ns/resolve/ns-resolve/
|
||||||
"create-ns" "remove-ns" "find-ns" "all-ns" "the-ns" "resolve"
|
# ns-aliases/ns-imports/ns-interns/refer are ctx-capturing
|
||||||
"ns-resolve" "ns-aliases" "ns-imports" "ns-interns"
|
# clojure.core fns now (compile as plain invokes — tier 6b), like
|
||||||
# ns/require/in-ns/use/import/refer-clojure are now clojure.core
|
# ns/require/in-ns/use/import/refer-clojure before them.
|
||||||
# fns/macros (compile as plain invokes / expand to them).
|
|
||||||
"read-string" "macroexpand-1" "defonce"
|
"read-string" "macroexpand-1" "defonce"
|
||||||
"refer"
|
|
||||||
# defprotocol/extend-type/extend-protocol/reify/defrecord now expand to
|
# defprotocol/extend-type/extend-protocol/reify/defrecord now expand to
|
||||||
# plain def + protocol-dispatch/register-method/make-reified/deftype.
|
# plain def + protocol-dispatch/register-method/make-reified/deftype.
|
||||||
"gen-class"
|
"gen-class"
|
||||||
|
|
|
||||||
|
|
@ -146,6 +146,16 @@
|
||||||
["alter-var-root rest args" "11" "(do (def avr 1) (alter-var-root (var avr) + 4 6) avr)"]
|
["alter-var-root rest args" "11" "(do (def avr 1) (alter-var-root (var avr) + 4 6) avr)"]
|
||||||
["alter-meta! + meta" "7" "(do (def amv 1) (alter-meta! (var amv) assoc :k 7) (:k (meta (var amv))))"]
|
["alter-meta! + meta" "7" "(do (def amv 1) (alter-meta! (var amv) assoc :k 7) (:k (meta (var amv))))"]
|
||||||
|
|
||||||
|
### ---- ns introspection fns as ordinary invokes (Stage 2 tier 6b) ----
|
||||||
|
["find-ns + ns-name" "(quote clojure.core)" "(ns-name (find-ns (quote clojure.core)))"]
|
||||||
|
["find-ns absent" "nil" "(find-ns (quote no.such.ns))"]
|
||||||
|
["create-ns + find" "true" "(do (create-ns (quote made.ns)) (some? (find-ns (quote made.ns))))"]
|
||||||
|
["remove-ns" "nil" "(do (create-ns (quote gone.ns)) (remove-ns (quote gone.ns)) (find-ns (quote gone.ns)))"]
|
||||||
|
["the-ns of symbol" "(quote user)" "(ns-name (the-ns (quote user)))"]
|
||||||
|
["ns-resolve + call" "3" "((var-get (ns-resolve (quote clojure.core) (quote inc))) 2)"]
|
||||||
|
["resolve + call" "3" "((var-get (resolve (quote inc))) 2)"]
|
||||||
|
["resolve absent" "nil" "(resolve (quote no-such-sym-xyz))"]
|
||||||
|
|
||||||
### ---- HIGH: aliased namespace calls ----
|
### ---- HIGH: aliased namespace calls ----
|
||||||
["require :as alias" "\"1,2,3\"" "(do (require (quote [clojure.string :as s])) (s/join \",\" [1 2 3]))"]
|
["require :as alias" "\"1,2,3\"" "(do (require (quote [clojure.string :as s])) (s/join \",\" [1 2 3]))"]
|
||||||
["ns form + alias" "\"HI\"" "(do (ns my.a (:require [clojure.string :as s])) (s/upper-case \"hi\"))"]
|
["ns form + alias" "\"HI\"" "(do (ns my.a (:require [clojure.string :as s])) (s/upper-case \"hi\"))"]
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,14 @@
|
||||||
"(var-get (var map))" "(var? (var map))" "(var-set (var map) map)"
|
"(var-get (var map))" "(var? (var map))" "(var-set (var map) map)"
|
||||||
"(alter-var-root (var map) identity)" "(find-var (quote clojure.core/map))"
|
"(alter-var-root (var map) identity)" "(find-var (quote clojure.core/map))"
|
||||||
"(intern (quote user) (quote tier6-sym) 42)"
|
"(intern (quote user) (quote tier6-sym) 42)"
|
||||||
"(alter-meta! (var map) assoc :k 1)" "(reset-meta! (var map) {})"])
|
"(alter-meta! (var map) assoc :k 1)" "(reset-meta! (var map) {})"
|
||||||
|
# Stage 2 tier 6b: ns-introspection fns are ordinary invokes now
|
||||||
|
"(find-ns (quote clojure.core))" "(create-ns (quote t6.created))"
|
||||||
|
"(remove-ns (quote t6.created))" "(count (all-ns))"
|
||||||
|
"(the-ns (quote clojure.core))" "(ns-interns (quote clojure.core))"
|
||||||
|
"(ns-aliases (quote user))" "(ns-imports (quote user))"
|
||||||
|
"(ns-resolve (quote clojure.core) (quote map))" "(resolve (quote map))"
|
||||||
|
"(refer (quote clojure.string))"])
|
||||||
|
|
||||||
# --- Intentional fallback (sanity sample): these SHOULD punt to the interpreter.
|
# --- Intentional fallback (sanity sample): these SHOULD punt to the interpreter.
|
||||||
# The remaining frozen/uncompiled set keeps the harness honest in the punt
|
# The remaining frozen/uncompiled set keeps the harness honest in the punt
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue