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

Posted at

概要

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"

成果物

以上。

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?