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:
@@ -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)))))
|
||||
|
||||
Reference in New Issue
Block a user