0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ilasmでstack machine その56

Posted at

概要

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!

成果物

以上。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?