Reputation: 38721
Given:
(define-syntax (test stx)
(syntax-case stx ()
[(_ body ...)
(with-syntax ([body0 (process-body #'(body ...))])
#'body0)]))
How should I receive the pattern and the ellipses in the helper? I'm not even sure if wrapping the body ... inside () is correct, but I've seen it around and it's the only thing that doesn't crash.
The process-body procedure ends up with syntax that has extra () wrapping it. I can try and break this apart, but I'm just wondering what the correct way to do this is.
process-body wraps the body pattern with some code before AND after. And, similar to define, I want to be able to provide the macro with multiple forms rather than all forms in one list. So, if given (form1) (form2), where form2 is the ellipses, process-body should (do-something) (form1) (form2) (do-something-else).
ie,
(define-for-syntax (process-body body-syntax)
(with-syntax ([stx body-syntax])
(syntax/loc body-syntax
(λ (request)
stx))))
Of course I have this working when I define the template in-line, and I suppose I could do that here, but sometimes the template becomes unwieldy and it's nice to call a helper.
Thanks a lot.
As an edit to try dyoo's first example, I'm providing the following:
#lang racket
(define-syntax (test2 stx)
(syntax-case stx ()
[(_ body ...)
(with-syntax ([(body0 ...) (process-body2 #'(body ...))])
#'(begin body0 ...))]))
(define-for-syntax (process-body2 bodies)
(with-syntax ([(body ...) bodies])
(syntax/loc bodies
(λ (request)
body ...))))
(test2 (print "hi"))
λ: bad syntax
Upvotes: 4
Views: 967
Reputation: 12003
The left hand side of a with-syntax
pattern can also have ellipses, so that the following is possible:
(define-syntax (test stx)
(syntax-case stx ()
[(_ body ...)
(with-syntax ([(body0 ...) (process-body #'(body ...))])
#'(begin body0 ...))]))
The basic idea is that if process-body
returns the transformed body elements, we can then introduce them all together with a begin
.
Your process-body
definition can also use with-syntax
with ellipses too. So you can do something like this:
(define-for-syntax (process-body bodies)
(with-syntax ([(body ...) bodies])
(syntax/loc bodies
(λ (request)
body ...))))
If that's the definition of process-body
, we should amend test
since the shape of the result from process-body
is now a complete lambda expression, so we can just return its result directly:
(define-syntax (test stx)
(syntax-case stx ()
[(_ body ...)
(process-body (syntax/loc stx (body ...)))]))
As a self-contained example:
#lang racket
(define-syntax (test stx)
(syntax-case stx ()
[(_ body ...)
(process-body
(syntax/loc stx (body ...)))]))
(define-for-syntax (process-body bodies)
(with-syntax ([(body ...) bodies])
(syntax/loc bodies
(λ (request)
(printf "before the body\n")
body ...
(printf "after the body\n")))))
;; Let's try it:
(define p
(test (displayln "hello") (displayln "world")))
(p 'should-be-a-request)
Upvotes: 4