ilasmでstack machine その56

# 概要
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!
```

# 成果物

https://paiza.io/projects/haugibXXBzb6kV4u3YCCfQ


以上。