scheme: Phase 7 — eval/interaction-environment/null-env + 13 tests [shapes-reflective]
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 31s

runtime.sx binds R7RS reflective primitives:
- eval EXPR ENV
- interaction-environment        — returns env captured by closure
- null-environment VERSION       — fresh empty env (ignores version)
- scheme-report-environment N    — fresh full standard env
- environment? V

interaction-environment closes over the standard env being built;
each invocation of scheme-standard-env produces a distinct
interaction env that returns ITSELF when queried — so user-side
(define name expr) inside (eval ... (interaction-environment))
persists for subsequent (eval 'name ...) lookups.

13 tests cover:
- eval over quoted forms (literal + constructed via list)
- define-then-lookup through interaction-environment
- eqv? identity of interaction-environment across calls
- sandbox semantics: eval in null-environment errors on +
- scheme-report-environment is fresh and distinct from interaction

**Second consumer for lib/guest/reflective/evaluator.sx unlocked.**
Scheme's eval/interaction-environment/null-environment triple is
the same protocol Kernel exposes via eval-applicative /
get-current-environment / make-environment. Extraction now
satisfies the two-consumer rule — same playbook as env.sx and
class-chain.sx, awaits a follow-up commit to actually extract
the kit.

270 total Scheme tests (62 + 23 + 49 + 78 + 25 + 20 + 13).
This commit is contained in:
2026-05-14 06:45:39 +00:00
parent 9a7ca54902
commit 342e1a2ccf
2 changed files with 134 additions and 0 deletions

View File

@@ -0,0 +1,100 @@
;; lib/scheme/tests/reflection.sx — Phase 7 reflective primitives.
(define scm-ref-pass 0)
(define scm-ref-fail 0)
(define scm-ref-fails (list))
(define
scm-ref-test
(fn
(name actual expected)
(if
(= actual expected)
(set! scm-ref-pass (+ scm-ref-pass 1))
(begin
(set! scm-ref-fail (+ scm-ref-fail 1))
(append! scm-ref-fails {:name name :actual actual :expected expected})))))
(define
scm-ref
(fn (src) (scheme-eval (scheme-parse src) (scheme-standard-env))))
(define
scm-ref-all
(fn
(src)
(scheme-eval-program (scheme-parse-all src) (scheme-standard-env))))
;; ── eval ─────────────────────────────────────────────────────────
(scm-ref-test
"eval: arithmetic"
(scm-ref "(eval '(+ 1 2 3) (interaction-environment))")
6)
(scm-ref-test
"eval: nested"
(scm-ref "(eval '(* (+ 1 2) (- 5 1)) (interaction-environment))")
12)
(scm-ref-test
"eval: constructed form"
(scm-ref "(eval (list '+ 10 20) (interaction-environment))")
30)
(scm-ref-test
"eval: variable reference"
(scm-ref-all "(define x 42) (eval 'x (interaction-environment))")
42)
;; ── interaction-environment ─────────────────────────────────────
(scm-ref-test
"interaction-environment: is an env"
(scm-ref "(environment? (interaction-environment))")
true)
(scm-ref-test
"interaction-environment: define persists"
(scm-ref-all
"(define ie (interaction-environment))\n (eval '(define stashed 99) ie)\n (eval 'stashed ie)")
99)
(scm-ref-test
"interaction-environment: same env across calls"
(scm-ref-all
"(define a (interaction-environment))\n (define b (interaction-environment))\n (eqv? a b)")
true)
;; ── null-environment ────────────────────────────────────────────
(scm-ref-test
"null-environment: is an env"
(scm-ref "(environment? (null-environment 7))")
true)
(scm-ref-test
"null-environment: has no + binding"
(scm-ref-all
"(define ne (null-environment 7))\n (guard (e (else 'unbound)) (eval '+ ne))")
"unbound")
;; ── scheme-report-environment ───────────────────────────────────
(scm-ref-test
"scheme-report-environment: is an env"
(scm-ref "(environment? (scheme-report-environment 7))")
true)
(scm-ref-test
"scheme-report-environment: has +"
(scm-ref "(eval '(+ 1 2) (scheme-report-environment 7))")
3)
(scm-ref-test
"scheme-report-environment: distinct from interaction"
(scm-ref-all
"(define ie (interaction-environment))\n (define re (scheme-report-environment 7))\n (eval '(define only-in-ie 1) ie)\n (guard (e (else 'unbound)) (eval 'only-in-ie re))")
"unbound")
;; ── eval with explicit env for sandboxing ──────────────────────
(scm-ref-test
"eval: sandbox with null-environment"
(scm-ref-all
"(define sandbox (null-environment 7))\n (guard (e (else 'unbound))\n (eval '(+ 1 1) sandbox))")
"unbound")
(define scm-ref-tests-run! (fn () {:total (+ scm-ref-pass scm-ref-fail) :passed scm-ref-pass :failed scm-ref-fail :fails scm-ref-fails}))