Macros 在球拍宏中使用新关键字
作为对Racket的练习,我尝试创建一个类似C的函数,接受Macros 在球拍宏中使用新关键字,macros,scheme,racket,Macros,Scheme,Racket,作为对Racket的练习,我尝试创建一个类似C的函数,接受return关键字 定义函数时宏: (require (for-syntax syntax/parse)) (define-syntax (function stx) (syntax-parse stx #:datum-literals (return) [(_ (func-id arg-id ...) body ...) #'(define (func-id arg-id ...) (c
return
关键字
定义函数时
宏:
(require (for-syntax syntax/parse))
(define-syntax (function stx)
(syntax-parse stx
#:datum-literals (return)
[(_ (func-id arg-id ...) body ...)
#'(define (func-id arg-id ...)
(call/cc (lambda (return) body ...)))]))
(require macro-debugger/expand)
(syntax->datum (expand-only
#'(function (f x) (return 100) (+ 1 x))
(list #'function)))
并使用return
语句创建函数f
:
(function (f x) (return 100) (+ 1 x))
(f 2)
我得到:
return: undefined;
cannot reference an identifier before its definition
但是,展开函数
宏:
(require (for-syntax syntax/parse))
(define-syntax (function stx)
(syntax-parse stx
#:datum-literals (return)
[(_ (func-id arg-id ...) body ...)
#'(define (func-id arg-id ...)
(call/cc (lambda (return) body ...)))]))
(require macro-debugger/expand)
(syntax->datum (expand-only
#'(function (f x) (return 100) (+ 1 x))
(list #'function)))
返回:
'(define (f x) (call/cc (lambda (return) (return 100) (+ 1 x))))
事实上:
(define (f x) (call/cc (lambda (return) (return 100) (+ 1 x))))
(f 2)
> 100
一切正常
对于我的虚拟案例,可以替换函数
定义中的模式匹配,如下所示:
[(_ (func-id arg-id ...) (return x-expr) body ...)
#'(define (func-id arg-id ...)
(call/cc (lambda (return) (return x-expr) body ...)))]
但是一般来说,return
关键字可以出现在函数体的任何地方
我该怎么做 我认为您误解了
基准文本的含义<代码>基准文本
用于模式匹配输入语法,而不是输出模板/语法
你试图做的事情不能仅仅通过重写规则来完成,因为Racket的卫生宏系统会将你的return
重命名为其他名称,以避免名称冲突
通常的方法是使用syntax参数。已经很好地解释了这一点,所以我不再在这里重复了。这似乎有效:
(require (for-syntax syntax/parse))
(require racket/stxparam)
(define-syntax-parameter return
(lambda (stx)
(raise-syntax-error (syntax-e stx) "can only be used inside aif")))
(define-syntax (function stx)
(syntax-parse stx
[(_ (func-id arg-id ...) body ...)
#'(define (func-id arg-id ...)
(call/cc (lambda (return_k)
(syntax-parameterize ([return (syntax-rules () [(_ val) (return_k val)])])
body ...))))]))
(function (f x) (return 100) (+ 1 x))
(f 2)
我想
syntax parameterize
可以通过make rename transformer
来改进,但我没有成功 我仍然无法应用make rename transformer
,无论如何,我获得了一个工作代码。看看我的答案,谢谢。我希望我需要一个参数(make rename transformer#'(return_k val))