Sorry, your browser cannot access this site
This page requires browser support (enable) JavaScript
Learn more >

Brainfuck是一门经典的深奥编程语言(Esolang, Esoteric Programming Language),由Urban Müller于 1993 年创造。它以极简的语法和指令集著称,仅由少数基本指令构成,但仍然具备图灵完备性。

Basics

Brainfuck的原理其实非常简单。它是基于

  • 1个以字节为单位、已初始化为零的数组

  • 1个指向该数组的指针(开始时指向数组的第一个字节)

  • 2个用于输入输出的两个字节流

  • 以及8个指令

指令 作用
> 指针递增,向右移动一格
< 指针递减,向左移动一格
+ 将指针当前位置的字节值加1然后取mod 256
- 将指针当前位置的字节值减1然后取mod 256
. 将指针当前位置的字节输出到 stdout
, stdin 读取一个字节,并写入指针当前位置
[ 如果指针当前位置的值为 0,则向后跳转到匹配的];否则执行下一条指令
] 如果指针当前位置的值不为 0,则向前跳转到匹配的[;否则执行下一条指令

实现的。

例子

Hello World:

1
++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.

解释器 Intepreter

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#include <stdint.h>
#include <stddef.h>

/*
* Brainfuck 解释器的运行状态
*/
struct BFState {
/*
* array_len 表示数组长度
* array 指向 Brainfuck 使用的数据数组开头
*/
size_t array_len;
uint8_t* array;

/*
* cur 指向当前正在操作的数组位置
* 必须满足:array <= cur < array + array_len
*/
uint8_t* cur;
};

/*
* state:
* 指向 Brainfuck 解释器的状态。
* 其中包含数据数组、数组长度,以及当前数据指针 cur。
*
* program:
* 指向需要执行的 Brainfuck 程序字符串。
* 字符串以 '\0' 结尾,非 Brainfuck 指令字符会被忽略。
*
* 返回值:
* 成功执行完整个程序返回 0;
* 如果发生数组越界或括号匹配错误,返回 -1。
*/
int brainfuck(struct BFState* state, const char* program) {
const char* pc = program;

while (*pc != '\0') {
switch (*pc) {
case '>':
if (state->cur + 1 >= state->array + state->array_len) {
return -1;
}
state->cur++;
break;

case '<':
if (state->cur == state->array) {
return -1;
}
state->cur--;
break;

case '+':
(*state->cur)++;
break;

case '-':
(*state->cur)--;
break;

case '.':
putchar(*state->cur);
break;

case ',':
int c = getchar();
if (c == EOF) return -1;
*state->cur = (uint8_t)c;
break;

case '[':
if (*state->cur == 0) {
int n = 1;
pc++;

while (*pc != '\0') {
if (*pc == '[') {
n++;
} else if (*pc == ']') {
n--;
}
if (n == 0) {
break;
}
pc++;
}
if (*pc == '\0') {
return -1;
}
}
break;

case ']':
if (*state->cur != 0) {
int n = -1;

if (pc == program) {
return -1;
}
pc--;

while (1) {
if (*pc == '[') {
n++;
} else if (*pc == ']') {
n--;
}
if (n == 0) {
break;
}
if (pc == program) {
return -1;
}
pc--;
}
}
break;

default:
break;
}
pc++;
}
return 0;
}