Scheme将宏应用于给定的S-Expression

时间:2013-09-01 12:49:34

标签: macros scheme

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

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

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

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

1 个答案:

答案 0 :(得分:2)

我认为您希望扩展数据并最终获得数据。如果情况并非如此,请通过更多信息更新您的问题。

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

然后解决方案是: (让((无论如何(expand-macros(read))))    ...)

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

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

这应该覆盖foo中带有+的let定义。要解决这个问题,你的扩展器需要知道你将要使用的Scheme的所有语言结构,并且能够理解它的绑定可能会被遮蔽。总而言之,你几乎需要它作为Scheme的翻译才能看到扩展与否。这不是那么容易,但它是可行的。