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に変換するコンパイラを書け。
数9を4個つかって1から15までの数を表す式をコンパイルせよ。

写真

image.png

投入したソース

d1:
  数値 9 を積み
  数値 9 を積み
  引く
  数値 9 を積み
  数値 9 を積み
  割る
  足す
  数値印字し
d2:
  数値 9 を積み
  数値 9 を積み
  割る
  数値 9 を積み
  数値 9 を積み
  割る
  足す
  数値印字し
d3:
  数値 9 を積み
  数値 9 を積み
  足す
  数値 9 を積み
  足す
  数値 9 を積み
  割る
  数値印字し
d4:
  数値 9 を積み
  数値 9 を積み
  足す
  数値 9 を積み
  割る
  数値 9 を積み
  捨てる
  コピペし
  足す
  数値印字し
d5:
  数値 9 を積み
  数値 9 を積み
  数値 9 を積み
  足す
  数値 9 を積み
  割る
  コピペし
  足す
  引く
  数値印字し
d6:
  数値 9 を積み
  コピペし
  数値 9 を積み
  足す
  数値 9 を積み
  足す
  数値 9 を積み
  割る
  引く
  数値印字し
d7:
  数値 9 を積み
  数値 9 を積み
  数値 9 を積み
  足す
  数値 9 を積み
  割る
  引く
  数値印字し
d8:
  数値 9 を積み
  数値 9 を積み
  数値 9 を積み
  割る
  引く
  数値 9 を積み
  捨てる
  数値印字し
d9:
  数値 9 を積み
  数値 9 を積み
  引く
  数値 9 を積み
  掛ける
  数値 9 を積み
  足す
  数値印字し
d10:
  数値 9 を積み
  数値 9 を積み
  割る
  数値 9 を積み
  足す
  数値 9 を積み
  捨てる
  数値印字し
d11:
  数値 9 を積み
  数値 9 を積み
  数値 9 を積み
  足す
  数値 9 を積み
  割る
  足す
  数値印字し
d12:
  数値 9 を積み
  コピペし
  数値 9 を積み
  数値 9 を積み
  足す
  足す
  数値 9 を積み
  割る
  足す
  数値印字し
d13:
  数値 9 を積み
  数値 9 を積み
  数値 9 を積み
  足す
  数値 9 を積み
  割る
  コピペし
  足す
  足す
  数値印字し
d14:
  数値 9 を積み
  コピペし
  数値 9 を積み
  数値 9 を積み
  足す
  数値 9 を積み
  割る
  コピペし
  足す
  引く
  足す
  数値印字し
d15:
  数値 9 を積み
  コピペし
  コピペし
  数値 9 を積み
  足す
  数値 9 を積み
  足す
  数値 9 を積み
  割る
  引く
  足す
  数値印字し
  終わり。


実行結果

.assembly extern mscorlib {}
.assembly d94 {}
.method static void main() {
.maxstack 8
.entrypoint
d1:
  ldc.i4   9
  ldc.i4   9
  sub
  ldc.i4   9
  ldc.i4   9
  div
  add
  call void [mscorlib]System.Console::WriteLine(int32)
d2:
  ldc.i4   9
  ldc.i4   9
  div
  ldc.i4   9
  ldc.i4   9
  div
  add
  call void [mscorlib]System.Console::WriteLine(int32)
d3:
  ldc.i4   9
  ldc.i4   9
  add
  ldc.i4   9
  add
  ldc.i4   9
  div
  call void [mscorlib]System.Console::WriteLine(int32)
d4:
  ldc.i4   9
  ldc.i4   9
  add
  ldc.i4   9
  div
  ldc.i4   9
  pop
  dup
  add
  call void [mscorlib]System.Console::WriteLine(int32)
d5:
  ldc.i4   9
  ldc.i4   9
  ldc.i4   9
  add
  ldc.i4   9
  div
  dup
  add
  sub
  call void [mscorlib]System.Console::WriteLine(int32)
d6:
  ldc.i4   9
  dup
  ldc.i4   9
  add
  ldc.i4   9
  add
  ldc.i4   9
  div
  sub
  call void [mscorlib]System.Console::WriteLine(int32)
d7:
  ldc.i4   9
  ldc.i4   9
  ldc.i4   9
  add
  ldc.i4   9
  div
  sub
  call void [mscorlib]System.Console::WriteLine(int32)
d8:
  ldc.i4   9
  ldc.i4   9
  ldc.i4   9
  div
  sub
  ldc.i4   9
  pop
  call void [mscorlib]System.Console::WriteLine(int32)
d9:
  ldc.i4   9
  ldc.i4   9
  sub
  ldc.i4   9
  mul
  ldc.i4   9
  add
  call void [mscorlib]System.Console::WriteLine(int32)
d10:
  ldc.i4   9
  ldc.i4   9
  div
  ldc.i4   9
  add
  ldc.i4   9
  pop
  call void [mscorlib]System.Console::WriteLine(int32)
d11:
  ldc.i4   9
  ldc.i4   9
  ldc.i4   9
  add
  ldc.i4   9
  div
  add
  call void [mscorlib]System.Console::WriteLine(int32)
d12:
  ldc.i4   9
  dup
  ldc.i4   9
  ldc.i4   9
  add
  add
  ldc.i4   9
  div
  add
  call void [mscorlib]System.Console::WriteLine(int32)
d13:
  ldc.i4   9
  ldc.i4   9
  ldc.i4   9
  add
  ldc.i4   9
  div
  dup
  add
  add
  call void [mscorlib]System.Console::WriteLine(int32)
d14:
  ldc.i4   9
  dup
  ldc.i4   9
  ldc.i4   9
  add
  ldc.i4   9
  div
  dup
  add
  sub
  add
  call void [mscorlib]System.Console::WriteLine(int32)
d15:
  ldc.i4   9
  dup
  dup
  ldc.i4   9
  add
  ldc.i4   9
  add
  ldc.i4   9
  div
  sub
  add
  call void [mscorlib]System.Console::WriteLine(int32)
  ret
}

検証

>ilasm d9.il

Microsoft (R) .NET Framework IL Assembler.  Version 4.8.9105.0
Copyright (c) Microsoft Corporation.  All rights reserved.
Assembling 'd9.il'  to EXE --> 'd9.exe'
Source file is UTF-8

Assembled global method main
Creating PE file

Emitting classes:

Emitting fields and methods:
Global  Methods: 1;

Emitting events and properties:
Global
Writing PE file
Operation completed successfully

>d9
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

成果物

サンプルコード

コンパイラ


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 i = 1;
  var res = ".assembly extern mscorlib {}\n.assembly d94 {}\n.method static void main() {\n.maxstack 8\n.entrypoint\n";
  while (i > 0)
  {
    var code = codes[pc].split(" ");
    switch (code[1])
    {
    case "入力し":  
      res += "  call string [mscorlib]System.Console::ReadLine()\n";
      pc++;
    break;
    case "乱数召喚し":  
      res += "  newobj instance void [mscorlib]System.Random::.ctor()\n";
      pc++;
    break;
    case "文字列":
      res += "  ldstr    " + code[2] + "\n";
      pc++;
    break;
    case "数値":
      res += "  ldc.i4   " + code[2] + "\n";
      pc++;
    break;
    case "変数":   
      if (code[3] == "を積み")
        res += "  ldloc    " + code[2] + "\n";
      if (code[3] == "に移動し")
        res += "  stloc    " + code[2] + "\n";
      pc++;
    break; 
    case "数値印字し":
      res += "  call void [mscorlib]System.Console::WriteLine(int32)\n";
      pc++;
    break;
    case "文字印字し":
      res += "  call void [mscorlib]System.Console::Write(string)\n";
      pc++;
    break;
    case "文字列印字し":
      res += "  call void [mscorlib]System.Console::WriteLine(string)\n";
      pc++;
    break;
    case "真なら": 
      res += "  brtrue   "+ code[2] + "\n";
      pc++;
    break;
    case "偽なら": 
      res += "  brfalse  "+ code[2] + "\n";
      pc++;
    break;      
    case "比べて大なら":  
      res += "  bgt      "+ code[2] + "\n";
      pc++;
    break;
    case "捨てる":  
      res += "  pop\n";
      pc++;
    break;
    case "コピペし":  
      res += "  dup\n";
      pc++;
    break;
    case "足す":  
      res += "  add\n";
      pc++;
    break;
    case "掛ける":  
      res += "  mul\n";
      pc++;
    break;
    case "引く":  
      res += "  sub\n";
      pc++;
    break;
    case "割る":  
      res += "  div\n";
      pc++;
    break;
    case "剰余し":  
      res += "  rem\n";
      pc++;    
    break;
    case "乱数し":  
      res += "  callvirt instance int32 [mscorlib]System.Random::Next(int32)\n";
      pc++;    
    break;
    case "長さし":  
      res += "  callvirt instance int32 [mscorlib]System.String::get_Length()\n";
      pc++;    
    break;
    case "切り出し":  
      res += "  callvirt instance string [mscorlib]System.String::Substring(int32, int32)\n";
      pc++;    
    break;
    case "無条件で": 
      res += "  br       "+ code[2] + "\n";
      pc++;
    break;
    case "終わり。":  
      res += "  ret\n}\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?