C预处理器优化Brainfuck解释器

Tests

这是一个符合C99标准的*,仅使用C预处理器编写(和执行)的优化版Brainfuck实现。

*如果您发现任何不符合标准或未明确/未定义的内容,请提交 issue。

示例

Hello World| 输出 ---|---

#include "bf.c"
BF(,I,I,I,I,I,I,I,I,B,R,I,I,I,I,B,R,I,I,R,I,I,
  I,R,I,I,I,R,I,L,L,L,L,D,E,R,I,R,I,R,D,R,R,
  I,B,L,E,L,D,E,R,R,A,R,D,D,D,A,I,I,I,I,I,I,
  I,A,A,I,I,I,A,R,R,A,L,D,A,L,A,I,I,I,A,D,D,
  D,D,D,D,A,D,D,D,D,D,D,D,D,A,R,R,I,A,R,I,I,A)

| ``` "Hello\x20World!\n"


**乘法 (0xc*0xa)**| **输出 (0xc*0xa=0x78)**
---|---

#include "bf.c" BF((c,a),G,R,G,L,B,R,B,D,R,I,R,I,L,L,E,R, R,B,D,L,L,I,R,R,E,L,L,L,D,E,R,R,O)

|  ```
"(78)"

查看 examples.c 获取更多示例。

开始使用

由于预处理器无法区分标准的Brainfuck符号,因此此实现使用以下替代指令名称:

原始指令 | 替代指令 | 描述 ---|---|---

| R | 将磁头向右移动 < | L | 将磁头向左移动

*请注意,符号之间可能会插入额外的空格,因为我所知道的所有预处理器在S(a)b中插入空格时存在分歧,其中#define S(x) xab中有不同的token。

预处理器/编译器

如果想要获得更精细的执行时间信息,可以对 tcc 进行 tinycc.diff 补丁。 这会添加 __TIMER__ 宏,该宏会展开为执行的时间并重置计时器,因此 __TIMER__ FOO __TIMER__ 中的第二个 __TIMER__ 会展开为预处理 FOO 所花费的时间。

这是如何工作的?

如果想了解我是如何编写它的,请查看 tutorial

与类似项目进行基准测试

测试的程序也存在于 examples.c 中。

程序 | bfcpp | bfi | CPP_COMPLETE | preprocessor_brainfuck ---|---|---|---|--- Hello World | 0.020s | 0.048s | 23s | ~20 分钟 insertion sort 1 | 0.049s | 0.11s | --- | --- insertion sort 2 | 0.09s | 0.22s | --- | --- insertion sort 3 | 0.75s | 1.7s | --- | --- insertion sort 4 | 2.15s | 5.1s | --- | --- sierpinski triangle | 5.32s | 6.6s | --- | --- square numbers from 0 to 10000 | 10.90s | 11.45s | --- | --- quine | 29.62s | 283.3s | --- | ---

鸣谢

感谢 notfoundry 和 Jad Lévesque 帮助我理解预处理器元编程。 另外,感谢 bfi 提供了加法查找表的想法,并极大地激励我进一步优化我的实现。

许可

对于所有没有集成许可的文件,适用 LICENSE