1
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やってみた。
練習問題やってみた。

練習問題

ilasmを日本語に変換するコンパイラを書け。
fizzbuzzをコンパイルせよ。

方針

  • Plunkerを使う。
  • 仕様
ニーモニック  日本語
ldstr "fizz" 文字列 "fizz" を積み
ldc.i4 100 数値 100 を積み
stloc i 変数 i に移動し
ldloc i 変数 i を積み
call System.Console::WriteLine(int32) 数値印字し
call System.Console::WriteLine(string) 文字印字し
brtrue tugi 真なら tugi へ飛ぶ
brfalse tugi 偽なら tugi へ飛ぶ
bgt tugi 比べて大なら tugi へ飛ぶ
add 足す
mul 掛ける
sub 引く
div 割る
rem 剰余し
br loop 無条件で loop へ飛ぶ
ret 終わり。

写真

image.png

投入したソース

    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


実行結果

  数値 100 を積み
  変数 n に移動し
  数値 1 を積み
  変数 i に移動し
loop:
  変数 i を積み
  変数 n を積み
  比べて大なら bye へ飛ぶ
  変数 i を積み
  数値 15 を積み
  剰余し
  偽なら fb へ飛ぶ
  変数 i を積み
  数値 5 を積み
  剰余し
  偽なら b へ飛ぶ
  変数 i を積み
  数値 3 を積み
  剰余し
  偽なら f へ飛ぶ
  変数 i を積み
  数値印字し
  無条件で tugi へ飛ぶ
fb:
  文字列 "fizzbuzz" を積み
  無条件で print へ飛ぶ
b:
  文字列 "buzz" を積み
  無条件で print へ飛ぶ
f:
  文字列 "fizz" を積み
print:
  文字印字し
tugi:
  変数 i を積み
  数値 1 を積み
  足す
  変数 i に移動し
  無条件で loop へ飛ぶ
bye:
  終わり。

サンプルコード

コンパイラ


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)
  {
    var code = codes[pc].split(" ");
    switch (code[1])
    {
    case "drop":
      pc++;
    break;
    case "dup":
      pc++;
    break;
    case "ldstr":
      res += "  文字列 " + code[2] + " を積み\n";
      pc++;
    break;
    case "ldc.i4":
      res += "  数値 " + code[2] + " を積み\n";
      pc++;
    break;
    case "stloc":   
      res += "  変数 "+ code[2] + " に移動し\n";
      pc++;
    break;
    case "ldloc":
      res += "  変数 "+ code[2] + " を積み\n";
      pc++;
    break; 
    case "call":
      if (code[4] == "System.Console::WriteLine(int32)")
        res += "  数値印字し\n";
      if (code[4] == "System.Console::WriteLine(string)")
        res += "  文字印字し\n";
      pc++;
    break;
    case "brtrue": 
      res += "  真なら "+ code[2] + " へ飛ぶ\n";
      pc++;
    break;
    case "brfalse": 
      res += "  偽なら "+ code[2] + " へ飛ぶ\n";
      pc++;
    break;      
    case "bgt":  
      res += "  比べて大なら "+ code[2] + " へ飛ぶ\n";
      pc++;
    break;
    case "add":  
      res += "  足す\n";
      pc++;
    break;
    case "mul":  
      res += "  掛ける\n";
      pc++;
    break;
    case "sub":  
      res += "  引く\n";
      pc++;
    break;
    case "div":  
      res += "  割る\n";
      pc++;
    break;
    case "rem":  
      res += "  剰余し\n";
      pc++;    
    break;
    case "br": 
      res += "  無条件で "+ code[2] + " へ飛ぶ\n";
      pc++;
    break;
    case "ret":  
      res += "  終わり。\n";
      i = 0;
    break;
    case undefined:
      res += code[0] + "\n";
      pc++;
    break;
    default:
      alert(code[1]);
      pc++;
    break;
    }
  }
  out.value = res;
}




成果物

以上

1
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
1
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?