feat(compile): Phase 1 — wire shared persistent env (compile mode now works across forms)
Compile mode was broken: compiled defns interned only into the jolt namespace, which Janet's eval couldn't see, so calling a compiled function threw 'unknown symbol'. And load-string ignored :compile? entirely. - Each context gets a persistent Janet env (ctx-janet-env), a child of the compiler module env (so core-* resolve) holding the context's user defs. compile-and-eval evals into it, so def/defn persist and resolve across forms; contexts stay isolated. nil ctx (one-off eval) gets a fresh child. - Emit a named fn for defn ((def f (fn f [..] (f ..)))) so recursion resolves lexically (the anonymous form couldn't forward-reference f at compile time). - Extract eval-one (per-form routing) and use it in both eval-string and load-string, so load-string honors :compile?. Stateful forms still interpret. compiled fib(30): ~50s (interpreted) -> 3.4s (~15x). spec: compile-mode-test gains cross-form/recursion/def + context-isolation cases. jpm test green. Fast operator emission (the rest of the win) is Phase 2.
This commit is contained in:
parent
b6e66e53d2
commit
f74af5dbc5
3 changed files with 90 additions and 40 deletions
|
|
@ -77,6 +77,23 @@
|
|||
|
||||
(print " complex...")
|
||||
(assert (= 6 (ct-eval ctx "(let [f (fn [n] (loop [i 0 acc 0] (if (< i n) (recur (inc i) (+ acc i)) acc)))] (f 4))")) "nested")
|
||||
(assert (= 15 (ct-eval ctx "(reduce + (map inc [0 1 2 3 4]))")) "reduce+map"))
|
||||
(assert (= 15 (ct-eval ctx "(reduce + (map inc [0 1 2 3 4]))")) "reduce+map")
|
||||
|
||||
# Phase 1 wiring: compiled defns persist across forms (the per-context Janet
|
||||
# env) and recurse correctly (named-fn self-reference).
|
||||
(print " cross-form defns + recursion...")
|
||||
(eval-string ctx "(defn fib [n] (if (< n 2) n (+ (fib (- n 1)) (fib (- n 2)))))")
|
||||
(assert (= 832040 (ct-eval ctx "(fib 30)")) "recursive fib across forms")
|
||||
(eval-string ctx "(defn sq [x] (* x x))")
|
||||
(eval-string ctx "(defn sum-sq [a b] (+ (sq a) (sq b)))")
|
||||
(assert (= 25 (ct-eval ctx "(sum-sq 3 4)")) "defn calling earlier defn")
|
||||
(eval-string ctx "(def base 100)")
|
||||
(assert (= 142 (ct-eval ctx "(+ base 42)")) "compiled def referenced later"))
|
||||
|
||||
# Context isolation: a def in one compiled context is invisible in another.
|
||||
(let [a (init {:compile? true}) b (init {:compile? true})]
|
||||
(eval-string a "(def secret 7)")
|
||||
(assert (= 7 (ct-eval a "secret")) "def visible in its own ctx")
|
||||
(assert (not ((protect (ct-eval b "secret")) 0)) "def isolated to its ctx"))
|
||||
|
||||
(print "\nAll Phase 6 tests passed!")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue