BrainFuck
语言的一个官方解释器
:
BrainFuck 语言,是一种按照“ Turing complete ”思想设计的语言,它的主要设计思路是:用最小的概念实现一种“简单”的语言, BrainFuck 语言只有八种符号,所有的操作都由这八种符号的组合来完成。
BrainFuck 基于一个简单的机器模型,除了八个指令,这个机器还包括:一个以字节为单位、被初始化为零的数组、一个指向该数组的指针( 初始时指向数组的第一个字节) 、以及用于输入输出的两个字节流。
因为 BrainFuck 只有八种指令,并且没有关键字,也不允许自定义标识符,
因此它的编译器实现起来非常简单,初学 C 语言不久的人都可以自己编出来,尽管在座的各位每人都可以自己编一个,不过为了引起大家的兴趣,我这里还是给出大家一个官方发布的版本:
#include <stdio.h>;
int p , r , q;
char a [ 5000 ], f [ 5000 ], b , o , *s = f;
void interpret( char * c)
{
char * d;
r ++;
while( * c ) {
//if(strchr("<>;+-,.[]/n",*c))printf("%c",*c);
switch( o = 1 , * c ++) {
case '<' : p --; break;
case '>' : p ++; break;
case '+' : a [p ] ++; break;
case '-' : a [p ] --; break;
case '.' : putchar( a [p ]); fflush( stdout); break;
case ',' : a [p ] = getchar(); fflush( stdout); break;
case '[' :
for( b = 1 , d = c; b && * c; c ++ )
b +=* c == '[' , b -=* c == ']';
if( !b) {
c [ - 1 ] = 0;
while( a [p ] )
interpret( d);
c [ - 1 ] = ']';
break;
}
case ']' :
puts( "UNBALANCED BRACKETS" ), exit( 0);
case '#' :
if( q > 2)
printf( "%2d %2d %2d %2d %2d %2d %2d %2d %2d %2d /n %*s /n " ,
* a , a [ 1 ], a [ 2 ], a [ 3 ], a [ 4 ], a [ 5 ], a [ 6 ], a [ 7 ], a [ 8 ], a [ 9 ], 3 *p + 2 , "^");
break;
default : o = 0;
}
if( p < 0 || p > 100)
puts( "RANGE ERROR" ), exit( 0);
}
r --;
// chkabort();
}
main( int argc , char * argv [])
{
FILE * z;
q = argc;
if( z = fopen( argv [ 1 ], "r")) {
while( (b = getc( z)) > 0 )
*s ++=b;
*s = 0;
interpret( f);
}
}
下面给出一个 BrainFuck 的打印 Hello world 的程序 :
++++++++++ [ >+++++++>++++++++++>+++>+<<<<- ] >++ . >+ . +++++++ .. +++ . >++ . <<+++++++++++++++ . > . +++ . ------ . -------- . >+ . > .
将上述 BrainFuck 编译为可执行文件,比如 test ,然后将上面的 BrainFuck 的 Hello world 程序存在一个文件中,比如 hello .b
然后运行 . / test hello .b 就可以输出 Hello world .
BrainFuck 语法:
字符 含义
>; 指针加一
< 指针减一
+ 指针指向的字节的值加一
- 指针指向的字节的值减一
. 输出指针指向的单元内容( ASCII 码)
, 输入内容到指针指向的单元( ASCII 码)
[ 如果指针指向的单元值为零,向前跳转到对应的 ] 指令的次一指令处
] 如果指针指向的单元值不为零,向后跳转到对应的 [ 指令的次一指令处
BrainFuck 语言,是一种按照“ Turing complete ”思想设计的语言,它的主要设计思路是:用最小的概念实现一种“简单”的语言, BrainFuck 语言只有八种符号,所有的操作都由这八种符号的组合来完成。
BrainFuck 基于一个简单的机器模型,除了八个指令,这个机器还包括:一个以字节为单位、被初始化为零的数组、一个指向该数组的指针( 初始时指向数组的第一个字节) 、以及用于输入输出的两个字节流。
因为 BrainFuck 只有八种指令,并且没有关键字,也不允许自定义标识符,
因此它的编译器实现起来非常简单,初学 C 语言不久的人都可以自己编出来,尽管在座的各位每人都可以自己编一个,不过为了引起大家的兴趣,我这里还是给出大家一个官方发布的版本:
#include <stdio.h>;
int p , r , q;
char a [ 5000 ], f [ 5000 ], b , o , *s = f;
void interpret( char * c)
{
char * d;
r ++;
while( * c ) {
//if(strchr("<>;+-,.[]/n",*c))printf("%c",*c);
switch( o = 1 , * c ++) {
case '<' : p --; break;
case '>' : p ++; break;
case '+' : a [p ] ++; break;
case '-' : a [p ] --; break;
case '.' : putchar( a [p ]); fflush( stdout); break;
case ',' : a [p ] = getchar(); fflush( stdout); break;
case '[' :
for( b = 1 , d = c; b && * c; c ++ )
b +=* c == '[' , b -=* c == ']';
if( !b) {
c [ - 1 ] = 0;
while( a [p ] )
interpret( d);
c [ - 1 ] = ']';
break;
}
case ']' :
puts( "UNBALANCED BRACKETS" ), exit( 0);
case '#' :
if( q > 2)
printf( "%2d %2d %2d %2d %2d %2d %2d %2d %2d %2d /n %*s /n " ,
* a , a [ 1 ], a [ 2 ], a [ 3 ], a [ 4 ], a [ 5 ], a [ 6 ], a [ 7 ], a [ 8 ], a [ 9 ], 3 *p + 2 , "^");
break;
default : o = 0;
}
if( p < 0 || p > 100)
puts( "RANGE ERROR" ), exit( 0);
}
r --;
// chkabort();
}
main( int argc , char * argv [])
{
FILE * z;
q = argc;
if( z = fopen( argv [ 1 ], "r")) {
while( (b = getc( z)) > 0 )
*s ++=b;
*s = 0;
interpret( f);
}
}
下面给出一个 BrainFuck 的打印 Hello world 的程序 :
++++++++++ [ >+++++++>++++++++++>+++>+<<<<- ] >++ . >+ . +++++++ .. +++ . >++ . <<+++++++++++++++ . > . +++ . ------ . -------- . >+ . > .
将上述 BrainFuck 编译为可执行文件,比如 test ,然后将上面的 BrainFuck 的 Hello world 程序存在一个文件中,比如 hello .b
然后运行 . / test hello .b 就可以输出 Hello world .
BrainFuck 语法:
字符 含义
>; 指针加一
< 指针减一
+ 指针指向的字节的值加一
- 指针指向的字节的值减一
. 输出指针指向的单元内容( ASCII 码)
, 输入内容到指针指向的单元( ASCII 码)
[ 如果指针指向的单元值为零,向前跳转到对应的 ] 指令的次一指令处
] 如果指针指向的单元值不为零,向后跳转到对应的 [ 指令的次一指令处