5 个版本
使用旧的 Rust 2015
0.5.3 | 2023年6月22日 |
---|---|
0.5.2 | 2023年6月18日 |
0.5.1 | 2020年10月10日 |
0.5.0 | 2020年7月28日 |
0.4.0 | 2020年7月3日 |
#58 in 编程语言
50 每月下载量
48KB
1K SLoC
BF 即时编译器
这是一个非常过度设计的,用 rust 编写的 BrainFuck 解释器/优化 JIT 编译器。
用法
fucker [--int] <program>
fucker (-d | --debug) <program>
fucker (-h | --help)
Options:
-h --help Show this screen.
-d --debug Display intermediate language.
--int Use an interpreter instead of the JIT compiler.
什么是 BrainFuck?
BrainFuck 是一种旨在既具有图灵完备性又易于编译的谜之编程语言。环境为程序员提供了一个 30,000 个单元的无符号字节数组和一个数据指针。只有 8 个单字符命令
+
: 将当前内存单元增加 1(带有环绕溢出)-
: 将当前内存单元减 1(带有环绕下溢)>
: 将数据指针移到下一个内存单元<
: 将数据指针移到上一个内存单元.
: 以 ASCII 字符输出当前内存单元,
: 从 stdin 读取一个 ASCII 字符[
: 如果当前内存单元为0
,则跳转到匹配的]
]
: 如果当前内存单元不为0
,则跳转到匹配的[
实现
优化
这里最直接的方法是对指令进行行程编码。在执行之前,可以组合连续的 +
、-
、>
和 <
命令。内部通过编译到一个中间语言来实现,该语言存储为一个 Instr
向量
pub struct Program {
pub data: Vec<Instr>,
}
pub enum Instr {
Incr(u8),
Decr(u8),
Next(usize),
Prev(usize),
Print,
Read,
BeginLoop(usize),
EndLoop(usize),
}
在不进行其他优化(除非你计算执行前的注释剥离)的情况下,这本身在与 BrainFuck Mandelbrot 集渲染器进行基准测试时实现了 ~3 倍的速度提升。
下一步是什么?更复杂的 BrainFuck 程序是从高级宏语言生成的。从 BrainFuck 反编译回这种语言可能使我能够执行更智能的代码。
JIT 编译
虽然无法直接阅读BrainFuck代码,但BrainFuck可能是最简单的图灵完备语言。这使得它成为探索即时编译的理想候选者。
我们定义在Instr
中的前六个指令在x86-64上实现起来相当直接。
+
:
add BYTE PTR [r10],n
其中
r10
用作数据指针n
与在Instr
枚举中Incr
持有的值相同
-
、>
和<
都同样简单。
Print
和Read
稍微复杂一些,但不需要我们自己做任何控制流。
基准测试
在mandelbrot.bf上运行。
使用Intel Core i5-3230M进行测试。
版本 | 运行时间 |
---|---|
原始解释器 | 56.824秒 |
优化解释器 | 19.055秒 |
优化即时编译 | 1.450秒 |
依赖项
~3.5–5.5MB
~95K SLoC