如果Lisp源代码基本上是AST,这是否意味着Lisp宏与语言无关?

如果Lisp源代码基本上是AST,这是否意味着Lisp宏与语言无关?,lisp,metaprogramming,abstract-syntax-tree,Lisp,Metaprogramming,Abstract Syntax Tree,宏或读取器宏甚至可以遍历非LISP语言的AST并以某种方式转换它们吗?我想在自己的编译器中运行非Lisp语言,而不是Lisp编译器。这并不意味着它是不可知的。这意味着它很少进行解析。程序的结构非常类似于生成的语法树,也非常类似于数据结构 任何语言都是一棵树,所以是的。Lisp可以在解析后遍历不同语言的语法树,并对其进行转换。任何语言都可以,因为我们正在讨论将一棵树转换为一棵稍有不同的树。它们中的任何一个看起来都与原始源代码相去甚远。这就是algol语言中强大的宏失败的地方。你不能告诉程序员解释A

宏或读取器宏甚至可以遍历非LISP语言的AST并以某种方式转换它们吗?我想在自己的编译器中运行非Lisp语言,而不是Lisp编译器。这并不意味着它是不可知的。这意味着它很少进行解析。程序的结构非常类似于生成的语法树,也非常类似于数据结构

任何语言都是一棵树,所以是的。Lisp可以在解析后遍历不同语言的语法树,并对其进行转换。任何语言都可以,因为我们正在讨论将一棵树转换为一棵稍有不同的树。它们中的任何一个看起来都与原始源代码相去甚远。这就是algol语言中强大的宏失败的地方。你不能告诉程序员解释AST级别的转换,因为它对她来说是陌生的

一些algol语言,比如,有强大的宏。它们与lisp有很大不同,但它们提供了引号unquote:

macro for (init, cond, change, body)
{
  <[ 
    $init;
    def loop () : void {
      if ($cond) { $body; $change; loop() } 
      else ()
    };
    loop ()
  ]>
}
这里的神奇之处在于,除了结果是AST之外,它与字符串一样工作。此外,变量前面的$表示编译时宏函数的某种排序或替换


我想用lisp语言为algol语言编写一个编译器,而不是让它自己编写,这将是一种浪费。引导是乐趣的一半

这并不意味着它是不可知论的。这意味着它很少进行解析。程序的结构非常类似于生成的语法树,也非常类似于数据结构

任何语言都是一棵树,所以是的。Lisp可以在解析后遍历不同语言的语法树,并对其进行转换。任何语言都可以,因为我们正在讨论将一棵树转换为一棵稍有不同的树。它们中的任何一个看起来都与原始源代码相去甚远。这就是algol语言中强大的宏失败的地方。你不能告诉程序员解释AST级别的转换,因为它对她来说是陌生的

一些algol语言,比如,有强大的宏。它们与lisp有很大不同,但它们提供了引号unquote:

macro for (init, cond, change, body)
{
  <[ 
    $init;
    def loop () : void {
      if ($cond) { $body; $change; loop() } 
      else ()
    };
    loop ()
  ]>
}
这里的神奇之处在于,除了结果是AST之外,它与字符串一样工作。此外,变量前面的$表示编译时宏函数的某种排序或替换


我想用lisp语言为algol语言编写一个编译器,而不是让它自己编写,这将是一种浪费。引导是乐趣的一半

首先,大多数Lisp宏使用非Lisp语言:宏的语言:

其次,Lisp宏确实可以用于扩展结构,最终生成一些完全非Lisp语言,并在其他地方进行处理

现在一个非常常见的例子是任何一个可用的HTML生成系统,其中许多系统使用宏,最终生成文本HTML—一种结构化的计算机语言,然后最终在用户的浏览器中进行处理

如果您希望代码生成系统能够使用Lisp宏,那么简单地说,您所要做的就是以这样一种方式来实现它,即通过对Lisp表单的求值来驱动它

例如,如果您为X86制作了一个基于Lisp的汇编程序,那么将它作为一个表单进行计算,从而处理类似movl eax ebx的表达式,这样实际上就有一个调用的movl函数或宏。此评估可能需要一些上下文,例如输出应该流向的流,并且可以通过一些设置宏进行设置:

(with-x86-assembler (:output-file "foo.asm")
  (movl eax ebx))  ;; just evaluated!
这个movl东西知道由with-x86-assembler设置的环境,例如保存目标流和其他上下文的动态作用域变量

由于with-x86-assembler宏的内部只是一些需要验证的形式,因此我们可以在那里使用宏:

(defmacro save-basic-regs (base-reg)
  ^(progn (movl (ind ,base-reg) eax)     ;; movl [<reg>], eax
          (movl (ind ,base-reg 4) ebx)   ;; movl [<reg> + 4], ebx
          ...))
现在我们可以使用save-basic regs-edi和-x86-assembler。实际上,我们有一个支持宏指令的宏汇编程序


Lisp宏可用于处理某些完全非Lisp语言的AST,该语言由与读取宏无关的自定义解析器解析。没有任何东西可以阻止您编写Lisp代码来解析JavaScript语法,并生成Lisp,然后对其进行计算。然后,Lisp依赖于各种运行时支持,其中可能包括宏。一些JavaScript循环可以变成一个循环。。。窗体,它是一个宏。Lisp是该代码的AST,循环宏在宏扩展AST walk期间展开。

首先,大多数Lisp宏采用非Lisp语言:宏的语言:

其次,Lisp宏确实可以用于扩展结构,最终生成一些完全非Lisp语言,并在其他地方进行处理

现在一个非常常见的例子是任何一个可用的HTML生成系统,其中许多系统使用宏,最终生成文本HTML—一种结构化的计算机语言t hat最终在用户的浏览器中进行处理

如果您希望代码生成系统能够使用Lisp宏,那么简单地说,您所要做的就是以这样一种方式来实现它,即通过对Lisp表单的求值来驱动它

例如,如果您为X86制作了一个基于Lisp的汇编程序,那么将它作为一个表单进行计算,从而处理类似movl eax ebx的表达式,这样实际上就有一个调用的movl函数或宏。此评估可能需要一些上下文,例如输出应该流向的流,并且可以通过一些设置宏进行设置:

(with-x86-assembler (:output-file "foo.asm")
  (movl eax ebx))  ;; just evaluated!
这个movl东西知道由with-x86-assembler设置的环境,例如保存目标流和其他上下文的动态作用域变量

由于with-x86-assembler宏的内部只是一些需要验证的形式,因此我们可以在那里使用宏:

(defmacro save-basic-regs (base-reg)
  ^(progn (movl (ind ,base-reg) eax)     ;; movl [<reg>], eax
          (movl (ind ,base-reg 4) ebx)   ;; movl [<reg> + 4], ebx
          ...))
现在我们可以使用save-basic regs-edi和-x86-assembler。实际上,我们有一个支持宏指令的宏汇编程序


Lisp宏可用于处理某些完全非Lisp语言的AST,该语言由与读取宏无关的自定义解析器解析。没有任何东西可以阻止您编写Lisp代码来解析JavaScript语法,并生成Lisp,然后对其进行计算。然后,Lisp依赖于各种运行时支持,其中可能包括宏。一些JavaScript循环可以变成一个循环。。。窗体,它是一个宏。Lisp是该代码的AST,循环宏在宏扩展AST walk期间被扩展。

@DiamondFox什么让你认为Python不是Algol?如果用块替换对齐的空格,很难区分它们之间的区别。@DiamondFox为什么你认为Python不是Algol?如果用块替换对齐的空格,很难区分它们之间的区别。