scheme: Phase 2 evaluator — env.sx third consumer + 23 tests [consumes-env]
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 25s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 25s
lib/scheme/eval.sx — R7RS evaluator skeleton: - Self-evaluating: numbers, booleans, characters, vectors, strings - Symbol lookup: refl-env-lookup - Lists: syntactic-operator table dispatch, else applicative call - Table-driven syntactic ops (Phase 2 wires `quote` only; full set in Phase 3) - Apply: callable host fn or scheme closure (closure stub for Phase 3) scheme-make-env / scheme-env-bind! / etc. are THIN ALIASES for the refl-env-* primitives from lib/guest/reflective/env.sx. No adapter cfg needed — Scheme's lexical-scope semantics ARE the canonical wire shape. This is the THIRD CONSUMER for env.sx after Kernel and Tcl + Smalltalk's variant adapters; the first to use it without any bridging code. Validates the kit handles canonical-shape adoption with zero ceremony. 23 tests in lib/scheme/tests/eval.sx cover literals, symbol lookup with parent-chain shadowing, quote (special form + sugar), primitive application with nested calls, and an env-as-value section explicitly demonstrating the kit primitives work on Scheme envs. 85 total Scheme tests (62 parse + 23 eval). chisel: consumes-env (third consumer for lib/guest/reflective/env.sx).
This commit is contained in:
162
lib/scheme/tests/eval.sx
Normal file
162
lib/scheme/tests/eval.sx
Normal file
@@ -0,0 +1,162 @@
|
||||
;; lib/scheme/tests/eval.sx — exercises lib/scheme/eval.sx (Phase 2).
|
||||
|
||||
(define scm-eval-pass 0)
|
||||
(define scm-eval-fail 0)
|
||||
(define scm-eval-fails (list))
|
||||
|
||||
(define
|
||||
scm-eval-test
|
||||
(fn
|
||||
(name actual expected)
|
||||
(if
|
||||
(= actual expected)
|
||||
(set! scm-eval-pass (+ scm-eval-pass 1))
|
||||
(begin
|
||||
(set! scm-eval-fail (+ scm-eval-fail 1))
|
||||
(append! scm-eval-fails {:name name :actual actual :expected expected})))))
|
||||
|
||||
(define scm-eval-src (fn (src env) (scheme-eval (scheme-parse src) env)))
|
||||
|
||||
;; A toy env with arithmetic + list primitives.
|
||||
(define
|
||||
scm-test-env
|
||||
(fn
|
||||
()
|
||||
(let
|
||||
((env (scheme-make-env)))
|
||||
(scheme-env-bind!
|
||||
env
|
||||
"+"
|
||||
(fn (args) (+ (first args) (nth args 1))))
|
||||
(scheme-env-bind!
|
||||
env
|
||||
"-"
|
||||
(fn (args) (- (first args) (nth args 1))))
|
||||
(scheme-env-bind!
|
||||
env
|
||||
"*"
|
||||
(fn (args) (* (first args) (nth args 1))))
|
||||
(scheme-env-bind! env "list" (fn (args) args))
|
||||
env)))
|
||||
|
||||
;; ── self-evaluating ──────────────────────────────────────────────
|
||||
(scm-eval-test
|
||||
"lit: integer"
|
||||
(scm-eval-src "42" (scheme-make-env))
|
||||
42)
|
||||
(scm-eval-test "lit: float" (scm-eval-src "3.14" (scheme-make-env)) 3.14)
|
||||
(scm-eval-test "lit: #t" (scm-eval-src "#t" (scheme-make-env)) true)
|
||||
(scm-eval-test "lit: #f" (scm-eval-src "#f" (scheme-make-env)) false)
|
||||
(scm-eval-test
|
||||
"lit: empty list"
|
||||
(scm-eval-src "()" (scheme-make-env))
|
||||
(list))
|
||||
(scm-eval-test
|
||||
"lit: string"
|
||||
(scheme-string? (scm-eval-src "\"hello\"" (scheme-make-env)))
|
||||
true)
|
||||
(scm-eval-test
|
||||
"lit: char"
|
||||
(scheme-char? (scm-eval-src "#\\a" (scheme-make-env)))
|
||||
true)
|
||||
(scm-eval-test
|
||||
"lit: vector"
|
||||
(scheme-vector? (scm-eval-src "#(1 2 3)" (scheme-make-env)))
|
||||
true)
|
||||
|
||||
;; ── symbol lookup ────────────────────────────────────────────────
|
||||
(scm-eval-test
|
||||
"sym: bound"
|
||||
(let
|
||||
((env (scheme-make-env)))
|
||||
(scheme-env-bind! env "x" 100)
|
||||
(scm-eval-src "x" env))
|
||||
100)
|
||||
(scm-eval-test
|
||||
"sym: parent chain"
|
||||
(let
|
||||
((p (scheme-make-env)))
|
||||
(scheme-env-bind! p "outer" 1)
|
||||
(let
|
||||
((c (scheme-extend-env p)))
|
||||
(scheme-env-bind! c "inner" 2)
|
||||
(+ (scm-eval-src "outer" c) (scm-eval-src "inner" c))))
|
||||
3)
|
||||
(scm-eval-test
|
||||
"sym: shadowing"
|
||||
(let
|
||||
((p (scheme-make-env)))
|
||||
(scheme-env-bind! p "x" 1)
|
||||
(let
|
||||
((c (scheme-extend-env p)))
|
||||
(scheme-env-bind! c "x" 2)
|
||||
(scm-eval-src "x" c)))
|
||||
2)
|
||||
|
||||
;; ── quote ────────────────────────────────────────────────────────
|
||||
(scm-eval-test
|
||||
"quote: symbol"
|
||||
(scm-eval-src "(quote foo)" (scheme-make-env))
|
||||
"foo")
|
||||
(scm-eval-test
|
||||
"quote: list"
|
||||
(scm-eval-src "(quote (+ 1 2))" (scheme-make-env))
|
||||
(list "+" 1 2))
|
||||
(scm-eval-test "quote: sugar 'x" (scm-eval-src "'x" (scheme-make-env)) "x")
|
||||
(scm-eval-test
|
||||
"quote: sugar list"
|
||||
(scm-eval-src "'(a b c)" (scheme-make-env))
|
||||
(list "a" "b" "c"))
|
||||
(scm-eval-test
|
||||
"quote: nested"
|
||||
(scm-eval-src "''x" (scheme-make-env))
|
||||
(list "quote" "x"))
|
||||
|
||||
;; ── primitive application ────────────────────────────────────────
|
||||
(scm-eval-test "prim: +" (scm-eval-src "(+ 2 3)" (scm-test-env)) 5)
|
||||
(scm-eval-test
|
||||
"prim: nested +"
|
||||
(scm-eval-src "(+ (+ 1 2) (+ 3 4))" (scm-test-env))
|
||||
10)
|
||||
(scm-eval-test
|
||||
"prim: mixed ops"
|
||||
(scm-eval-src "(- (* 4 5) (+ 3 2))" (scm-test-env))
|
||||
15)
|
||||
(scm-eval-test
|
||||
"prim: list builds SX list"
|
||||
(scm-eval-src "(list 1 2 3)" (scm-test-env))
|
||||
(list 1 2 3))
|
||||
(scm-eval-test
|
||||
"prim: args eval in order"
|
||||
(let
|
||||
((env (scm-test-env)))
|
||||
(scheme-env-bind! env "a" 10)
|
||||
(scheme-env-bind! env "b" 20)
|
||||
(scm-eval-src "(+ a b)" env))
|
||||
30)
|
||||
|
||||
;; ── env-as-value (the third-consumer demonstration) ─────────────
|
||||
;; Scheme's env IS lib/guest/reflective/env.sx's canonical wire shape
|
||||
;; with no adapter cfg. Verify the kit primitives work directly.
|
||||
(scm-eval-test
|
||||
"env: refl-env? on Scheme env"
|
||||
(refl-env? (scheme-make-env))
|
||||
true)
|
||||
(scm-eval-test
|
||||
"env: lookup via kit"
|
||||
(let
|
||||
((env (scheme-make-env)))
|
||||
(refl-env-bind! env "name" "scheme")
|
||||
(refl-env-lookup env "name"))
|
||||
"scheme")
|
||||
(scm-eval-test
|
||||
"env: find-frame walks parent"
|
||||
(let
|
||||
((p (scheme-make-env)))
|
||||
(refl-env-bind! p "root-binding" 99)
|
||||
(let
|
||||
((c (scheme-extend-env p)))
|
||||
(= (refl-env-find-frame c "root-binding") p)))
|
||||
true)
|
||||
|
||||
(define scm-eval-tests-run! (fn () {:total (+ scm-eval-pass scm-eval-fail) :passed scm-eval-pass :failed scm-eval-fail :fails scm-eval-fails}))
|
||||
Reference in New Issue
Block a user