为什么Befunge被认为难以编译?

时间:2014-01-05 16:11:45

标签: compilation interpreted-language esoteric-languages befunge

Befunge的设计目标之一是难以编译。但是,它很容易解释。人们可以用传统语言编写解释器,例如C.要将Befunge程序转换为等效的机器代码,可以将Befunge代码硬编码到C解释器中,并将生成的C程序编译为机器代码。或者"编译"意味着更多限制,不包括这个翻译?

3 个答案:

答案 0 :(得分:1)

  

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

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

但这并不是Befunge上下文中“编译”的含义 - 而且我认为将其称为“编译器”非常缺乏编译点,即将代码转换为某些内容(更高)语言与其他(较低)语言中的语义等效代码。这里没有进行这样的转换。

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

答案 1 :(得分:1)

由于p,Befunge无法真正进行AOT编译。就JIT而言,与所有那些动态语言相比,它是一个很好的蛋糕。 I've worked on some fast implementations.

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

bejit我观察到大部分计划时间花在了四处走动上。 bejit记录其解释的痕迹,&如果在同一方向上击中相同的位置,我们跳转到跟踪记录的内部字节码格式。当p执行我们已追踪的程序源上的写入时,我们会删除所有跟踪&回到口译员。在实践中,这会比mandel.bf快3倍。它还开启了窥视孔优化,其中示踪剂可以应用恒定传播。这在Befunge中特别有用,因为常量是由多个指令构建的

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

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

wfunge.py是funge.py的一个端口,准备http://bugs.python.org/issue26647

funge2.py将指令跟踪到控制流程图中。不幸的是,我们无法进行JVM和JVM的静态堆栈调整。 CIL需求,因此优化有点困难。 funge2.py执行常量折叠,循环展开,一些堆栈深度跟踪以减少堆栈深度检查,&我正在添加更多(跳转到跳转优化,更智能的堆栈深度杂耍,不跳转或跳转或跳转组合)

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

  1. load const
  2. binop(+, - ,*,/,%,>)
  3. 弹出
  4. DUP
  5. 交换
  6. printint / printchar / printstr(常量折叠使得这些确定性的最后一个)
  7. getint /的getchar
  8. readmem
  9. writemem
  10. jumprand
  11. jumpif
  12. 出口
  13. 编译似乎很难

答案 2 :(得分:-1)

由于pg命令,Befunge很难编译。有了这些,您可以在运行时放入和获取命令,即编写自我修改代码。

你无法直接将它转换为汇编,更不用说二进制代码了。

如果你将Befunge程序嵌入到解释器代码中并编译它,你仍在编译解释器,而不是Befunge程序......