scalaをマクロアセンブラのマクロ用言語にしてます
最近、川で遊んでて、emobileを流してしまったので、家でネットが出来ません。
かってくればいいんだけど、買いにいく気力がない。
ってことで、家だと黙々プログラム組むしかないんで、時間が出来たらアセンブラをいじってます。
昨日やったのは、Scalaの関数でアセンブラを出力する。
def movl(a:String, b:String) { p.println("movl "+a+","+b) } : :
さらに、マクロアセンブラのマクロっぽい物をScalaの関数で作る。
def beginFunction(s:String) { globl("_"+s) label("_"+s) pushq("%ebp") movq("%esp", "%ebp") } : :
ってかんじの関数を作って使う。
ということをやってました。
でそろそろ、変数の領域を自動確保する機能を作りたくなってきた。
ってかんじで、コンパイラがない時代からコンパイラを作りたくなってきた時代の感じを体験中です。
コンパイラの普通の教科書だと結構、確立されたコンパイラの作り方がいきなり乗っていて、それが敷居が高い感があるので、
アセンブラをいじりつつ、徐々に、コンパイラが欲しい前段階に進んで、コンパイラの前進的なところを作っていくことで、
理解を深めよう作戦です。
てことで、
a=1;b=2; c=a+b; d=c*3; printInt(d)
なんてプログラムをコンパイル出来るプログラムを作ってます。
複雑な式は計算できないけど、変数は使えて、case classだけ使って書くと
List( Eq(Var("a"),IntV(1)), Eq(Var("b"),IntV(2)), Add(Var("c"),Var("a"),Var("b")), Mul(Var("d"),Var("c"),IntV(3)), PrintInt(Var("d")) )
こんなプログラムをコンパイルして実行するプログラムです。
変数の名前がいくつあるかを計算して、変数名からアドレスのマップを作って、
関数呼び出しが出来ればいいわけです。
def funTest() { beginFunction("test"); compile(List( Eq(Var("a"),IntV(1)), Eq(Var("b"),IntV(2)), Add(Var("c"),Var("a"),Var("b")), Mul(Var("d"),Var("c"),IntV(3)), PrintInt(Var("d")) )); endFunction() }
で、test関数のアセンブラが出力されるという。
とまぁ、こんな感じで進んでおります。