我有一些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所暗示的那样。
答案 0 :(得分:2)
我认为您希望扩展数据并最终获得数据。如果情况并非如此,请通过更多信息更新您的问题。
您需要运行自己的宏实现。假设您使用make-macro
创建宏并使用expand-macros
展开它们,这样只会展开用户定义的宏。
然后解决方案是: (让((无论如何(expand-macros(read)))) ...)
您可以查看很多宏实现。 Alexpander是基于卫生语法规则的,而经典的unygenic defmacro +扩展器非常容易。但是,如果完全安全,就不可能做到。想象一下你的foo
:
(let ((foo +))
(foo 5 6))
这应该覆盖foo
中带有+的let
定义。要解决这个问题,你的扩展器需要知道你将要使用的Scheme的所有语言结构,并且能够理解它的绑定可能会被遮蔽。总而言之,你几乎需要它作为Scheme的翻译才能看到扩展与否。这不是那么容易,但它是可行的。