yharaさんトークショー
yharaさんの
Rubyで作る奇妙なプログラミング言語 ~Esoteric Language~
- 作者: 原悠
- 出版社/メーカー: 毎日コミュニケーションズ
- 発売日: 2008/12/20
- メディア: 単行本(ソフトカバー)
- 購入: 8人 クリック: 148回
- この商品を含むブログ (69件) を見る
内容としては前半奇妙な本紹介で、後半奇妙な松江紹介が行われた。このネタで本を出すアタリが流石のyharaさんで、このネタで出版しようと思うところが流石のUSU-YAさんなのかな、と良く知りもしないのに夢想してみた。
僕はbrainf*ckとgrassくらいしか知らなかった。Befungeとか面白かった。
仕様とか全然読んでないのだけれど、この本読んであんまり面白くって感動したので勢いでrubyで書いてみた。
v >v"Hello World!!"0< .: ^_>@
quartz:pts/3% ruby befunge.rb test.bf Hello World!!
いいっぽいけど '*'とかわかんね。
うーん。抜け仕様だらけだ。後でちゃんと仕様読んでみよう。
追記:
というか'*'とかは単純に演算子だよね。きっと。追加してみた。
",,,"v v < >123456789++++++++..v v..********123456789< >123456789--------..v @ .////////123456789<
かな。
45,362880,-27,0
なんのことはない。というか仕様嫁、とかセルフツッコミ。
ソース
class VM class Point attr_accessor :x, :y def initialize(x,y) @x = x @y = y end def to_s "(#{x} , #{y})" end end attr_reader :dir UP = 0 DOWN = 1 LEFT = 2 RIGHT = 3 DIR = {'>'=>RIGHT, '<'=>LEFT, '^'=>UP, 'v'=>DOWN} attr_reader :state MODE_NORMAL = 0 MODE_STRING = 1 attr_reader :curpos attr_reader :stack attr_reader :prog def read @prog[@curpos.y][@curpos.x].chr end def initialize(prog) @stack = [] @curpos = Point.new(0,0) @dir = RIGHT @state = MODE_NORMAL @debug = false load_program(prog) end def load_program(prog) @prog = prog.split("\n") @width = @prog.map {|l| l.length}.max @height = @prog.length end def doubleQuote @state = (MODE_STRING+MODE_NORMAL) - @state end def nextpos case @dir when RIGHT @curpos.x = (@curpos.x+1) % @width when LEFT @curpos.x = (@curpos.x-1) % @width when UP @curpos.y = (@curpos.y-1) % @height when DOWN @curpos.y = (@curpos.y+1) % @height end end def step(n=1) case c = read when '"' doubleQuote when 'v','<','>','^' @dir = DIR[c] when ':' @stack.push @stack.last when '.' print @stack.pop when '@' return nil when '_' if @stack.pop == 0 @dir = RIGHT else @dir = LEFT end when '|' if @stack.pop == 0 @dir = UP else @dir = DOWN end else if @state == MODE_STRING @stack.push(c) elsif ("0".."9").include?(c) @stack.push(c.to_i) end end if @debug STDERR.puts "pos: #{@curpos} mnemonic: #{read} dir: #{@dir} state: #{@state}" end nextpos end def debugenable @debug = true end end vm = VM.new(File.open(ARGV[0]).read) #vm.debugenable while vm.step end
追加分
*** old.rb 2008-12-22 17:39:54.000000000 +0900 --- bef.rb 2008-12-22 17:39:18.000000000 +0900 *************** *** 25,30 **** --- 25,37 ---- attr_reader :stack attr_reader :prog + OP = { + '+' => Proc.new {|x,y| x+y}, + '-' => Proc.new {|x,y| x-y}, + '*' => Proc.new {|x,y| x*y}, + '/' => Proc.new {|x,y| x/y}, + } + def read @prog[@curpos.y][@curpos.x].chr end *************** *** 85,90 **** --- 92,100 ---- else @dir = DOWN end + when '+', '-', '*', '/' + res = OP[c].call(@stack.pop, @stack.pop) + @stack.push(res) else if @state == MODE_STRING @stack.push(c)