小ネタ 2012-013
CIL(MSIL)中間コードを生成するTiny BASICコンパイラを作ってみた
以前に、サブセットCコンパイラの改造でIA32のコード出力とかを試した。
次にCIL(MSIL)中間コードを生成するコンパイラに改造しようと思ったものの意外に難しく、もう少し簡単な言語ということでTiny BASICコンパイラを作ってみた。(2012-09-01)
1. つくってみたもの
Tiny Basic Compiler (Tiny Basic for .NETみたいなもの)
[ Tiny Basic Compiler 実行ファイル+ソースコード tinybas01.zip (download) ]
2. 使い方
BASICのソースコードをコンパイルし、出力される.ilファイルをilasmを使ってアセンブルして.exeファイルを生成する。
順番に手順を説明すると以下のとおり。
サンプルのソースコードは例えば次のようになる。(example1.bas)
10 INPUT X
20 Y= x*x + 6*x + 9
30 PRINT Y
コマンドラインで、次のようにコマンド入力してコンパイルする。
% tinybas example1.bas
結果、example1.il が得られる。
この.il ファイルはCIL(MSIL)のアセンブリーソースコードである。
ilasmを使って.exeファイルを作る。
% ilasm example1.il
で、example1.exeが作られる。
実行するには、次のようにする。
% example1.exe
ちなみにアセンブリーソースコード(example1.ilファイル)は、以下のように生成される。
//============================================================ // Compiler: Tiny Basic Compiler Ver 0.1 // Source: example1.bas // Object: example1.il //============================================================ .assembly extern mscorlib { } .assembly basic_program { } .method static void main() { .entrypoint .maxstack 16 //------------------------------------ _L10: .locals ( int32 _V0 ) ldstr "?" call void [mscorlib]System.Console::Write(string) call string [mscorlib]System.Console::ReadLine() ldloca _V0 call bool [mscorlib]System.Int32::TryParse(string,int32&) pop _L20: .locals ( int32 _V1 ) ldloc _V0 ldloc _V0 mul ldc.i4 6 ldloc _V0 mul add ldc.i4 9 add stloc _V1 _L30: ldloc _V1 call void [mscorlib]System.Console::WriteLine(int32) //------------------------------------ _END: ret }
Ubuntu 12.04上で、bison+gcc+Monoを使って動かしたみた。