ilasmでstack machine その53

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

# 練習問題
Rustでilasmを実行する、インタープリタを書け。
fizzbuzzを実行せよ。

# サンプルコード

```
const MAXVAL: usize = 10;
fn push(val: &mut [f32; MAXVAL], sp: &mut i32, op: f32) {
	if *sp < MAXVAL as i32
	{
		val[*sp as usize] = op;
		*sp += 1;
	}
	else
	{
		println!("error: stack full, can't push {}", op);
	}
}
fn pop(val: &mut [f32; MAXVAL], sp: &mut i32) -> f32 {
	if *sp > 0
	{
		*sp -= 1;
		return val[*sp as usize];
	}
	else
	{
		println!("error: stack empty");
		return 0.0;
	}
}
fn jmp(s: &str, l: &str) -> usize {
	let mut pc: usize = 0;
	let mut v: Vec<&str> = s.split('\n').collect();
	//println!("{:?}", v[0]); 
	loop
	{
		let cs: Vec<&str> = v[pc].split_whitespace().collect::<Vec<_>>();
		//println!("{:?}", cs);
		if cs[0] == format!("{}:", l)
		{
			break;
		}
		pc = pc + 1
	}
	return pc;
}
fn ilasm(s: &str) {
	let mut sp: i32 = 0;
	let mut n: f32 = 0.0;
	let mut i: f32 = 0.0;
	let mut pc: usize = 0;
	let mut lp: usize = 0;
	let mut bu: &str = "";
	let mut val: [f32; MAXVAL] = [0.0; MAXVAL];
	//println!("{}", s);
	let mut v: Vec<&str> = s.split('\n').collect();
	//println!("{:?}", v[0]); 
	loop
	{
		//println!("{:?}", pc);
		if lp > 2500
		{
			break;
		}
		if pc > v.len() - 1
		{
			break;
		}
		let cs: Vec<&str> = v[pc].split_whitespace().collect::<Vec<_>>();
		//println!("{:?}", cs);
		match cs[0]
		{
		"bgt" => {
			let right = pop(&mut val, &mut sp);
			let left = pop(&mut val, &mut sp);
			if left > right
			{
				pc = jmp(s, cs[1]);
			}
		}
		"brfalse" => {
			if pop(&mut val, &mut sp) == 0.0
			{
				pc = jmp(s, cs[1]);
			}
		}
		"br" => {
			pc = jmp(s, cs[1]);
		}
		"ldstr" => {
			bu = cs[1];
		}
		"ldc.i4" => {
			let number: f32 = cs[1].parse::<f32>().expect("REASON");
			push(&mut val, &mut sp, number);
		}
		"stloc" => {
			if cs[1] == "n"
			{
				n = pop(&mut val, &mut sp);
			}
			if cs[1] == "i"
			{
				i = pop(&mut val, &mut sp);
			}
		}
		"ldloc" => {
			if cs[1] == "n"
			{
				push(&mut val, &mut sp, n);
			}
			if cs[1] == "i"
			{
				push(&mut val, &mut sp, i);
			}
		}
		"add" => {
			let right = pop(&mut val, &mut sp);
			let left = pop(&mut val, &mut sp);
			push(&mut val, &mut sp, left + right);
		}
		"sub" => {
			let right = pop(&mut val, &mut sp);
			let left = pop(&mut val, &mut sp);
			push(&mut val, &mut sp, left - right);
		}
		"mul" => {
			let right = pop(&mut val, &mut sp);
			let left = pop(&mut val, &mut sp);
			push(&mut val, &mut sp, left * right);
		}
		"div" => {
			let right = pop(&mut val, &mut sp);
			let left = pop(&mut val, &mut sp);
			push(&mut val, &mut sp, left / right);
		}
		"rem" => {
			let right = pop(&mut val, &mut sp);
			let left = pop(&mut val, &mut sp);
			push(&mut val, &mut sp, left % right);
		}
		"call" => {
			if cs[3] == "System.Console::WriteLine(int32)"
			{
				let right = pop(&mut val, &mut sp);
				println!("{}", right);
			}
			if cs[3] == "System.Console::WriteLine(string)"
			{
				println!("{}", bu);
			}
		}
		"dup" => {
			let right = pop(&mut val, &mut sp);
			push(&mut val, &mut sp, right);
			push(&mut val, &mut sp, right);
		}
		"pop" => {
			let right = pop(&mut val, &mut sp);
		}
		_ => {
			//println!("{}", cs[0]);
		}
		}
		pc = pc + 1;
		lp = lp + 1;
	}
}

fn main() {
    ilasm("    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"
```

# 成果物

https://paiza.io/projects/OdlK4rVp7mMCX_g0i8x_EQ


以上。