[racket] ... in macro defining macros?
Hi,
I'm trying to use ... in the inner macro of a macro defining macro,
but can't figure out the right way to escape it.
Here's a minimal (pointless) example:
(require (for-syntax syntax/parse))
(define-syntax (example stx)
(syntax-parse
stx
;#:literals (...) ; Doesn't help :(
[(_ name:id)
#'(define-syntax (name stx)
(syntax-parse
stx
[(_ args ...) #'(args ...)]))]))
The goal is to have (example invisible) define a macro called
invisible that erases itself.
Any ideas? The full code I'm trying to enable follows below if you'd
like more context.
Thanks,
Nick
#lang racket
(require (for-syntax syntax/parse)
racket/splicing)
;;;
;;; Procedure Application
;;;
(define arc-nil #f)
(define-syntax (arc-#%app stx)
(syntax-parse
stx
[(_ fn:expr arg:expr)
#'(let ([efn fn])
(cond [(procedure? efn) (#%app efn arg)]
[(pair? efn) (#%app list-ref efn arg)]
[(string? efn) (#%app string-ref efn arg)]
[(hash? efn) (#%app hash-ref efn arg arc-nil)]
[else (#%app efn arg)]))]
[(_ fn:expr arg1:expr arg2:expr)
#'(let ([efn fn])
(if (hash? efn)
; Have to use the lamda in case arg2 is a function
; See hash-ref docs for more info
(#%app hash-ref fn arg1 (lambda () arg2))
(#%app fn arg1 arg2)))]
[(_ args ...)
#'(#%app args ...)]))
; This allows cross module mutation of globals
(define-syntax (declare-with-set-transformer stx)
(syntax-parse
stx
;#:literals (...) ; Doesn't help :(
[(_ var:id)
#'(declare-with-set-transformer var (gensym 'unintialized))]
[(_ var:id init-val:expr)
(let ([store-name (gensym (syntax->datum #'var))])
#`(begin
(define #,store-name init-val)
(splicing-let ([set (lambda (val)
(set! #,store-name val))])
(define-syntax var
(make-set!-transformer
(lambda (stx)
(syntax-case stx (set!)
[(set! id val) #'(set val)]
; Uses Racket's #%app, which doesn't work for arc
[(id . args) #'(#,store-name . args)] ; function application
; Obviously invalid syntax
;[(id . args) #'(arc-#%app #,store-name . args)]
; Errors because ... isn't recognized as a literal
;[(id args ...) #'(arc-#%app #,store-name args ...)]
[id (identifier? #'id) #'#,store-name])))))))]))
; Demo of what I'm looking for
(define test (make-hash))
(hash-set! test 'key 'value)
(displayln (arc-#%app test 'key))
; Example of what doesn't work right now
(declare-with-set-transformer test2 (make-hash))
(hash-set! test2 'key 'value)
(displayln (test2 'key))