我需要使用 defmacro 实现 my_let*,其工作方式与 let* 类似,但是当 let* 扩展为一系列嵌套的 let 调用(在幕后)时,my_let* 需要扩展到单个let调用,并使用define语句来定义我得到的参数。
使用 my_let* 的示例:
(my_let* ((a 2)
(b 3)
(c (+ a b)))
(+ a b c))
这段代码的返回值应该是10。就像使用let*一样。 上面的代码将在 my_let* 中扩展为以下内容:
(let ()
(define a 2)
(define b 3)
(define c (+ a b))
(+ a b c))
我是使用宏的新手,虽然我成功编写了一些宏,但这个让我迷失了。
预先感谢您。
最佳答案
使用语法解析
。至少不要考虑在 Racket 中使用 defmacro
。
#lang racket
(require (for-syntax syntax/parse))
(define-syntax (my-let* stx)
(syntax-parse stx
[(_my-let* ([name:id e:expr] ...) body ...)
#'(let ()
(define name e) ...
body ...)]))
name:id
表示 name
必须是标识符,e:expr
表示
e
必须是一个表达式。这些简单的注释有助于语法分析
为您提供更好的错误消息。
示例:
(my-let* ((4 2)
(b 3)
(c (+ a b)))
(+ a b c))
这里 DrRacket 将为 4 个读数着色并给出消息:
my-let*: expected identifier in: 4
关于macros - Racket - 使用宏实现 let* 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43985964/