<?xml version="1.0" encoding="euc-jp"?>
<?xml-stylesheet href="brainfuck.xsl" type="text/xsl"?>
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>Brainf**k interpriter in XSLT</title>
  </head>
  <body>
    <h1>Brainf**k interpriter in XSLT</h1>
    
    <p>XSLTでBrainf**kインタプリタを書きました。</p>
    <p>
      <script type="application/x-brainfuck+xml">
        <span class="program">
          <![CDATA[
[-]>[-]+++++++[<++++++++++++>-]<.[-]>[-]++++++++[<+++++++++++++>-]<.[-]>[-]+++++++[<+++++++++++++++>-]<.[-]>[-]++++++++[<++++++++++++++>-]<+++.[-]>[-]++++[<++++++++>-]<.[-]>[-]+++++++++[<++++++++++++>-]<+.[-]>[-]++++++++++[<++++++++++>-]<+.[-]>[-]++++++++[<++++++++++++++>-]<+++.[-]>[-]++++++++[<++++++++++++++>-]<+++.[-]>[-]++++++++[<++++++++++++>-]<+.[-]>[-]++++++++++[<++++++++++>-]<+++.[-]>[-]++++++++++[<++++++++++>-]<+.
]]>
        </span>
        <span clsss="input">
        </span>
      </script>
      <!--
           The XSLT engine of Firefox and IE impose restriction on recursion depth.
           We devide brainf**k code.
      -->
      <script type="application/x-brainfuck+xml">
        <span class="program">
          <![CDATA[
[-]>[-]++++[<++++++++>-]<.[-]>[-]+++++++[<+++++++++++++++>-]<.[-]>[-]++++++++[<++++++++++++++>-]<+++.[-]>[-]++++[<++++++++>-]<.
]]>
        </span>
        <span clsss="input">
        </span>
      </script>
      <script type="application/x-brainfuck+xml">
        <span class="program">
          <![CDATA[
[-]>[-]+++++++[<+++++++++++++++++>-]<.[-]>[-]++++++++[<++++++++++++++>-]<++.[-]>[-]+++++++[<+++++++++++++++>-]<.[-]>[-]++++++++[<++++++++++++++>-]<++++.[-]>[-]++++++++[<++++++++++++++>-]<++++.[-]>[-]++++++++++[<++++++++++>-]<+.[-]>[-]+++++++++++[<++++++++++>-]<.[-]>[-]++++[<++++++++>-]<.[-]>[-]+++++++[<+++++++++++++++>-]<.[-]>[-]+++++++++++[<++++++++++>-]<.[-]>[-]++++[<++++++++>-]<.
]]>
        </span>
        <span clsss="input">
        </span>
      </script>
      <script type="application/x-brainfuck+xml">
        <span class="program">
          <![CDATA[
[-]>[-]+++++++[<++++++++++++++>-]<.[-]>[-]++++++++[<++++++++++++++>-]<++.[-]>[-]++++++++[<++++++++++++>-]<+.[-]>[-]+++++++[<+++++++++++++++>-]<.[-]>[-]+++++++++++[<++++++++++>-]<.[-]>[-]++++++++++[<++++++++++>-]<++.[-]>[-]+++++++[<++++++>-]<.[-]>[-]+++++++[<++++++>-]<.[-]>[-]+++++++[<+++++++++++++++>-]<++.[-]>[-]+++++[<+++++++++>-]<+.
]]>
        </span>
        <span clsss="input">
        </span>
      </script>
    </p>

    <h2>使い方</h2>
    <p>XHTMLの中に次のようなコードを書いておいて、<a href="brainfuck.xsl">XSLTコード</a>をスタイルシートとして指定します。</p>
    <blockquote>
      <pre>&lt;script type="application/x-brainfuck+xml"&gt;
  &lt;span class="program"&gt;
    プログラムコード
  &lt;/span&gt;
  &lt;span clsss="input"&gt;
    入力
  &lt;/span&gt;
&lt;/script&gt;</pre>
    </blockquote>
    
    <h2>制約とか</h2>
    <h3>ASCIIコードしか入出力に使えない</h3>
    <p>XSLTには文字と文字コードを変換する機構はありません。なのでASCIIコードを表引きして自前で変換しています。最初は出力に数値参照を使って任意のUnicode文字を出力できるようにしようと思ったのですが、Firefoxはdisable-output-escaping="yes"を許してくれないので無理でした。</p>
    
    <h3>タグを出力したりはできない</h3>
    <p>Firefoxはdisable-output-escaping="yes"を許してくれないのでタグなどは出力できません。</p>

    <h3>大規模なコードは書けない</h3>
    <p>FirefoxやIEのXSLTプロセッサは再帰回数が一定以上になると処理を止めてしまうので、大規模なコードは書けません。</p>

    <h2>おまけ</h2>
    <p><a href="bfencode.rb">文字列をBrainf**kのプログラムに変換するRubyスクリプト</a>。<a href="http://www2.coins.tsukuba.ac.jp/~i021216/diary/?date=20060909#p02">水島さん作のbfencode</a>を元にしています。</p>
    <p>水島さんのbfencodeはbfencode自身の短さを重視していますが、私のものは出力されるコードを少しだけ短くしています。</p>

    <h2>実装</h2>
    <p>XSLT 1.0では配列などは使えないのでポインタは文字列のインデックスとしました。その文字列は数字列で、3文字を1セル(0〜255を10進で表している)として扱っています。</p>
    <p>あとは、ひたすらloopという名前を付けたテンプレートを再帰呼び出ししています。</p>
  </body>
</html>

