5

Befunge 的设计目标之一是难以编译。但是,它很容易解释。可以用传统语言编写解释器,比如 C。要将 Befunge 程序翻译成等效的机器代码,可以将 Befunge 代码硬编码到 C 解释器中,然后将生成的 C 程序编译为机器代码。或者“编译”是否意味着排除这种翻译的更受限制的东西?

4

3 回答 3

2

由于p. 就 JIT 而言,与现有的所有动态语言相比,这简直是小菜一碟。我致力于一些快速的实现。

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

bejit我观察到大部分程序时间都花在了四处走动上。bejit在解释时记录跟踪,如果在同一方向上击中相同位置,我们将跳转到跟踪记录的内部字节码格式。当p对我们跟踪的程序源执行写入时,我们删除所有跟踪并返回到解释器。在实践中,这可以使执行mandel.bf速度提高 3 倍。它还开辟了窥视孔优化,其中示踪剂可以应用恒定传播。这在 Befunge 中特别有用,因为常量是由多条指令构建的

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

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

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

funge2.py将指令跟踪到控制流图中。不幸的是,我们没有 JVM 和 CIL 要求的静态堆栈调整,所以优化有点困难。funge2.py 进行常量折叠、循环展开、一些堆栈深度跟踪以减少堆栈深度检查,并且我正在添加更多(跳转到跳转优化、更智能的堆栈深度杂耍、不跳转或跳转弹出或 dup - 跳跃结合)

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

  1. 加载常量
  2. 二元运算(+、-、*、/、%、>)
  3. 不是
  4. 流行音乐
  5. 重复
  6. 交换
  7. printint/printchar/printstr(最后一个用于当常量折叠使这些确定性时)
  8. getint/getchar
  9. 自述文件
  10. 写内存
  11. 跳跃
  12. 跳跃
  13. 出口

这似乎并不难编译

于 2016-04-02T12:47:28.463 回答
2

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

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

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

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

于 2016-01-10T19:44:59.643 回答
0

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

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

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

于 2016-01-09T18:53:52.507 回答