Ioっぽいforth
Forthというと後置記法なので、1+2*3は123*+とかけるというものです。
ところで、もしもメッセージの連鎖を書き連ねたforthを作ったらどうなるかと
考えてたら1+(2*(3))いう表記になりました。まるでIo言語です。
この文字列をバイトコードとして実行する処理系をJavaScriptで書いてみました。
<script> Object.prototype.get = function(prm) {var obj = this;return function(a){return obj[prm](a);};} Object.prototype.p = function() {document.write(this+"<br/>");} Number.prototype["+"]=function(a){return this+a;} Number.prototype["*"]=function(a){return this*a;} String.prototype.run = function() { var pc = 0; var stack = []; var prm; while (true) { code = this.charAt(pc++); switch(code) { case ";": return stack.pop(); case "(": prm = stack.pop(); stack.push(stack.pop().get(prm)); break; case ")": prm = stack.pop(); stack.push(stack.pop()(prm)); break; default: if(code.match(/[0-9]/))stack.push(new Number(code)); else stack.push(code); } } } "1+(2*(3));".run().p(); </script>
たったこれだけです。
解説
1,+はそれぞれstackに積みます。[1,+]
そして、(のコードが来たらstackからメソッド名とオブジェクトを取り出し、オブジェクトからメソッドを
取り出してstackに積みます。[function1+n]
2,*でもそれぞれをstackに積みます。[function1+n,2,*]
(でメソッドを取り出します。[function1+n,function2*n]
3をstackに積みます。[function1+n,function2*n,3]
)でメソッドを実行します。[function1+n,6]
)でメソッドを実行します。[7]
;で処理を終了しstack.topを返します。7
結果として7が返ります。
これで、ifをどうする?ループの処理はどうする?と考えていくと面白そうですが、疲れたのでここまで。