-
-
Save anishathalye/0fca51025a70cc9af5a86e4fe796290c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#lang racket | |
(require (for-syntax syntax/parse)) | |
; a bit of an artificial example, but probably more usable | |
; than the real code I'm working with | |
(begin-for-syntax | |
(define-splicing-syntax-class field | |
(pattern [name:id component:id num:nat])) | |
(define (field->struct field-stx) | |
(syntax-parse field-stx | |
[(field:field) | |
#'(struct field.name (field.component))])) | |
; suppose I have some more of these field->foo functions | |
; to transform an individual field into something else, | |
; and for modularity, I don't want to inline all of this stuff | |
; into the define-syntax form below | |
) | |
(define-syntax (parse-fields stx) | |
(syntax-parse stx | |
[(_ field:field ...) | |
#`(begin | |
#,@(map field->struct (syntax-e #'(field ...)))) | |
])) | |
; usage | |
(parse-fields | |
[foo bar 3] | |
[baz qux 4]) | |
(define x (foo "hi")) | |
(foo-bar x) ; => "hi" |
soegaard
commented
Feb 10, 2020
This is one purpose that syntax-class attributes are designed for. You can bind attributes with #:with
or #:attr
. It's a good idea to declare a syntax class's attributes (including pattern variables, if you want to refer to them in templates elsewhere) using #:attributes
.
(begin-for-syntax
(define-splicing-syntax-class field
#:attributes (name component struct-decl)
(pattern [name:id component:id num:nat]
#:with struct-decl #'(struct name (component)))))
(define-syntax (parse-fields stx)
(syntax-parse stx
[(_ field:field ...)
#'(begin field.struct-decl ...)]))
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment