Reputation: 796
This is the scenario: Given a pattern of the form [sym ...]
(e.g. [a b]
and [a b c d]
) I want to generate (using macros) functions that concatenate the symbols in the pattern, but also supply them as arguments. For example, [a b]
transforms to something of the form
(define (ab a b)
body)
In this post someone helps me generate the name of the function via a syntax class called signal-list
. In the following code I can match the signals
pattern variable with a pattern of the form (sig ...)
, and I can then use it to generate the desired function definition.
(define-syntax (define-something stx)
(syntax-parse stx
[(_ (signals:signal-list body ...))
(syntax-parse #'signals
[(sig ...)
#'(define (signals.concatenated-ids sig ...)
body ...)])]))
An example that matches this macro:
(define-something
([a b] 'body))
which expands to (define (ab a b) 'body)
But how do macros work if I want to generate multiple function definitions? For example:
(define-something
([a b] 'body)
([c d e] 'body))
=>
(begin (define (ab a b) 'body)
(define (cde c d e) 'body))
I can add an ellipsis in the pattern of the first syntax-parse:
(_ (signals:signal-list body ...) ...)
But then I cannot use the second syntax-parse to match against signals
because it needs an ellipsis. Is there a different way to 'de-construct' signals
so that I can use its contents as formal parameters to a function, which is compatible with using ellipses?
Upvotes: 2
Views: 68
Reputation: 222973
To directly answer your question, you can pass #'(signals ...)
(in place of your existing #'signals
) to the inner syntax-parse
invocation.
As a proof of concept, I wrote a syntax-case
version of your macro (since I don't know syntax-parse
yet). You should be able to adapt the same technique to syntax-parse
easily:
(define-syntax (define-something outerstx)
(define (make-name paramstx)
(datum->syntax outerstx
(string->symbol
(apply string-append
(map symbol->string (syntax->datum paramstx))))))
(define (make-names innerstx)
(syntax-case innerstx ()
(()
#'())
(((param ...) rest ...)
(with-syntax ((name (make-name #'(param ...)))
((next ...) (make-names #'(rest ...))))
#'(name next ...)))))
(syntax-case outerstx ()
((_ ((param ...) body ...)
...)
(with-syntax (((name ...) (make-names #'((param ...) ...))))
#'(define-values (name ...)
(values (lambda (param ...)
body ...)
...))))))
Upvotes: 2