小ネタ 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を使って動かしたみた。