繁体   English   中英

编译嵌套的相互递归函数

[英]Compiling nested mutually recursive function

我正在创建一个玩具动态语言(对javascript感到痛苦),而我的实现是在DLR之上,我认为这个问题的解决方案将是非常语言/平台无关。

编译递归函数或彼此相邻的相互递归函数我没有问题。 但是编译嵌套的相互递归函数变得更加困难。

我用来测试的示例函数如下

void f(int x) {
 void g(int y) {
  if((x + y) < 100) {
   f(x + y);
  } else {
   print(x + y);
  }
 }
 g(x);
}

我认为解决这个问题的解决方案必须非常普遍(也许我错了)并且不是DLR特有的,我假设我不得不解除g的内部定义并在f之前定义它并且仍然保持闭包上下文。

闭包通常表示为组合函数指针和参数列表。 实际上,第一步是将所有嵌套函数提升到全局范围,将其环境中的任何绑定变量作为参数。 这相当于:

void _f(int x) 
{ 
  closure g = closure(_g,x);       
  call(g,x);  
}

void _g(int x, int y) 
{
  ...;
}

一旦你有'闭包'和'调用'原语,它就可以了。 在静态语言中, closure()只保留相关变量。 在动态语言中, closure()必须保持整个上下文堆栈可用,以防函数需要它。

我知道你正在创建一个动态语言,但我认为相同的原则适用于非动态语言 - 你仍然有一个符号表,你仍然需要通过多次传递处理源。

如果要在代码生成阶段之前创建语义树,这很容易。 对函数的调用指向对象(节点),该对象将包含函数的语义定义。 或者它只是一个节点(语义上)调用此函数。 由于对函数的调用不需要知道函数包含的内容,因此只需指向符号表条目的指针即可。

如果您正在进行优化(尾端递归?),那么您需要先执行两次传递,然后才能对此类优化进行分析。 对于我看到的所有编译器来说这是正常的,因为这个阶段发生在语义/词法分析之后。

我想这篇文章中的图表可以显示我正在谈论的内容(但是它有两种不同的输入语言。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM