1

我有一些 s 表达式(let ((whatever (foo (bar 4) (bar 5)))) ...)(作为 的结果(read "(whatever (foo (bar 4) (bar 5)))")。现在我想用一个自定义宏来转换它,例如扩展为foo宏表达式。

将宏应用于给定 S 表达式的机制是什么?请注意,我不希望这种替换发生在 .scm 文件的编译时,而是在读取 s 表达式之后发生。

此外,我不想使用 eval,因为这些 S-Expressions 不是 Scheme 代码。我不想let在给定的 s 表达式中扩展语句,只有foo.

基本上,我认为 Scheme 将包含一个足够灵活的树转换框架,使我能够随时使用特定的宏来操作任何类型的 S 表达式。然而,与此同时,我了解到 Scheme 的宏不是一流的对象,不能以这种方式使用,正如 Sylwester 所暗示的那样。

4

1 回答 1

2

我想你想扩展数据并最终得到数据。如果不是这种情况,请使用更多信息更新您的问题。

您需要运行自己的宏实现。假设您使用宏创建make-macro并扩展它们,expand-macros这样只会扩展您用户定义的宏。

那么解决方案是: (let ((whatever (expand-macros (read)))) ...)

您可以查看很多宏实现。Alexpander是基于卫生语法规则的,而经典的 unygenic defmacro + 扩展器将非常容易。但是,如果完全安全,那将是不可能的。想象一下你的foo

(let ((foo +))
  (foo 5 6))

这应该覆盖您foolet. 要解决此问题,您的扩展器需要了解您将要使用的 Scheme 的所有语言结构,并且能够理解它的绑定可能会被隐藏。总而言之,您几乎需要它作为 Scheme 的解释器才能看到要扩展或不扩展的内容。这并不容易,但它是可行的。

于 2013-09-01T16:27:56.437 回答