OCaml runtime: R7RS parameters, VM closure introspection, import suspension

- R7RS parameter primitives (make-parameter, parameter?, parameterize support)
- VM closure get_val introspection (vm-code, vm-upvalues, vm-name, vm-globals)
- Lazy list caching on vm_code for transpiled VM performance
- VM import suspension: check_io_suspension + resume_module for browser lazy loading
- 23 new R7RS tests (parameter-basic, parameterize-basic, syntax-rules-basic)
- Playwright bytecode-loading spec + WASM rebuild

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-04 18:48:51 +00:00
parent 2727577702
commit 4baed1853c
16 changed files with 692 additions and 178 deletions

View File

@@ -196,3 +196,176 @@
(assert (boolean=? true true))
(assert (boolean=? false false))
(assert (not (boolean=? true false)))))
(defsuite
"parameter-basic"
(deftest
"make-parameter creates parameter"
(let ((p (make-parameter 42))) (assert (parameter? p))))
(deftest
"parameter returns default value"
(let ((p (make-parameter 42))) (assert= 42 (p))))
(deftest
"parameter? false for non-parameters"
(do
(assert= false (parameter? 42))
(assert= false (parameter? "hello"))
(assert= false (parameter? (list 1 2)))))
(deftest
"two parameters are independent"
(let
((p1 (make-parameter 10)) (p2 (make-parameter 20)))
(do (assert= 10 (p1)) (assert= 20 (p2))))))
(defsuite
"parameterize-basic"
(deftest
"parameterize rebinds single parameter"
(let
((p (make-parameter 1)))
(assert= 99 (parameterize ((p 99)) (p)))))
(deftest
"parameterize restores after body"
(let
((p (make-parameter 1)))
(do (parameterize ((p 99)) (p)) (assert= 1 (p)))))
(deftest
"parameterize with multiple bindings"
(let
((p1 (make-parameter 10)) (p2 (make-parameter 20)))
(parameterize
((p1 100) (p2 200))
(do (assert= 100 (p1)) (assert= 200 (p2))))))
(deftest
"nested parameterize"
(let
((p (make-parameter 1)))
(parameterize
((p 10))
(do
(assert= 10 (p))
(parameterize ((p 100)) (assert= 100 (p)))
(assert= 10 (p))))))
(deftest
"parameterize with empty bindings"
(assert= 42 (parameterize () 42)))
(deftest
"parameterize body returns last expr"
(let
((p (make-parameter 0)))
(assert= 3 (parameterize ((p 3)) 1 2 (p))))))
(defsuite
"syntax-rules-basic"
(deftest
"simple constant pattern"
(do
(define-syntax my-const
(syntax-rules ()
((_) 42)))
(assert= 42 (my-const))))
(deftest
"pattern with variable"
(do
(define-syntax my-id
(syntax-rules ()
((_ x) x)))
(assert= 7 (my-id 7))))
(deftest
"variable in template expression"
(do
(define-syntax my-double
(syntax-rules ()
((_ x) (+ x x))))
(assert= 10 (my-double 5))))
(deftest
"multiple clauses by arity"
(do
(define-syntax my-if2
(syntax-rules ()
((_ test then) (if test then nil))
((_ test then else-expr) (if test then else-expr))))
(assert= 1 (my-if2 true 1))
(assert= 2 (my-if2 false 1 2))))
(deftest
"ellipsis collects zero-or-more"
(do
(define-syntax my-list
(syntax-rules ()
((_ x ...) (list x ...))))
(assert= (list 1 2 3) (my-list 1 2 3))
(assert= (list) (my-list))))
(deftest
"nested pattern"
(do
(define-syntax my-let1
(syntax-rules ()
((_ ((var val)) body) (let ((var val)) body))))
(assert= 10 (my-let1 ((x 10)) x))))
(deftest
"literal keyword matching"
(do
(define-syntax my-arrow
(syntax-rules (=>)
((_ x => y) (list x y))))
(assert= (list 1 2) (my-arrow 1 => 2))))
(deftest
"literal keyword no match falls through"
(do
(define-syntax my-cond
(syntax-rules (=>)
((_ x => fn-expr) (fn-expr x))
((_ x y) (list x y))))
(assert= (list 3 4) (my-cond 3 4))))
(deftest
"recursive macro with ellipsis"
(do
(define-syntax my-and
(syntax-rules ()
((_) true)
((_ e) e)
((_ e1 e2 ...) (if e1 (my-and e2 ...) false))))
(assert= true (my-and))
(assert= 5 (my-and 5))
(assert= true (my-and true true true))
(assert= false (my-and true false true))))
(deftest
"swap macro"
(do
(define-syntax my-swap!
(syntax-rules ()
((_ a b) (let ((tmp a)) (set! a b) (set! b tmp)))))
(let ((x 1) (y 2))
(my-swap! x y)
(assert= 2 x)
(assert= 1 y))))
(deftest
"when macro via syntax-rules"
(do
(define-syntax my-when
(syntax-rules ()
((_ test body ...) (if test (do body ...) nil))))
(assert= nil (my-when false 1 2 3))
(assert= 3 (my-when true 1 2 3))))
(deftest
"nested ellipsis in binding pairs"
(do
(define-syntax my-let
(syntax-rules ()
((_ ((var val) ...) body)
(let ((var val) ...) body))))
(assert= 6 (my-let ((a 1) (b 2) (c 3)) (+ a b c)))))
(deftest
"or macro with short-circuit"
(do
(define-syntax my-or
(syntax-rules ()
((_) false)
((_ e) e)
((_ e1 e2 ...)
(let ((t e1)) (if t t (my-or e2 ...))))))
(assert= false (my-or))
(assert= 42 (my-or 42))
(assert= 1 (my-or 1 2 3))
(assert= 3 (my-or false false 3))
(assert= false (my-or false false false)))))