[plt-scheme] Testing procedures using local-expand
Noel Welsh wrote:
> Hello,
>
> I'm trying to test a function the uses local-expand. This is somewhat
> difficult, as I can't use local-expand outside of a transformer, so I
> have to do some hoops to setup a transformer etc. Anyway, I'm getting
> an error from my test:
>
> unet-util-test.ss:8:10: define-syntaxes: bad syntax in:
> (define-syntaxes (foo) (syntax-rules () ((foo x) (define x 1))))
>
> This is a perfectly fine expression (I can paste it into a REPL and it
> works). So can anyone enlighten me on what is going on? Code is
> below.
That doesn't necessarily mean that the term is bad, just that it doesn't
match any clause of some 'syntax-case' expression.
> First, the function under tests:
>
> ;; sort-exprs : (stx-listof stx) -> (values (listof expr) (listof expr))
> ;;
> ;; Sort a list of syntax into a list of transformer
> ;; definitions and a list of other expressions
> (define (sort-exprs exprs)
> (let loop ([exprs exprs]
> [transformers null]
> [expressions null])
> (if (null? exprs)
> (values transformers expressions)
> (let ([stx (stx-car exprs)]
> [rest (stx-cdr exprs)])
> (kernel-syntax-case
> (local-expand stx 'module (kernel-form-identifier-list))
> #f
> [(define-syntaxes (id ...) body ...)
> (loop rest (cons stx transformers) expressions)]
> [(define-values (id ...) body ...)
> (loop rest transformers (cons stx expressions))])))))
>
> The test harness:
>
> (define-for-syntax exprs
> (list #'(define-syntax foo
> (syntax-rules ()
> [(foo x) (define x 1)]))
> #'(define (bar x)
> (+ x 1))))
>
> (define-syntax (sort stx)
> (syntax-case stx ()
> [(sort)
> (with-syntax ([(transformers expressions) (sort-exprs exprs)])
> (syntax (list (quote-syntax transformers)
> (quote-syntax expressions))))]))
This works for me, if I wrap a 'begin-for-syntax' around the definition
of 'sort-exprs' above (and add requires for-syntax of syntax/stx and
syntax/kerncase and change 'values' to 'list').
If you're putting 'sort-exprs' in another module and requiring it
for-syntax, you need to add
(require (for-template scheme/base))
to the module; otherwise, it won't have the right bindings for
'define-values' and 'define-syntaxes', and the literals won't match.
Omitting that require gives you the error you reported above.
Ryan