素人がプログラミングを勉強していたブログ

プログラミング、セキュリティ、英語、Webなどのブログ since 2008

連絡先: twitter: @javascripter にどうぞ。

Brainfuckのインタプリタ

前から作ってみたいと思っていた、Brainfuckインタプリタを作った。
JavaScript Brainfuck interpreterに置いた。
id:lizanデバッグを手伝ってもらったり、実装についてアドバイスを貰いながら、けっこう苦労して作った。

var brainfuck = function (source, getc) {
  var heap, ptr, cur, c, ret, stack, i, bracket, stack;
  heap = [0];
  ptr = 0;
  cur = -1;
  ret = '';
  stack = [];
  if (!getc) getc = function () { return prompt("input a character"); };
  while ((c = source.charAt(++cur))) {
    switch (c) {
    case "+":
      ++heap[ptr];
      if (heap[ptr] == 256) heap[ptr] = 0;
      break;
    case "-":
      --heap[ptr];
      if (heap[ptr] == -1) heap[ptr] = 255;
      break;
    case ">":
      if (++ptr >= heap.length) heap.push(0);
      break;
    case "<":
      if (--ptr < 0) throw new Error("access to a negative address");
      break;
    case ".":
      ret += String.fromCharCode(heap[ptr]);
      break;
    case ",":
      heap[ptr] = getc().charCodeAt(0);
      break;
    case "[":
      stack.push(cur);
      if (heap[ptr] != 0) break;
      i = cur;
      bracket = 1;
      while (bracket > 0) { // find ]
        c = source.charAt(++i);
        if (c == "[") {
          ++bracket;
        } else if (c == "]") {
          --bracket;
        }
        if (i >= source.length) throw new Error("unterminated brackets");
      }
      cur = i;
      break;
    case "]":
      if (stack.length <= 0) throw new Error("unterminated brackets");
      cur = stack.pop() - 1;
      break;
    }
  }
  return ret;
};

// "Hello, world!"
brainfuck("+++++++++[>++++++++>+++++++++++>+++++<<<-]>.>++.+++++++..+++.>-.------------.<++++++++.--------.+++.------.--------.>+.");
<html>
  <head>
    <title>JavaScript Brainfuck interpreter</title>
    <style type="text/css">
      ul {
        list-style: none;
        margin: 1em;
      }
      #source {
        width: 50%;
        height: 50%;
      }
    </style>
  </head>
  <body>
    <h1>JavaScript Brainfuck interpreter</h1>
    <ul>
      <li>
        <textarea id="source">+++++++++[&gt;++++++++&gt;+++++++++++&gt;+++++&lt;&lt;&lt;-]&gt;.&gt;++.+++++++..+++.&gt;-.------------.&lt;++++++++.--------.+++.------.--------.&gt;+.</textarea>
      </li>
      <li><button id="exec">execute</button></li>
      <li><pre id="result"></pre></li>
    </ul>
    <script type="text/javascript" src="brainfuck.js"></script>
    <script type="text/javascript">
      var source = document.getElementById('source');
      var exec = document.getElementById('exec');
      var result = document.getElementById('result');
      exec.onclick = function () {
        result.textContent = brainfuck(source.value);
      };
    </script>
  </body>
</html>