概要
ilasmでstack machineやってみた。
練習問題やってみた。
練習問題
c#でilasmを実行する、インタープリタを書け。
fizzbuzzを実行せよ。
サンプルコード
using System;
using System.Collections;
using System.Collections.Generic;
public class ilasm {
private static Stack<int> stack = new Stack<int>();
private static int n = 0;
private static int i = 0;
private static string g = "";
private static int bgt(string str, string s, int pc) {
int top1 = stack.Pop();
int top2 = stack.Pop();
if (top1 < top2)
{
return getln(str, s);
}
else
{
return pc;
}
}
private static int brfalse(string str, string s, int pc) {
int top1 = stack.Pop();
if (top1 == 0)
{
return getln(str, s);
}
else
{
return pc;
}
}
private static int br(string str, string s) {
return getln(str, s);
}
private static void call(string s) {
if (s == "System.Console::WriteLine(int32)")
{
int top1 = stack.Pop();
Console.WriteLine(top1);
}
if (s == "System.Console::WriteLine(string)")
Console.WriteLine(g);
}
private static void ldstr(string s) {
g = s;
}
private static void stloc(string s) {
int top1 = stack.Pop();
if (s == "n")
n = top1;
if (s == "i")
i = top1;
}
private static void ldloc(string s) {
if (s == "n")
stack.Push(n);
if (s == "i")
stack.Push(i);
}
private static void add() {
int top1 = stack.Pop();
int top2 = stack.Pop();
int v = top2 + top1;
stack.Push(v);
}
private static void sub() {
int top1 = stack.Pop();
int top2 = stack.Pop();
int v = top2 - top1;
stack.Push(v);
}
private static void mul() {
int top1 = stack.Pop();
int top2 = stack.Pop();
int v = top2 * top1;
stack.Push(v);
}
private static void div() {
int top1 = stack.Pop();
int top2 = stack.Pop();
int v = top2 / top1;
stack.Push(v);
}
private static void rem() {
int top1 = stack.Pop();
int top2 = stack.Pop();
int v = top2 % top1;
stack.Push(v);
}
private static void dup() {
int top1 = stack.Pop();
stack.Push(top1);
stack.Push(top1);
}
private static void drop() {
int top1 = stack.Pop();
}
private static void push(string s) {
int v = Convert.ToInt32(s);
stack.Push(v);
}
private static string getl(string str, int pc) {
string[] s = str.Split(new string[] {
"\n"
}, StringSplitOptions.None);
return s[pc + 1];
}
private static int getln(string str, string la) {
int j = 0;
string[] s = str.Split(new string[] {
"\n"
}, StringSplitOptions.None);
for (j = 0; j < s.Length; j++)
{
if (s[j].IndexOf(la) == 0)
{
//Console.WriteLine(s[i]);
//Console.WriteLine(la);
break;
}
}
return j - 1;
}
public static void Main() {
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 lb
ldloc i
ldc.i4 3
rem
brfalse fc
ldloc i
call void [mscorlib] System.Console::WriteLine(int32)
br tugi
fb: _
ldstr ""fizzbuzz""
br print
lb: _
ldstr ""buzz""
br print
fc: _
ldstr ""fizz""
print: _
call void [mscorlib] System.Console::WriteLine(string)
tugi: _
ldloc i
ldc.i4 1
add
stloc i
br loop
bye: _
ret
";
int pc = 0;
int ss = 0;
while (true)
{
if (pc > 60)
{
Console.WriteLine("Max!");
break;
}
string src = getl(str, pc);
//Console.WriteLine(src);
//Console.WriteLine(i);
if (ss > 2560)
{
Console.WriteLine("OVER!");
break;
}
string[] s = src.Split(new string[] {
" "
}, StringSplitOptions.None);
switch (s[1])
{
case "bgt":
pc = bgt(str, s[2], pc);
break;
case "brfalse":
pc = brfalse(str, s[2], pc);
break;
case "br":
pc = br(str, s[2]);
break;
case "call":
call(s[4]);
break;
case "ldstr":
ldstr(s[2]);
break;
case "stloc":
stloc(s[2]);
break;
case "ldloc":
ldloc(s[2]);
break;
case "add":
add();
break;
case "sub":
sub();
break;
case "mul":
mul();
break;
case "div":
div();
break;
case "rem":
rem();
break;
case "dup":
dup();
break;
case "pop":
drop();
break;
case "ldc.i4":
push(s[2]);
break;
case "ret":
pc = 100;
break;
default:
//Console.WriteLine(s[1]);
break;
}
pc++;
ss++;
//Console.WriteLine(pc);
}
}
}
実行結果
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"
Max!
成果物
以上。