最近花了点时间做了个 Brainfuck 编译器,编译后的程序用 C# 的类型来表达。
比如这是一个编译出来的 Hello World 的 Brainfuck 程序:
AddData<Int<Hex0, Hex0, Hex0, Hex0, Hex0, Hex0, Hex0, Hex8>,Loop<AddPointer<Int<Hex0, Hex0, Hex0, Hex0, Hex0, Hex0, Hex0, Hex1>, AddData<Int<Hex0, Hex0, Hex0, Hex0, Hex0, Hex0, Hex0, Hex4>, Loop<AddPointer<Int<Hex0, Hex0, Hex0, Hex0, Hex0, Hex0, Hex0, Hex1>, AddData<Int<Hex0, Hex0, Hex0, Hex0, Hex0, Hex0, Hex0, Hex2>, AddPointer<Int<Hex0, Hex0, Hex0, Hex0, Hex0, Hex0, Hex0, Hex1>, AddData<Int<Hex0, Hex0, Hex0, Hex0, Hex0, Hex0, Hex0, Hex3>, AddPointer<Int<Hex0, Hex0, Hex0, Hex0, Hex0, Hex0, Hex0, Hex1>, AddData<Int<Hex0, Hex0, Hex0, Hex0, Hex0, Hex0, Hex0, Hex3>, AddPointer<Int<Hex0, Hex0, Hex0, Hex0, Hex0, Hex0, Hex0, Hex1>, AddData<Int<Hex0, Hex0, Hex0, Hex0, Hex0, Hex0, Hex0, Hex1>, AddPointer<Int<HexF, HexF, HexF, HexF, HexF, HexF, HexF, HexC>, AddData<Int<HexF, HexF, HexF, HexF, HexF, HexF, HexF, HexF>, Stop>>>>>>>>>>, AddPointer<Int<Hex0, Hex0, Hex0, Hex0, Hex0, Hex0, Hex0, Hex1>, AddData<Int<Hex0, Hex0, Hex0, Hex0, Hex0, Hex0, Hex0, Hex1>, AddPointer<Int<Hex0, Hex0, Hex0, Hex0, Hex0, Hex0, Hex0, Hex1>, AddData<Int<Hex0, Hex0, Hex0, Hex0, Hex0, Hex0, Hex0, Hex1>, AddPointer<Int<Hex0, Hex0, Hex0, Hex0, Hex0, Hex0, Hex0, Hex1>, AddData<Int<HexF, HexF, HexF, HexF, HexF, HexF, HexF, HexF>, AddPointer<Int<Hex0, Hex0, Hex0, Hex0, Hex0, Hex0, Hex0, Hex2>, AddData<Int<Hex0, Hex0, Hex0, Hex0, Hex0, Hex0, Hex0, Hex1>, Loop<AddPointer<Int<HexF, HexF, HexF, HexF, HexF, HexF, HexF, HexF>, Stop>, AddPointer<Int<HexF, HexF, HexF, HexF, HexF, HexF, HexF, HexF>, AddData<Int<HexF, HexF, HexF, HexF, HexF, HexF, HexF, HexF>, Stop>>>>>>>>>>>>>>, AddPointer<Int<Hex0, Hex0, Hex0, Hex0, Hex0, Hex0, Hex0, Hex2>, OutputData<AddPointer<Int<Hex0, Hex0, Hex0, Hex0, Hex0, Hex0, Hex0, Hex1>, AddData<Int<HexF, HexF, HexF, HexF, HexF, HexF, HexF, HexD>, OutputData<AddData<Int<Hex0, Hex0, Hex0, Hex0, Hex0, Hex0, Hex0, Hex7>, OutputData<OutputData<AddData<Int<Hex0, Hex0, Hex0, Hex0, Hex0, Hex0, Hex0, Hex3>, OutputData<AddPointer<Int<Hex0, Hex0, Hex0, Hex0, Hex0, Hex0, Hex0, Hex2>, OutputData<AddPointer<Int<HexF, HexF, HexF, HexF, HexF, HexF, HexF, HexF>, AddData<Int<HexF, HexF, HexF, HexF, HexF, HexF, HexF, HexF>, OutputData<AddPointer<Int<HexF, HexF, HexF, HexF, HexF, HexF, HexF, HexF>, OutputData<AddData<Int<Hex0, Hex0, Hex0, Hex0, Hex0, Hex0, Hex0, Hex3>, OutputData<AddData<Int<HexF, HexF, HexF, HexF, HexF, HexF, HexF, HexA>, OutputData<AddData<Int<HexF, HexF, HexF, HexF, HexF, HexF, HexF, Hex8>, OutputData<AddPointer<Int<Hex0, Hex0, Hex0, Hex0, Hex0, Hex0, Hex0, Hex2>, AddData<Int<Hex0, Hex0, Hex0, Hex0, Hex0, Hex0, Hex0, Hex1>, OutputData<AddPointer<Int<Hex0, Hex0, Hex0, Hex0, Hex0, Hex0, Hex0, Hex1>, AddData<Int<Hex0, Hex0, Hex0, Hex0, Hex0, Hex0, Hex0, Hex2>, OutputData<Stop>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
然后可以直接运行这个程序输出 Hello World!
:
<前面那一大串类型>.Run(0, stackalloc byte[16], Console.OpenStandardInput(), Console.OpenStandardOutput());
性能出乎意料的不错,尤其是经过 NativeAOT 编译出独立可执行文件后,跑 Mandelbrot 甚至超过了先把 Brainfuck 代码翻译到 C 后再用 clang -O3 -march=native
编译出来的程序的性能。
项目 | 执行时间(毫秒) | 排名 | 比例 |
---|---|---|---|
C 解释器 | 4874.6587 | 5 | 5.59 |
GCC | 901.0225 | 3 | 1.03 |
Clang | 881.7177 | 2 | 1.01 |
.NET JIT | 925.1596 | 4 | 1.06 |
.NET AOT | 872.2287 | 1 | 1.00 |
项目地址: https://github.com/hez2010/Brainfly
一些介绍: https://zhuanlan.zhihu.com/p/20878662768
欢迎点 star !
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.