新しく発言する  EXIT  インデックスへ

Brainf*ckインタプリタをつくる


  Brainf*ckインタプリタをつくる 山中和義 2008/08/26 19:19:08 
  プログラム例(DATA文の差し替え) 山中和義 2008/08/26 19:19:34 
  参考.チューリングマシンのシミュレータ 山中和義 2008/08/27 19:45:29  (修正1回)
   └サンプル(DATA文差し替え) 山中和義 2008/08/29 22:01:20 

  Brainf*ckインタプリタをつくる 山中和義 2008/08/26 19:19:08   ツリーへ
Brainf*ckインタプリタをつくる  返事を書く  ノートメニュー
山中和義 <drdlxujciw> 2008/08/26 19:19:08
!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
  プログラム例(DATA文の差し替え) 山中和義 2008/08/26 19:19:34   ツリーへ
Re: Brainf*ckインタプリタをつくる  返事を書く  ノートメニュー
山中和義 <drdlxujciw> 2008/08/26 19:19:34
プログラム例(DATA文の差し替え)


!100までの素数
DATA ">++++[<++++++++>-]>++++++++[<++++++>-]<++.<.>+.<.>++."
DATA "<.>++.<.>>++[<--->-]<..<.>.++.<.>--.>++[<+++>-]<.<.>>++[<--->-]"
DATA "<.>++[<++++>-]<.<.>>++[<--->-]<-.+.<.>-.>+++[<++>-]<+.<.>>++"
DATA "[<--->-]<.--.<.>++.++++.<.>---.---.<.>+++.-.<.>+.+++.<.>--.--."
DATA "<.>++.++++.<.>---.-----.<.>+++++.+.<.>.>++[<--->-]<.<.>>++"
DATA "[<+++>-]<.----.<.>++++.++.<.>-.-----.<.>+++++.+.<.>.--."






!A〜Zの表示
DATA "++++++++[>++++++++<-]>>+++++[<<+++++>>-]<<+[>+.<-]"

  参考.チューリングマシンのシミュレータ 山中和義 2008/08/27 19:45:29  (修正1回)  ツリーへ
Re: Brainf*ckインタプリタをつくる  返事を書く  ノートメニュー
山中和義 <drdlxujciw> 2008/08/27 19:45:29 ** この記事は1回修正されてます
参考.チューリングマシンのシミュレータ


!1テープ・チューリングマシン(Turing Machine)


!---------- ↓↓↓↓↓ ----------

!動作表(状態遷移表)
! 現在の状態、現在のテープの値
! テープに書き込む値、移動方向、次の状態

100 DATA 1,_, _,R,1 !1進法による数の減算
DATA 1,1, 1,R,1
DATA 1,-, -,R,1
DATA 1,"=", _,L,2
DATA 2,1, "=",L,3
DATA 2,"-", _,L,2 !halt
DATA 3,1, 1,L,3
DATA 3,"-", "-",L,4
DATA 4,_, _,L,4
DATA 4,1, _,R,1

!初期値
LET q=1 !状態q0
LET tp$="11111-11=" !テープの値 ※5-2の計算
LET p=1 !ヘッダ位置
!---------- ↑↑↑↑↑ ----------


!トレース
CALL DispStatus !初期状態

LET Running=1 !実行フラグ
DO WHILE Running=1
LET Running=0

LET n=1 !行番号
RESTORE 100
DO !一致するプログラム(動作表)を実行する
READ IF MISSING THEN EXIT DO: p1,p2$,p3$,p4$,p5

IF p<1 OR p>LEN(tp$) THEN
PRINT "テープから外れます。"; p
STOP
END IF

IF q=p1 AND tp$(p:p)=p2$ THEN
LET Running=1

LET tp$(p:p)=p3$ !テープへの書き込み

SELECT CASE UCASE$(p4$) !ヘッドの移動
CASE "R"
LET p=p+1
CASE "L"
LET p=p-1
CASE ELSE
END SELECT

LET q=p5 !状態遷移

!トレース
PRINT "動作";STR$(n);" →";p1;p2$;" ";p3$;" ";p4$;p5 !実行した動作
CALL DispStatus !遷移した状態
END IF

LET n=n+1
LOOP

LOOP

PRINT "停止!"


SUB DispStatus !現在の状態を表示する
PRINT "テープの値=";tp$
PRINT "ヘッド位置=";p
PRINT "状態=";q
PRINT
END SUB

END
   └サンプル(DATA文差し替え) 山中和義 2008/08/29 22:01:20   ツリーへ
Re: 参考.チューリングマシンのシミュレータ  返事を書く  ノートメニュー
山中和義 <drdlxujciw> 2008/08/29 22:01:20
サンプル(DATA文差し替え)


!※1進法による数の加算

100 DATA 0,1, 1,R,1
DATA 0,_, _,R,0
DATA 1,1, 1,R,1
DATA 1,_, 1,x,2
DATA 2,1, 1,R,2
DATA 2,_, _,L,3
DATA 3,1, _,x,3

!初期値
LET q=0 !状態q0
LET tp$="11_1111_" !テープの値
LET p=1 !ヘッダ位置






!※パリティチェック

100 DATA 0,0,_,R,0
DATA 0,1,_,R,1
DATA 1,0,_,R,1
DATA 1,1,_,R,0
DATA 0,_,0,R,99
DATA 1,_,1,R,99

!初期値
LET q=0 !状態q0
LET tp$="010110_" !テープの値
LET p=1 !ヘッダ位置







!※2進法による数のビット反転(NOT演算)

100 DATA 0,_, _,R,99
DATA 0,1, 0,R,0
DATA 0,0, 1,R,0

!初期値
LET q=0 !状態q0
LET tp$="100110_" !テープの値
LET p=1 !ヘッダ位置






!※2進法による数のインクリメント

100 DATA 0,_, _,L,1
DATA 0,1, 1,R,0
DATA 0,0, 0,R,0
DATA 1,1, 0,L,1
DATA 1,0, 1,x,99

!初期値
LET q=0 !状態q0
LET tp$="01011_" !テープの値 ※桁上げ用に最上位を0とする
LET p=1 !ヘッダ位置






!※2進法による数のディクリメント

100 DATA 0,_, _,L,1
DATA 0,1, 1,R,0
DATA 0,0, 0,R,0
DATA 1,1, 0,x,99
DATA 1,0, 1,L,1

!初期値
LET q=0 !状態q0
LET tp$="1010100_" !テープの値 ※桁上げ用に最上位を1とする
LET p=1 !ヘッダ位置






!※2の補数

100 DATA 0,1,0,R,0
DATA 0,0,1,R,0
DATA 0,_,_,L,1
DATA 1,0,1,R,99
DATA 1,1,0,L,1
DATA 1,_,1,R,99

!初期値
LET q=0 !状態q0
LET tp$="1101101_" !テープの値
LET p=1 !ヘッダ位置






!※2進法による数の加算 1011+101

100 DATA 0,1,1,r,0
DATA 0,0,0,r,0
DATA 0,_,_,r,1
DATA 1,0,0,r,1
DATA 1,1,1,r,1
DATA 1,_,_,l,2
DATA 2,0,1,l,2
DATA 2,1,0,l,4
DATA 2,_,_,r,3
DATA 3,1,_,r,3
DATA 3,0,_,r,3
DATA 4,1,1,l,4
DATA 4,0,0,l,4
DATA 4,_,_,l,5
DATA 5,1,0,l,5
DATA 5,_,1,r,0
DATA 5,0,1,r,0

!初期値
LET q=0 !状態q0
LET tp$="01011_101_" !テープの値 01011+101 ※桁上げ用に最上位を0とする
LET p=1 !ヘッダ位置

 インデックスへ  EXIT
新規発言を反映させるにはブラウザの更新ボタンを押してください。