概要
俺言語をやってみた。
スタックマシーンでバイトコードインタープリタを書いてみた。
バイトコード
push "x"
push ""
set
push "i"
push "0"
set
loop push "i"
push "i"
push "i"
get
++
set
get
push "x"
push "x"
get
push "i"
get
add
set
push "x"
push "x"
get
push " "
add
set
push "i"
get
push "100"
>
!
if skip
jp loop
skip end
出力
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
仕様
一行は、ラベル、オペコード、値の順。
オペコードと意味は、以下。
push "x" xをスタックに積む。
set スタックのトップをスタックの2番目を変数として、メモリーにセーブして、トップと2番目を消費する。
get スタックのトップを変数として、メモリーからロードして消費してから、積む。
++ スタックのトップをインクリメント。
add スタックのトップと2番目を合体する。
> スタックのトップと2番目を評価する。
! スタックのトップを否定する。
if スタックのトップが真なら、ラベルへジャンプ。
jp ラベルへジャンプ。
スタックマシーンなバイトコードインタープリタ
function run() {
var memory = [];
var stack = [];
var tmp;
var v;
var pc = 0;
var src = document.getElementById('src0').value;
var m = src.split("\n");
var i;
var flg = 0;
while (flg == 0)
{
var cm = m[pc].split(" ");
switch (cm[1])
{
case "push":
tmp = cm[2].replace(/\"/g, "");
stack.push(tmp);
break;
case "set":
tmp = stack.pop();
v = stack.pop();
memory[v] = tmp;
break;
case "get":
v = stack.pop();
tmp = memory[v];
stack.push(tmp);
break;
case "++":
tmp = stack.pop();
tmp = new Number(tmp) + 1;
stack.push(tmp);
break;
case "add":
tmp = stack.pop();
tmp = stack.pop() + " " + tmp;
stack.push(tmp);
break;
case ">":
stack.push(stack.pop() > stack.pop());
break;
case "!":
tmp = stack.pop();
stack.push(!tmp);
break;
case "if":
if (stack.pop())
{
for (i = 0; i < m.length; i++)
{
var la = m[i].split(" ");
if (la[0] == cm[2])
{
pc = i - 1;
}
}
}
break;
case "jp":
for (i = 0; i < m.length; i++)
{
var la = m[i].split(" ");
if (la[0] == cm[2])
{
pc = i - 1;
}
}
break;
case "end":
flg = 1;
break;
case "+":
break;
case "-":
break;
case "*":
break;
case "/":
break;
case "=":
break;
case "&":
break;
case "|":
break;
case "^":
break;
case "%":
break;
case "&&":
stack.push(stack.pop() && stack.pop());
break;
case "||":
stack.push(stack.pop() || stack.pop());
break;
case "==":
stack.push(stack.pop() == stack.pop());
break;
case "pop":
break;
}
pc++;
}
var list = document.getElementById('out');
list.innerHTML = memory["x"];
}
成果物
以上。