概要
ilasmでstack machineやってみた。
練習問題やってみた。
練習問題
日本語プログラミング言語のMindで、ilasmのインタープリタを書け。
fizzbuzzを実行せよ。
サンプルコード
コードは 50個の 文字列。
コード数は 変数。
スタック1は 変数。
スタック2は 変数。
nは 変数。
iは 変数。
文字列スタックは 文字列。
アセンブラとは
コード(コード数)に 入れ
コード数に 1を 加えて コード数に 入れる
。
行検索とは
文字列1は 文字列
単語1は 文字列
ラベル1は 文字列
数2は 変数
pcは 変数
ラベル1に 入れ
ラベル1に 「:」を 合成し ラベル1に 入れ
数2に 5を 入れ
pcに 1を 入れ
ここから
もし pcが コード数より 大きい
ならば
終り
つぎに
コード(pc)を 文字列1に 入れ
文字列1から 単語切り出し 単語1に 入れ
もし 単語1が ラベル1に 等しい文字列
ならば
数2に pcを 入れ
打ち切り
つぎに
pcに 1を 加えて pcに 入れる
繰り返す
※ 数2を 数値表示し 改行する
数2を 返す
。
RUNとは
文字列1は 文字列
単語1は 文字列
単語2は 文字列
単語3は 文字列
数1は 変数
数2は 変数
合否は 変数
pcは 変数
スタック1に 0を 入れ
スタック2に 0を 入れ
nに 0を 入れ
iに 0を 入れ
pcに 1を 入れ
ここから
もし pcが コード数より 大きい
ならば
終り
つぎに
コード(pc)を 文字列1に 入れ
文字列1から 単語切り出し 単語1に 入れ
文字列1から 単語切り出し 単語2に 入れ
文字列1から 単語切り出し 単語3に 入れ
もし 単語1が 「ret」に 等しい文字列
ならば
打ち切り
つぎに
もし 単語1が 「rem」に 等しい文字列
ならば
スタック2と スタック1を 剰余し スタック1に 入れる
つぎに
もし 単語1が 「add」に 等しい文字列
ならば
スタック2と スタック1を 加えて スタック1に 入れる
つぎに
もし 単語1が 「call」に 等しい文字列
ならば
もし 単語3が 「[mscorlib]System.Console::WriteLine(int32)」に 等しい文字列
ならば
スタック1を 数値表示し 改行し
さもなければ
文字列スタックを 一行表示し
つぎに
つぎに
もし 単語1が 「ldloc」に 等しい文字列
ならば
もし 単語2が 「n」に 等しい文字列
ならば
スタック2に スタック1を 入れ
スタック1に nを 入れる
つぎに
もし 単語2が 「i」に 等しい文字列
ならば
スタック2に スタック1を 入れ
スタック1に iを 入れる
つぎに
つぎに
もし 単語1が 「stloc」に 等しい文字列
ならば
もし 単語2が 「n」に 等しい文字列
ならば
nに スタック1を 入れる
スタック1に スタック2を 入れ
つぎに
もし 単語2が 「i」に 等しい文字列
ならば
iに スタック1を 入れる
スタック1に スタック2を 入れ
つぎに
つぎに
もし 単語1が 「bgt」に 等しい文字列
ならば
もし スタック1より スタック2が 大きい
ならば
スタック1に 1を 入れる
単語2で 行検索し pcに 入れる
つぎに
つぎに
もし 単語1が 「brfalse」に 等しい文字列
ならば
もし スタック1より 1が 大きい
ならば
単語2で 行検索し pcに 入れる
つぎに
つぎに
もし 単語1が 「br」に 等しい文字列
ならば
単語2で 行検索し pcに 入れる
つぎに
もし 単語1が 「ldc.i4」に 等しい文字列
ならば
単語2を 数値変換し 数1と 合否に 入れ
もし 合否が 真?
ならば
スタック2に スタック1を 入れ
スタック1に 数1を 入れる
つぎに
つぎに
もし 単語1が 「ldstr」に 等しい文字列
ならば
文字列スタックに 単語2を 入れる
つぎに
pcに 1を 加えて pcに 入れる
※ pcを 数値表示し 「,」を 表示し スタック1を 数値表示 「,」を 表示し スタック2を 数値表示 「,」を 表示し nを 数値表示し 「,」を 表示し iを 数値表示し 改行する
繰り返す
。
メインとは
コードを クリアし
1を コード数に 入れ
「 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 」を アセンブラし RUNする
。
実行結果
c:\pmind>il1
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"
以上。