gpt4 book ai didi

macros - Racket 宏省略语法

转载 作者:行者123 更新时间:2023-12-02 07:07:18 26 4
gpt4 key购买 nike

我有一个在传递一个参数时起作用的宏,我想使用 ... 将其扩展为接受 n 个参数,但我在弄清楚语法时遇到了麻烦。

宏接受自定义语法,即 key:val key:val,或者接受过程。

例如:(3种不同的用法)

(schema-properties [(name:first-name type:string)])
(schema-properties [(name:age type:number required:#t)])
(schema-properties [(my-custom-fn arg1 arg2 arg3)])

定义:

(define-syntax (schema-properties stx)
(syntax-parse stx
[(_ [(prop:expr ...)])
(with-syntax ([prop0 (make-prop-hash #'(prop ...))])
#'(list prop0))]))

(define-for-syntax (make-prop-hash stx)
(with-syntax ([(props ...) stx])
(if (regexp-match #px":"
(symbol->string (car (syntax->datum #'(props ...)))))
#'(pairs->hash 'props ...)
#'(props ...))))

这是有效的,因为它检查 prop:expr 语法中是否存在“:”,如果存在,则将其传递给函数 (pairs->hash 'props ...),否则,它只是调用它( Prop ...)。

现在,我希望能够传入:

(schema-properties [(name:first-name type:string)
(name:last-name type:string)
(my-fn arg1 arg2 arg3)])

并以同样的方式工作。但我目前正处于省略号 hell ,我的大脑不再正常工作。

任何见解都值得赞赏。

最佳答案

建议:使用辅助函数来帮助处理嵌套。您的 schema-properties 宏知道如何处理一级嵌套,并且您希望将其应用于多个子句。这与我们处理事物列表时的原则相同:有一个助手来处理事物,然后将其应用到您的列表中。它有助于降低复杂性。

对于您的代码,我们可以这样做:

#lang racket
(require (for-syntax syntax/parse))

(define-syntax (schema-properties stx)
(syntax-parse stx
[(_ [clause ...])
(with-syntax ([(transformed-clauses ...)
(map handle-clause (syntax->list #'(clause ...)))])
#'(list transformed-clauses ...))]))


;; handle-clause: clause-stx -> stx
(define-for-syntax (handle-clause a-clause)
(syntax-parse a-clause
[(prop:expr ...)
(make-prop-hash #'(prop ...))]))


(define-for-syntax (make-prop-hash stx)
(with-syntax ([(props ...) stx])
(if (regexp-match #px":"
(symbol->string (car (syntax->datum #'(props ...)))))
#'(pairs->hash 'props ...)
#'(props ...))))


;;; Let's try it out. I don't know what your definition of pairs->hash is,
;;; but it probably looks something like this:
(define (pairs->hash . pairs)
(define ht (make-hash))
(for ([p pairs])
(match (symbol->string p)
[(regexp #px"([-\\w]+):([-\\w]+)"
(list _ key value))
(hash-set! ht key value)]))
ht)

(schema-properties [(name:first-name type:string)
(name:last-name type:string)
(list 1 2 3)])

关于macros - Racket 宏省略语法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16069434/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com