是否有可能将类似Lisp的宏构建为命令式语言?

时间:2013-07-29 19:50:17

标签: c compiler-construction macros lisp language-design

什么阻止像C这样的语言使用Lisp宏?在编译过程的什么时候,C放弃了操纵其代码树的能力?

而且,这是否特别是解释与编译问题?

4 个答案:

答案 0 :(得分:16)

语法问题

是的,你可以在命令式语言中使用类似Lisp的宏,因为Lisp支持命令式编程。 C和Lisp中宏的主要区别在于操作源树是多么容易:

  • 在C中,有声明,声明符,语句,表达式,块,一些不同的控制结构,标签等。新的语法结构可能需要更改解析器。宏将需要构建这些数据结构。

  • 在Lisp中,只有s表达式。新的语法结构不需要更改解析器。只有一个数据结构意味着用于构造语法树的API非常简单且易于记忆。

有些语言具有更复杂的语法(如C),但它们具有强大的宏功能(如Lisp)。例如,Haskell。但是,在Haskell中编写宏的接口有点复杂,因为您需要创建和应用类型构造函数,表达式,声明,表达式等的函数,而不仅仅是列表的单个构造函数。

Haskell中宏中的模板的类型有注释:

[e| ... |] -- expression
[d| ... |] -- declaration
[t| ... |] -- type
[p| ... |] -- pattern

相比之下,Lisp宏中不需要这些字母edtp。这些在Haskell not 中是必需的,因为Haskell是强类型的,但是因为注释将解析器置于正确的状态,因此它可以使用适当的上下文解析内容。同样,Lisp语法只有一个上下文。

解释与编译

大多数语言可以同时解释,编译或同时解释。 C可以是其中之一或两者。 Lisp可以是​​其中之一或两者。宏需要编译器在编译时执行代码,这可以通过解释宏代码,或者通过编译宏然后执行它来完成。所以解释与编译实际上并不是一个问题(在几乎所有关于语言的讨论中都不是问题。)

答案 1 :(得分:2)

Rust,对于" C-like"的某些定义来说肯定是类C语言,有一个Scheme-like macro system

答案 2 :(得分:1)

Haskell已经输入了强大的宏:

http://www.haskell.org/ghc/docs/7.0.2/html/users_guide/template-haskell.html

在C的情况下,我认为它源于C的设计试图保持简单的事实,因此程序的语义易于理解(不像C ++具有允许创建DSL的许多功能)

答案 3 :(得分:1)

你可以使用一些更强大的C预处理器,例如gpp可以用作更强大的cpp替代品,同时保持与它的完全兼容。

gppcpp一样,适用于文本表示,而不适用于抽象语法树。

您可以自定义C编译器(特别是GCC):例如,通过使用MELT扩展GCC - 您可以在编译器中添加自己的内置和编译指示并更改优化。

使用MELT,您主要处理GCC内的树和Gimple内部表示。