diff options
| author | 2025-11-02 13:06:51 -0500 | |
|---|---|---|
| committer | 2025-11-02 13:06:51 -0500 | |
| commit | 4359571add4124b304b74e10f27dd567d0a82774 (patch) | |
| tree | 84744c1d67d820e63718d0d938716d116ecd6cb5 | |
| parent | make macro generators, test on chibi. Currently broken in CHICKEN-5 due to a ... (diff) | |
add hack to support foment and CHICKEN 5.3.0
| -rw-r--r-- | README.md | 9 | ||||
| -rw-r--r-- | cuprate.egg | 2 | ||||
| -rw-r--r-- | lib/cuprate.define-test-application.scm | 25 | ||||
| -rw-r--r-- | lib/cuprate.scm | 78 | ||||
| -rw-r--r-- | lib/cuprate.simple-define-test-application.scm | 39 | ||||
| -rw-r--r-- | lib/cuprate.sld | 17 | ||||
| -rw-r--r-- | lib/cuprate/rewriters/foment.sld | 16 | ||||
| -rw-r--r-- | tests/impl.scm | 6 | ||||
| -rw-r--r-- | tests/run.scm | 4 |
9 files changed, 143 insertions, 53 deletions
@@ -184,6 +184,15 @@ This library requires `make-parameter` and `parameterize` to work like in R7RS. Most R6RS implementations should support dynamic parameters out of the box. +The macro `define-test-application` uses the `letrec` trick to create +temporary variables in pure `syntax-rules` for use in the pattern side of +a generated `syntax-rules` macro. Some implementations, like CHICKEN 5.4.0 +(kinda) and Foment, do not work correctly with this type of macro. If +the macro doesn't work in your implementation, you will probably need +to rewrite it in a low-level macro system. (If your implementation does +not offer a low-level macro system, then bug the maintainer of your +implementation to fix hygiene in their macro expander.) + ## Instructions Per Implementation ### CHICKEN diff --git a/cuprate.egg b/cuprate.egg index 875c533..8c78f40 100644 --- a/cuprate.egg +++ b/cuprate.egg @@ -6,7 +6,7 @@ (dependencies "r7rs" "srfi-128" "srfi-146" "srfi-225") (components (extension cuprate (source "lib/cuprate.sld") - (source-dependencies "lib/cuprate.scm") + (source-dependencies "lib/cuprate.scm" "lib/cuprate.simple-define-test-application.scm") (component-dependencies cuprate.rewriters) (csc-options "-R" "r7rs" "-X" "r7rs")) (extension cuprate.rewriters diff --git a/lib/cuprate.define-test-application.scm b/lib/cuprate.define-test-application.scm new file mode 100644 index 0000000..f28eb37 --- /dev/null +++ b/lib/cuprate.define-test-application.scm @@ -0,0 +1,25 @@ +(define-syntax define-test-application + (syntax-rules () + ((_ name (args ...)) + (define-test-application "loop" name (args ...) () ())) + ((_ "loop" name ((default) args ...) (rest ...) ids) + (define-test-application "loop" name (args ...) + ((#f default) rest ...) ids)) + ((_ "loop" name (arg args ...) (rest ...) (ids ...)) + (define-test-application "loop" name (args ...) + ((arg tmp) rest ...) (tmp ids ...))) + ((_ "loop" name () stuff ids) + (define-test-application "reverse1" name stuff ids ())) + ((_ "reverse1" name (pair rest ...) ids (acc ...)) + (define-test-application "reverse1" name (rest ...) ids (pair acc ...))) + ((_ "reverse1" name () ids pairs) + (define-test-application "reverse2" name ids () pairs)) + ((_ "reverse2" name (id1 id2 ...) (acc ...) pairs) + (define-test-application "reverse2" name (id2 ...) (id1 acc ...) pairs)) + ((_ "reverse2" name () (ids ...) (pairs ...)) + (define-syntax name + (syntax-rules () + ((_ ids ...) (name #f ids ...)) + ((_ test-name ids ...) + (test-named-application test-name pairs ...))))))) + diff --git a/lib/cuprate.scm b/lib/cuprate.scm index b37afbe..8265571 100644 --- a/lib/cuprate.scm +++ b/lib/cuprate.scm @@ -306,51 +306,67 @@ ;;; Wrappers and semi-compatability with SRFI-64 ;;; ;;;;;;;;;;;; -(define-syntax define-test-application - (syntax-rules () - ((_ name (args ...)) - (define-test-application "loop" name (args ...) () ())) - ((_ "loop" name ((default) args ...) (rest ...) ids) - (define-test-application "loop" name (args ...) - ((#f default) rest ...) ids)) - ((_ "loop" name (arg args ...) (rest ...) (ids ...)) - (define-test-application "loop" name (args ...) - ((arg tmp) rest ...) (tmp ids ...))) - ((_ "loop" name () stuff ids) - (define-test-application "reverse1" name stuff ids ())) - ((_ "reverse1" name (pair rest ...) ids (acc ...)) - (define-test-application "reverse1" name (rest ...) ids (pair acc ...))) - ((_ "reverse1" name () ids pairs) - (define-test-application "reverse2" name ids () pairs)) - ((_ "reverse2" name (id1 id2 ...) (acc ...) pairs) - (define-test-application "reverse2" name (id2 ...) (id1 acc ...) pairs)) - ((_ "reverse2" name () (ids ...) (pairs ...)) - (define-syntax name - (syntax-rules ...* () - ((_ ids ...) (name #f ids ...)) - ((_ test-name ids ...) - (test-application test-name pairs ...))))))) - -(define-syntax test-application +(define-syntax test-named-application (syntax-rules () ((_ test-name (%name %expr) ...) - (test-application "generate" test-name ((%name %expr) ...) ())) + (test-named-application "generate" test-name ((%name %expr) ...) ())) ((_ "generate" test-name ((#f expr) rest ...) (acc ...)) - (test-application "generate" test-name (rest ...) ((tmp expr) acc ...))) + (test-named-application "generate" test-name (rest ...) ((tmp expr) acc ...))) ((_ "generate" test-name ((sym expr) rest ...) (acc ...)) - (test-application "generate" test-name (rest ...) + (test-named-application "generate" test-name (rest ...) ((sym (let ((tmp expr)) (test-set! (quote sym) tmp) tmp)) acc ...))) ((_ "generate" test-name () (acc ...)) - (test-application "reverse" test-name (acc ...) ())) + (test-named-application "reverse" test-name (acc ...) ())) ((_ "reverse" test-name (a b ...) (c ...)) - (test-application "reverse" test-name (b ...) (a c ...))) + (test-named-application "reverse" test-name (b ...) (a c ...))) ((_ "reverse" test-name () ((name expr) ...)) (call-as-test test-name (lambda () (let ((name expr) ...) (test-set! 'success? (name ...)))))))) +(define-syntax test-application + (syntax-rules () + ((_ test-name (%fun expr ...)) + (test-application "generate-temporaries" + test-name + 1 + (expr ...) + (tmp) + ((tmp (let ((tmp %fun)) + (test-set! 'fun tmp) + tmp))))) + ((_ "generate-temporaries" test-name n (e expr ...) (tmps ...) (bindings ...)) + (test-application "generate-temporaries" + test-name + (+ n 1) + (expr ...) + (tmp tmps ...) + ((tmp (let ((tmp e)) + (test-set! (string->symbol + (string-append + "arg-" + (number->string n))) + e))) + bindings ...))) + ((_ "generate-temporaries" test-name _ () (tmps ...) bindings) + (test-application "reverse" + test-name + (tmps ...) + () + bindings)) + ((_ "reverse" test-name (a b ...) (c ...) bindings) + (test-application "reverse" + test-name + (b ...) + (a c ...) + bindings)) + ((_ "reverse" test-name () form bindings) + (call-as-test test-name + (lambda () + (let bindings (test-set! 'success? form))))))) + (define-syntax test-body (syntax-rules () ((_ name body ...) diff --git a/lib/cuprate.simple-define-test-application.scm b/lib/cuprate.simple-define-test-application.scm new file mode 100644 index 0000000..463364a --- /dev/null +++ b/lib/cuprate.simple-define-test-application.scm @@ -0,0 +1,39 @@ +;;; Some buggy implementations do not rename temporaries on the left +;;; hand side of a syntax-rules application. This is for implementations +;;; that cannot work around this issue with a low-level mcaro system. +;;; +;;; This shim is used to support the essential cases. This can be extended +;;; to support more cases as desired. + +(define-syntax define-test-application + (syntax-rules () + ((_ name ((predicate) value)) + (define-syntax name + (syntax-rules () + ((_ tmp) (name #f tmp)) + ((_ test-name tmp) + (test-named-application test-name (#f predicate) (value tmp)))))) + ((_ name (predicate value)) + (define-syntax name + (syntax-rules () + ((_ tmp1 tmp2) (name #f tmp1 tmp2)) + ((_ test-name tmp1 tmp2) + (test-named-application test-name (predicate tmp1) (value tmp2)))))) + ((_ name ((predicate) expected actual)) + (define-syntax name + (syntax-rules () + ((_ tmp1 tmp2) (name #f tmp1 tmp2)) + ((_ test-name tmp1 tmp2) + (test-named-application test-name (#f predicate) (expected tmp1) (actual tmp2)))))) + ((_ name (predicate expected actual)) + (define-syntax name + (syntax-rules () + ((_ tmp0 tmp1 tmp2) (name #f tmp0 tmp1 tmp2)) + ((_ test-name tmp0 tmp1 tmp2) + (test-named-application test-name (predicate tmp0) (expected tmp1) (actual tmp2)))))) + ((_ name ((predicate) a1 a2 a3)) + (define-syntax name + (syntax-rules () + ((_ t1 t2 t3) (name #f t1 t2 t3)) + ((_ test-name t1 t2 t3) + (test-named-application test-name (#f predicate) (a1 t1) (a2 t2) (a3 t3))))))))
\ No newline at end of file diff --git a/lib/cuprate.sld b/lib/cuprate.sld index 41847ed..abd1bc1 100644 --- a/lib/cuprate.sld +++ b/lib/cuprate.sld @@ -20,7 +20,8 @@ default-on-exception-in-group ;; SRFI-64 style assertions call-as-test call-as-group - test-application test-body + define-test-application test-predicate test-binary + test-named-application test-application test-body define-test-application test-equal test-eqv test-eq test-approximate test-error expect-to-fail @@ -35,16 +36,16 @@ test-info? (dict unwrap-test-info set-test-info!)) (define assertion-violation error)) + (cond-expand + ((or foment chicken-5) (include "cuprate.simple-define-test-application.scm")) + (else (include "cuprate.define-test-application.scm"))) ;; Pretty printing (cond-expand (chicken (import (only (chicken pretty-print) pretty-print))) - (foment (import (srfi 166)) - (begin (define (pretty-print obj) - (show #t (pretty obj)) - (newline)))) - (chibi (import (srfi 166)) - (begin (define (pretty-print obj) - (show #t (pretty obj))))) + ((or foment chibi) (import (srfi 166)) + (begin (define (pretty-print obj) + (show #t (pretty obj)) + (newline)))) (gauche (import (scheme show)) (begin (define (pretty-print obj) (show #t (pretty obj))))) diff --git a/lib/cuprate/rewriters/foment.sld b/lib/cuprate/rewriters/foment.sld index 6f88ea5..248e2ef 100644 --- a/lib/cuprate/rewriters/foment.sld +++ b/lib/cuprate/rewriters/foment.sld @@ -7,18 +7,18 @@ (export rewriters rewrite) (begin (define (default-on-pair pair) - (cons (test-rewrite (car pair)) - (test-rewrite (cdr pair)))) + (cons (rewrite (car pair)) + (rewrite (cdr pair)))) (define (default-on-vector vec) - (vector-map test-rewrite vec)) + (vector-map rewrite vec)) (define (default-on-error error) (let ((msg (error-object-message error)) (irritants (error-object-irritants error))) - `(error (type ,(test-rewrite (error-object-type error))) - (who ,(test-rewrite (error-object-who error))) - (kind ,(test-rewrite (error-object-kind error))) - (msg ,(test-rewrite (error-object-message error))) - (irritants ,@(map test-rewrite (error-object-irritants error)))))) + `(error (type ,(rewrite (error-object-type error))) + (who ,(rewrite (error-object-who error))) + (kind ,(rewrite (error-object-kind error))) + (msg ,(rewrite (error-object-message error))) + (irritants ,@(map rewrite (error-object-irritants error)))))) (define rewriters (make-parameter `((,pair? . ,default-on-pair) (,vector? . ,default-on-vector) diff --git a/tests/impl.scm b/tests/impl.scm index 840d590..6e15c11 100644 --- a/tests/impl.scm +++ b/tests/impl.scm @@ -307,17 +307,17 @@ (test-equal "inner name stack" '("gr2" "gr1") (dict-ref (test-dto) inner-dict 'name-stack)))) -(test-group "test application" +(test-group "test named application" (test-body "true" (define dict (parameterize ((test-info silent-dict)) - (test-application "not" (not not) (arg #f)) + (test-named-application "not" (not not) (arg #f)) (test-info-dict))) (eqv? 1 (dict-ref (test-dto) dict 'passed))) (test-body "false" (define dict (parameterize ((test-info silent-dict)) - (test-application "not" (not not) (arg #t)) + (test-named-application "not" (not not) (arg #t)) (test-info-dict))) (eqv? 1 (dict-ref (test-dto) dict 'failed)))) diff --git a/tests/run.scm b/tests/run.scm index 2c0d342..7f28673 100644 --- a/tests/run.scm +++ b/tests/run.scm @@ -3,5 +3,5 @@ (else)) (import (cuprate) (srfi 225) (cuprate rewriters)) -(parameterize ((test-info (test-set 'verbose? #t))) - (include "impl.scm")) + (include "impl.scm") + |
