Brainfuck
簡稱bf
是一種程式語言
最近看到覺得有點有趣
我大致簡單講解一下
整個機器包含一個很長的一維陣列和一個指標
像這樣
0 0 0 0 0 0 0 0 0 0 0 0 .....
^
每個一維陣列裡的數範圍是0~255
這個語言裡有八個狀態分別由八個字元代表
bf C
> ++ptr;
< --ptr;
+ ++*ptr;
- --*ptr;
. putchar(*ptr);
, getchar(*ptr);
[ while(*ptr){
] }
就這樣
首先先來寫個Hello World! 吧
++++++++++
第一格加到10 會長這樣: 10 0 0 0 0 0 0 0 0 0
[
>+++++++>++++++++++>+++>+<<<<-
]
把後三格分別加7 10 3 1 十次
然後第一格變為零
0 70 100 30 10 0 0 0 0 0 0 0
接下來把每一格調成對應每個字的ASCII碼並輸出
>++. H
>+. e
+++++++. l
. l
+++. o
>++. space
<<+++++++++++++++. W
>. o
+++. r
------. l
--------. d
>+. !
>. \n
順帶一提
這個語言在編譯的時候會直接忽略掉所有不是關鍵字元的東西
所以只要你的註解沒有用到這些字元你想寫哪就可以寫哪
排版也完全沒有規定
如果註解裡有關鍵字 可以用以下的方法
[-][你的註解...]
不過會把當前指標指向的位元組的值歸零就是了
還有裡面的中括號也要對稱才不會出問題
網路上有一些還不錯的直譯器
這款能把所有機器的動作放慢並顯示出來
能幫助初學者聊解其中運作的方式
不過缺點是跑得有點慢而且陣列只有27格
跑大一點的程式可能會超過
這款就很適合跑比較大的程式
並且執行速度也快
不過缺點就是沒辦法看到怎麼跑的
手機版的軟體好像都不怎麼好
有空的話我計劃自己弄一個
當作我開發第一個APP的目標
然後網路上查了幾個用C寫的直譯器好像都不太能用
有幾個是本身邏輯有問題
有幾個是用了我沒裝的標頭檔所以我跑不動
所以自己寫了一個來試試看
目前用起來沒什麼問題
#include<stdio.h>
unsigned char tape[30000]={0};
unsigned char* ptr = tape;
void interpret(char* input){
int i,loop;
for (i=0;input[i]!=0;i++){
switch(input[i]){
case '>':
++ptr;
break;
case '<':
--ptr;
break;
case '+':
++*ptr;
break;
case '-':
--*ptr;
break;
case '.':
putchar(*ptr);
break;
case ',':
*ptr=getchar();
break;
case '[':
if(*ptr==0){
loop=1;
while(loop>0){
i++;
if(input[i]=='['){
loop++;
}else if(input[i]==']'){
loop--;
}
}
}
break;
case ']':
if(*ptr!=0){
loop=1;
while(loop>0){
i--;
if(input[i]=='['){
loop--;
}else if(input[i]==']'){
loop++;
}
}
}
break;
default:
break;
}
}
}
int main(int argc,char *argv[]) {
if(argc!=2){
printf("Usage: %s file.bf\n",argv[0]);
system("pause");
exit(2);
}
FILE *file=fopen(argv[1],"r");
if(file==NULL){
printf("Error: fopen failed\n");
system("pause");
exit(1);
}
fseek(file,0L,SEEK_END);
long file_len=ftell(file);
rewind(file);
char *file_buf=malloc(file_len*sizeof(char)+1);
file_buf[file_len]='\0';
fread(file_buf,file_len,sizeof(char),file);
fclose(file);
interpret(file_buf);
free(file_buf);
system("pause");
return 0;
}
這個程式主要參考自這篇
https://gist.github.com/D0tty/e4712ab8024944f17533a1f5354ca83f
不過他寫的裡面迴圈的部分有點問題
所以我改了一下