概要
ilasmでstack machineやってみた。
練習問題やってみた。
練習問題
ilasmが動く、インタープリタを書け。
zundokoを動作させよ。
写真
投入したソース
ldc.i4 0
stloc a
loop:
ldc.i4 3
callvirt instance int32 [mscorlib]System.Random::Next(int32)
ldc.i4 1
bgt zun
ldc.i4 0
stloc a
ldstr "ドコ"
call void [mscorlib]System.Console::Write(string)
br loop
zun:
ldstr "ズン"
call void [mscorlib]System.Console::Write(string)
ldloc a
ldc.i4 1
add
stloc a
ldloc a
ldc.i4 3
bgt end
br loop
end:
ldstr "ドコ,キヨシ!!"
call void [mscorlib]System.Console::WriteLine(string)
ret
実行結果
"ドコ"
"ズン"
"ドコ"
"ズン"
"ドコ"
"ドコ"
"ズン"
"ズン"
"ズン"
"ドコ"
"ズン"
"ドコ"
"ズン"
"ドコ"
"ドコ"
"ズン"
"ズン"
"ズン"
"ズン"
"ドコ,キヨシ!!"
サンプルコード
var out = document.getElementById("out");
var src = document.getElementById("src");
function run() {
var str = src.value;
str = str.replace(/\t/g, " ");
str = str.replace(/ /g, " ");
str = str.replace(/ /g, " ");
str = str.replace(/ /g, " ");
var codes = str.split("\n");
var pc = 0;
var sp = 0;
var len = codes.length;
var i;
var label = {};
var val = {};
var ram = [];
var res = "";
for (i = 0; i < len; i++)
{
if (codes[i].indexOf(":") > -1)
{
label[codes[i]] = i;
}
}
while (i > 0)
{
//alert(pc);
var code = codes[pc].split(" ");
switch (code[1])
{
case "drop":
sp--;
pc++;
break;
case "dup":
ram[sp] = ram[sp - 1];
sp++;
pc++;
break;
case "ldstr":
ram[sp] = code[2];
sp++;
pc++;
break;
case "callvirt":
ram[sp] = Math.floor(Math.random() * 2 + 1);
sp++;
pc++;
break;
case "ldc.i4":
ram[sp] = code[2];
sp++;
pc++;
break;
case "stloc":
sp--;
val[code[2]] = ram[sp];
pc++;
break;
case "ldloc":
ram[sp] = val[code[2]];
sp++;
pc++;
break;
case "call":
sp--;
res += ram[sp] + "\n";
pc++;
break;
case "brtrue":
sp--;
if (ram[sp] == 1)
{
pc = label[code[2] + ":"];
}
else
{
pc++;
}
break;
case "brfalse":
sp--;
if (ram[sp] == 0)
{
pc = label[code[2] + ":"];
}
else
{
pc++;
}
break;
case "bgt":
sp--;
if (parseInt(ram[sp - 1]) > parseInt(ram[sp]))
{
sp--;
pc = label[code[2] + ":"];
}
else
{
sp--;
pc++;
}
break;
case "add":
sp--;
ram[sp - 1] = parseInt(ram[sp - 1]) + parseInt(ram[sp]);
pc++;
break;
case "mul":
sp--;
ram[sp - 1] = parseInt(ram[sp - 1]) * parseInt(ram[sp]);
pc++;
break;
case "sub":
sp--;
ram[sp - 1] = parseInt(ram[sp - 1]) - parseInt(ram[sp]);
pc++;
break;
case "div":
sp--;
ram[sp - 1] = parseInt(ram[sp - 1]) / parseInt(ram[sp]);
pc++;
break;
case "rem":
sp--;
ram[sp - 1] = parseInt(ram[sp - 1]) % parseInt(ram[sp]);
pc++;
break;
case "br":
pc = label[code[2] + ":"];
break;
case "ret":
i = 0;
break;
case undefined:
pc++;
break;
default:
alert(code[1]);
pc++;
break;
}
}
//alert("ok");
out.value = res;
}
成果物
以上