RubyでBrainf*ckのインタプリタを実装すること,以上!

適当にWikipediaを読んでいたら,Brainf*ckの項目にたどり着いた

Brainfuck - Wikipedia

ので,とっさに思いついて処理系を実装しようと思った.
ポインタ云々なので,Cを使ったら楽だと思いつつ,あえてRubyで書くことに.


ちなみにWikipediaみてもイミフな人に向けて説明すると,Brainf*ckとは

  • 記憶領域の番地を1進む,あるいは1戻るの移動
  • 指定の番地の記憶領域に1を足すこと,あるいは引く
  • 指定番地の1文字を出力する,あるいは指定番地に1文字入力する
  • それら命令の条件(「指定番地のデータが0か,それ以外か」のみ)を持った繰り返し

だけの命令しか存在しないプログラミング言語


なので,プログラムの文字は><+-.,[]の8種類のみ.
#8文字ということは"如月千早天海春香"とか"涼宮ハルヒの憂鬱"とかの8文字でもいけるんじゃね!!??


よって,予想通り,Brainf*ckのプログラムは

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

こんなことになりますw



Rubyでの実装は意外とシンプルにできました.
[]が後方で評価してるのは頂けませんが,これは途中までBrainf*ckの仕様をよく理解せず作っていたのが原因w

$ ruby brainfuck.rb hello.bf

てな感じで実行すると,HelloWorld!っちゃいます.

Input filename : hello.bf
Source===============================================================
 >+++++++++[<++++++++>-]<.>++++
 +++[<++++>-]<+.+++++++..+++.[-
 ]>++++++++[<++++>-]<.>++++++++
 +++[<+++++>-]<.>++++++++[<+++>
 -]<.+++.------.--------.[-]>++
 ++++++[<++++>-]<+.[-]++++++++++.

Result===============================================================
Hello World!


イカソース!


brainfuck.rb

filepath = ARGV[0]

puts "Input filename : #{filepath}"
source = open(filepath).read
puts "Source==============================================================="
puts source
puts 
puts "Result==============================================================="

#変数とか準備
stack = Array.new()
data = Array.new()
address = 0
pointer = 0
data.push 0

while(address < source.length)
	case source[address].chr
		when ">"
			pointer += 1
			if(data.length >= pointer)
				data.push(0)
			end
		when "<"
			pointer -= 1
		when "+"
			data[pointer] += 1
		when "-"
			data[pointer] -= 1
		when "."
			print data[pointer].chr
		when ","
			data[pointer] = STDIN.getc
		when "["
			stack.push(address)
		when "]"
			if data[pointer] != 0
				address = stack.pop() - 1
			else
				stack.pop()
			end
		else
			#それ以外は華麗にスルー
	end
		
	address += 1
end


hello.bf

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


echo.bf

 +[>,.<]