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 その19

Last updated at Posted at 2024-11-01

概要

ilasmでstack machineやってみた。
練習問題やってみた。

練習問題

ilasmが動く、インタープリタを書け。

方針

  • Plunker、使う。

  • 命令セット

ニーモニック 意味 stackの状態
nop 何もしない。 変化無し
ldc.i4 1 stackに整数 1を積む。 1個増える
ldstr "fizzbuzz" stackに「fizzbuzz」を積む。 1個増える
ldloc i stackに変数iの値を積む。 1個増える
stloc i 変数iにstackを移動。 1個減る
call void [mscorlib] System.Console::WriteLine(int32) stackを数値印刷。 1個減る
call void [mscorlib] System.Console::WriteLine(string) stackを文字印刷。 1個減る
callvirt instance int32 [mscorlib]System.Random::Next(int32) 乱数を積む 1個減る
beq bye セカンドとトップを比べて等しいならbyeに飛ぶ。 2個減る
bgt bye セカンドとトップを比べて小さいならbyeに飛ぶ。 2個減る
blt bye セカンドとトップを比べて大きいならbyeに飛ぶ。 2個減る
br tugi tugiへ飛ぶ。 変化無し
brfalse fizzbuzz ゼロで無いならfizzbuzzに飛ぶ。 1個減る
brtrue fizzbuzz ゼロならfizzbuzzに飛ぶ。 1個減る
dup stackにコピーを積む。 1個増える
drop stackを一個減らす。 1個減る
add セカンドとトップの加算を求める。 1個減る
sub セカンドとトップの減算を求める。 1個減る
mul {セカンドとトップの乗算を求める。 1個減る
div セカンドとトップの除算を求める。 1個減る
rem セカンドとトップの剰余を求める。 1個減る

サンプルコード


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 "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;
}




投入したソース

    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

実行結果

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"

成果物

以上

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?