haXeで作るプログラミング言語(13)
縁起を担いで2回にわけます。
シンボル
今回はシンボルという概念を導入することで、識別子と文字列を分けて考えることができるようにします。
シンボルはRubyやLispではおなじみの概念ですが、他の言語では聞きなれないものかと思います。
識別子は変数名やキーワードにあたります。たとえば変数ならa、b、stack,tmpとかです。
キーワードはifやfor,swith,case等になります。
前回までの処理系では実は文字列という概念はなくて、シンボルのみが存在していたとも言えると思います。
ということで、シンボルの実装をしていきましょう。
とりあえず、全部チェック
function macroExpand(a:Exp, e:Hash<Exp>):Exp { switch(a) { case op(l, tag, r): return op(macroExpand(l, e),tag,macroExpand(r)); case fun(prm, body, env): return fun(macroExpand(l), macroExpand(body), env); default return a; } }
add(a,b)をa+bにするシンタックスシュガー
function macroExpand(a:Exp, e:Hash<Exp>):Exp { switch(a) { case op(l, tag, r): switch(l){ case sym(s): if(s=="add" && tag=="M()") { var rr:Exp = r; switch(rr) { case op(aa, tag2, bb): if(tag2=="L,") { return op(macroExpand(aa,e),"L+",macroExpand(bb,e)); } default: } } else default: } return op(macroExpand(l, e),tag,macroExpand(r,e)); case fun(prm, body, env): return fun(macroExpand(prm,e), macroExpand(body,e), env); default: return a; } }
次にすべてのパターンにマッチするようにする。