概要
ilasmでstack machineやってみた。
練習問題やってみた。
練習問題
Node.jsでilasmを実行する、インタープリタを書け。
fizzbuzzを実行せよ。
サンプルコード
process.stdin.resume();
process.stdin.setEncoding('utf8');
var str = `
ldc.i4 100
stloc n
ldc.i4 1
stloc i
loop:
ldloc i
ldloc n
bgt bye
ldloc i
ldc.i4 15
rem
brfalse fb
ldloc i
ldc.i4 5
rem
brfalse b
ldloc i
ldc.i4 3
rem
brfalse f
ldloc i
call void [mscorlib] System.Console::WriteLine(int32)
br tugi
fb:
ldstr "fizzbuzz"
br print
b:
ldstr "buzz"
br print
f:
ldstr "fizz"
print:
call void [mscorlib] System.Console::WriteLine(string)
tugi:
ldloc i
ldc.i4 1
add
stloc i
br loop
bye:
ret
`;
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 "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;
}
}
console.log(res)
実行結果
1
2
"fizz"
4
"buzz"
"fizz"
7
8
"fizz"
"buzz"
11
"fizz"
13
14
"fizzbuzz"
16
17
"fizz"
19
"buzz"
"fizz"
22
23
"fizz"
"buzz"
26
"fizz"
28
29
"fizzbuzz"
31
32
"fizz"
34
"buzz"
"fizz"
37
38
"fizz"
"buzz"
41
"fizz"
43
44
"fizzbuzz"
46
47
"fizz"
49
"buzz"
"fizz"
52
53
"fizz"
"buzz"
56
"fizz"
58
59
"fizzbuzz"
61
62
"fizz"
64
"buzz"
"fizz"
67
68
"fizz"
"buzz"
71
"fizz"
73
74
"fizzbuzz"
76
77
"fizz"
79
"buzz"
"fizz"
82
83
"fizz"
"buzz"
86
"fizz"
88
89
"fizzbuzz"
91
92
"fizz"
94
"buzz"
"fizz"
97
98
"fizz"
"buzz"
成果物
以上。