为什么Befunge被认为很难编译



Befunge的设计目标之一是难以编译。然而,它很容易解释。人们可以用传统语言编写解释器,比如C。要将Befunge程序翻译成等效的机器代码,可以将Befunge代码硬编码到C解释器中,并将生成的C程序编译成机器代码。还是"编译"意味着更受限制的东西,排除了这个翻译?

要将Befunge程序翻译成等效的机器代码,可以将Befung代码硬编码到C解释器中,并将生成的C程序编译成机器代码。

是的,当然。这可以应用于任何解释器,无论是否是深奥的语言,在某些定义下,这可以称为编译器。

但在Befunge的上下文中,这不是"编译"的意思——我认为称之为"编译器"在很大程度上忽略了编译的意义,即将某些(高级)语言中的代码转换为其他(低级)语言中语义等效的代码。这里没有进行这样的转换。

根据这个定义,Befunge确实是一种很难以这种方式转换的语言,因为给定一条指令,在编译时很难知道下一条指令是什么

Befunge由于p而无法真正进行AOT编译。就JIT而言,与所有那些动态语言相比,这只是小菜一碟。我研究过一些快速实现。

marsh通过成为一个线程解释器而获得了它的速度。为了加快指令调度,它必须为每个方向创建4个解释器副本。我优化边界检查&通过将程序存储在80x32空间而不是80x25空间中进行查找

bejit是我观察到的,程序的大部分时间都花在了移动上。bejit在解释时记录跟踪,&如果同一位置在同一方向上被击中,我们将跳转到跟踪记录的内部字节码格式。当p对我们已经跟踪的程序源执行写入时,我们丢弃所有跟踪&返回口译员。在实践中,它执行mandel.bf之类的东西的速度要快3倍。它还开启了窥视孔优化,示踪剂可以应用恒定传播。这在Befunge中特别有用,因为常数是由多个指令建立的

我的python实现在执行之前编译整个程序,因为python函数的字节码是不可变的。这开启了整个程序分析的可能性

funge.py将befunge指令跟踪到CPython字节码中。由于CPython不处理堆栈下溢,因此它必须在堆栈顶部保留一个int来跟踪堆栈高度。我最初希望创建一个通用的python字节码优化器,但我最终意识到,用一个没有跳转偏移的中间格式进行优化会更有效。此外,数组比链表快的常见建议在CPython中并不适用,因为数组是指针数组&一个链表只会把这些指针分散开来。所以我创建了funge2.py

(wfunge.py是为http://bugs.python.org/issue26647)

funge2.py将指令跟踪到控制流图中。不幸的是,我们没有得到JVM&CIL需求,因此优化有点困难。funge2.py进行恒定折叠、循环展开、一些堆栈深度跟踪以减少堆栈深度检查,&我正在添加更多(跳跃到跳跃优化,更智能的堆栈深度杂耍,而不是跳跃或跳跃弹出或重复跳跃组合)

当funge2优化Befunge时,它是一个非常简单的IR

  1. 负载常量
  2. binop(+,-,*,/,%,>)
  3. 不是
  4. pop
  5. dup
  6. 掉期
  7. printint/printchar/printstr(当常量折叠使这些具有确定性时的最后一个)
  8. getint/getchar
  9. 自述
  10. writemem
  11. 跳跃
  12. 跳跃
  13. 出口

编译似乎并不那么困难

Befunge由于使用pg命令而难以编译。有了这些,您可以在运行时放置和获取命令,即编写自更改代码。

无法将其直接转换为程序集,更不用说二进制代码了。

如果您将Befunge程序嵌入到解释器代码中并对其进行编译,那么您仍然在编译解释器,而不是Befunge程序。。。

相关内容

  • 没有找到相关文章

最新更新