(define -ayalog '())

括弧に魅せられて道を外した名前のないプログラマ

CoffeeScriptでBrainf*ckを書いた

Rubyで作る奇妙なプログラミング言語を読んでいたら、書きたくなったのでRubyじゃなくてCoffeeScriptで書いた!!

String.prototype.to_array = -> this.split('')

brainf_ck = ->
  that = {}

  tokens = []
  jumps = {}

  that.parse = (src) ->
    tokens = src.to_array()
    starts = []
    for c, i in tokens
      switch c
        when '['
          starts.push i
        when ']'
          j = starts.pop()
          jumps[j] = i
          jumps[i] = j

  that.run = ->
    tape = []
    pc = 0
    cur = 0

    while pc < tokens.length
      switch tokens[pc]
        when '+'
          tape[cur] ||= 0
          tape[cur]++

        when '-'
          tape[cur] ||= 0
          tape[cur]--

        when '.'
          $('p').append String.fromCharCode tape[cur]

        when ','
          throw 'NotImplementedError'

        when '>'
          cur++

        when '<'
          cur--
          throw 'OutOfBoundsError' if cur < 0

        when '['
          pc = jumps[pc] if tape[cur] == 0

        when ']'
          pc = jumps[pc] if tape[cur] != 0

      pc++

  return that

# Hello, world!
bf = brainf_ck()
bf.parse(" +++++++++[>++++++++>+++++++++++>+++++<<<-]>.>++.+++++++..+++.>-.
           ------------.<++++++++.--------.+++.------.--------.>+. ")
bf.run()

「.」の実装は1文字ずつ出力したかったので、適当にjQuery適当なpタグ捕まえて雑に突っ込んでます。「,」はJavaScriptで画面から受け取るっていうのがよく分かんなかったんで実装しないことにしました(ぇ
あとコンストラクタ関数嫌いなんで、使わないように実装しました。もうちょっと小奇麗に実装したかったけど、まぁ致し方なし。あ、一箇所穴があるけど気にしないでほしいな(マテ
そういえば「*」で伏せ字にしている部分って「s」らしいって「Rubyで作る奇妙なプログラミング言語」に書いてありました。

今、半分くらい読んだのであと半分。結構面白いかも。