ilasmでstack machine その40

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

# 練習問題
俺言語を、ilasmに変換するコンパイラを書け。
zundokoをコンパイルせよ。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/5a264dc7-fd9f-918d-d8f6-87fa376c399e.png)


# 投入したソース

```
10 a=0
30 b=$
50 #=b<1*100
60 ?="zun "
70 a=a+1
80 #=a>3*130
90 #=30
100 ?="doko "
110 a=0
120 #=30
130 ?="doko "
140 ?="kiyosi!"
```

# 実行結果

```
.assembly extern mscorlib {}
.assembly zundoko {}
.method static void main() {
.entrypoint
.locals init (class [mscorlib]System.Random r, int32 a, int32 b)
	newobj instance void [mscorlib]System.Random::.ctor()
	stloc r
	ldc.i4	0
	stloc	a
label_30:
	ldloc r
	ldc.i4 2
	callvirt instance int32 [mscorlib]System.Random::Next(int32)
	brfalse	label_100
	ldstr "zun "
	call void [mscorlib] System.Console::WriteLine(string)
	ldloc	a
	ldc.i4	1
	add
	stloc	a
	ldloc	a
	ldc.i4	3
	bgt	label_130
	br	label_30
label_100:
	ldstr "doko "
	call void [mscorlib] System.Console::WriteLine(string)
	ldc.i4	0
	stloc	a
	br	label_30
label_130:
	ldstr "doko "
	call void [mscorlib] System.Console::WriteLine(string)
	ldstr "kiyosi!"
	call void [mscorlib] System.Console::WriteLine(string)
label_255:
	ret
}
```

# 検証

```
>ilasm zundoko4.il

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

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

>zundoko4
doko
zun
zun
doko
zun
zun
doko
doko
doko
zun
zun
doko
zun
doko
zun
doko
zun
doko
zun
doko
zun
zun
doko
doko
doko
doko
doko
doko
doko
zun
doko
zun
zun
zun
zun
doko
kiyosi!

```

# 成果物

https://embed.plnkr.co/plunk/A1WNhDJTMDl2cF65

# サンプルコード
コンパイラ

```


function putlp(d) {
  val = "";
  var n = 0;
	while (buf[ptr] != d)
	{
	  val += buf[ptr++];
	}
	val = '"' + val + '"';
}
function term() {
	f = buf[ptr++];
	factr2();
	return;
}
function term2() {
	ff = buf[ptr++];
	factr3();
	return;
}
function factr3() {
	if (buf[ptr] == '\0')
	{
		return;
	}
	t = 3;
	if (getnm4())
	{
	  return;
	}
	getvr4();
	ptr++;
	return;
}
function factr2() {
	if (buf[ptr] == '\0')
	{
		return;
	}
	t = 2;
	if (getnm3())
	{
	  return;
	}
	getvr3();
	ptr++;
	return;
}
function factr() {
	if (buf[ptr] == '\0')
	{
		val = 0;
		return;
	}
	if (getnm2())
	{
	  return;
	}
	t = 1;
	getvr2();
	ptr++;
	return;
}
function expr() {
	factr();
	if (buf[ptr] != '\0')
	{
		term();
		if (buf[ptr] != '\0')
  	{
  		term2();
  	}
	}
	ptr++;
	return;
}
function getvr4() {
	cccc = buf[ptr];
}
function getvr3() {
	ccc = buf[ptr];
}
function getvr2() {
	cc = buf[ptr];
}
function getvr() {
	c = buf[ptr];
}
function ordr() {
	getvr();
 	ptr++;
	ptr++;
	if (buf[ptr] == '"')
	{
	  t = 2;
		ptr++;
		putlp('"');
	}
	else
	{
		expr();
	}
	return;
}
function num() {
	if (48 <= (buf[ptr]).charCodeAt(0) && (buf[ptr]).charCodeAt(0) <= 57) 
		return true;
	else 
		return false;
}
function getnm4() {
	var ch;
	if (!num()) 
		return false;
	var n = 0;
	do
	{
		n *= 10;
		ch = buf[ptr++];
		n += ch.charCodeAt(0) - 48;
	} while (num());
	val3 = n;
	return true;
}
function getnm3() {
	var ch;
	if (!num()) 
		return false;
	var n = 0;
	do
	{
		n *= 10;
		ch = buf[ptr++];
		n += ch.charCodeAt(0) - 48;
	} while (num());
	val2 = n;
	return true;
}
function getnm2() {
	var ch;
	if (!num()) 
		return false;
	var n = 0;
	do
	{
		n *= 10;
		ch = buf[ptr++];
		n += ch.charCodeAt(0) - 48;
	} while (num());
	val = n;
	return true;
}
function getnm() {
	var ch;
	if (!num()) 
		return false;
	var n = 0;
	do
	{
		n *= 10;
		ch = buf[ptr++];
		n += ch.charCodeAt(0) - 48;
	} while (num());
	lin = n;
	return true;
}
var koko = document.getElementById('koko');
var out = document.getElementById('out');
var ptr;
var c;
var cc;
var ccc;
var f;
var val;
var val2;
var buf;
var t;
var lin;

function run() {
	var i;
	var str = koko.value;
	var label = {};
  var res = ".assembly extern mscorlib {}\n.assembly zundoko {}\n.method static void main() {\n.entrypoint\n.locals init (class [mscorlib]System.Random r, int32 a, int32 b)\n\tnewobj instance void [mscorlib]System.Random::.ctor()\n\tstloc r\n";
	var lines = str.split("\n");
	for (i = 0; i < lines.length; i++)
	{
	  var k = lines[i].indexOf(" #=");
	  if (k > -1) 
    {
      var lin0 = lines[i].substr(k + 3);
      k = lin0.indexOf("*");
	    if (k > -1) 
      {
        label[parseInt(lin0.substr(k + 1))] = 1;
      }
      else
      {
        label[parseInt(lin0)] = 1;
      }
    }
  }
	for (i = 0; i < lines.length; i++)
	{
	  ptr = 0;
	  c = null;
	  cc = null;
	  val = null;
	  val2 = null;
	  t = 0;
	  lin = 0;
	  buf = lines[i] + '\0';
	  getnm();
	  ptr++;
	  ordr();
	  if (label[parseInt(lin)] > 0)
	  {
      res += "label_" + lin + ":\n";
	  }
	  if (c == '?')
	  {
	    if (t == 1)
	    {
	      res += "\tldloc " + cc + "\n\tcall void [mscorlib] System.Console::WriteLine(int32)\n";
	    }
	    if (t == 2)
	    {
	      res += "\tldstr " + val + "\n\tcall void [mscorlib] System.Console::WriteLine(string)\n";
	    }
	  }
	  else if (c == '#')
	  {
	    if (t == 0)
	    {
	      res += "\tbr\tlabel_" + val + "\n";
	    }
	    if (t == 3)
	    {
	      if (cc== 'b')
	      {
	         res += "\tbrfalse\tlabel_" + val3 + "\n";
	      }
	      if (cc== 'a')
	      {
	         res += "\tldloc\ta\n\tldc.i4\t" + val2 + "\n\tbgt\tlabel_" + val3 + "\n";
	      }
	    }
	  }
	  else if (c == 'a')
	  {
	    if (t == 0)
	    {
	      res += "\tldc.i4\t" + val + "\n\tstloc\ta\n";
	    }
	    if (t == 2)
	    {
				if (f == "+") 
					f = "add";
	      res += "\tldloc\t" + cc + "\n\tldc.i4\t" + val2 + "\n\t" + f + "\n\tstloc\ta\n";
	    }
	  }
	  else if (c == 'b')
	  {
			if (cc == "$")
			{
				res +=	"\tldloc r\n\tldc.i4 2\n\tcallvirt instance int32 [mscorlib]System.Random::Next(int32)\n";
			}
	    if (t == 2)
	    {
				if (f == "%") 
					f = "rem";
	      res += "\tldloc\t" + cc + "\n\tldc.i4\t" + val2 + "\n\t" + f + "\n";
	    } 
	  }
	}
	res += "label_255:\n\tret\n}";
	out.value = res;
}




```

以上