!Brainf*ckインタプリタ
!参考サイト http://ja.wikipedia.org/wiki/Brainfuck
DIM mem(0 TO 16) !テープ(配列と要素) ※値は1バイトの整数、初期値は0 MAT mem=ZER
LET p=0 !ヘッド位置(要素を示すポインタ) ※初期値はテープの先頭
!Brainf*ckのプログラムリスト
DATA "++++++++++[>+++++++>++++++++++>+++>+<<<<-]" !Hello World" DATA ">++.>+.+++++++..+++.>++.<<+++++++++++++++." DATA ">.+++.------.--------.>+.>."
LET s$="" !プログラムを読み込む DO READ IF MISSING THEN EXIT DO: ss$ LET s$=s$&ss$ LOOP
LET ip=1 !プログラムを読み込む位置 DO WHILE ip<=LEN(s$) !プログラムを実行する
SELECT CASE s$(ip:ip) !Bfの各命令に応じて CASE ">" !ヘッド位置を1つ進める ※C言語の ++p; に相当 LET p=p+1 CASE "<" !ヘッド位置を1つ戻す ※--p; LET p=p-1 CASE "+" !ヘッド位置の値を1増やす ※++*p; LET mem(p)=MOD(mem(p)+1,256) CASE "-" !ヘッド位置の値を1減らす ※--*p; LET mem(p)=MOD(mem(p)-1,256) CASE "." !ヘッド位置の値を表示する ※putchar(*p); WHEN EXCEPTION IN PRINT CHR$(mem(p)); USE PRINT "."; END WHEN CASE "," !ヘッド位置に値を入力する ※*p=getchar(); CHARACTER INPUT t$ LET mem(p)=ORD(t$) !!!INPUT mem(p) CASE "[" !ヘッド位置の値が0なら、対応する次の]までジャンプする ※while(*p) { IF mem(p)=0 THEN LET t=0 DO LET ip=ip+1 SELECT CASE s$(ip:ip) CASE "[" LET t=t+1 !nest CASE "]" IF t=0 THEN EXIT DO !search it LET t=t-1 CASE ELSE END SELECT LOOP END IF CASE "]" !ヘッド位置の値が0でないなら、対応する前の[までジャンプする ※} IF mem(p)<>0 THEN LET t=0 DO LET IP=IP-1 SELECT CASE s$(ip:ip) CASE "[" IF t=0 THEN EXIT DO !search it LET t=t-1 CASE "]" LET t=t+1 !nest CASE ELSE END SELECT LOOP LET ip=ip-1 !!! END IF CASE ELSE !無関係な文字はスキップする END SELECT
LET ip=ip+1 !次へ LOOP PRINT
PRINT p !メモリダンプ MAT PRINT mem;
END
|