DLR で俺言語を作ってみる講座:第3回目
id:SiroKuro:20070923:1190558118 の続き。時間あけると良くないね。
Microsoft.Scripting.Ast.Ast クラス
さて、DLR の AST を作成するメソッドが大量に納められているのがこの Ast クラスです。DLR の AST は "CodeBlock" "Statement" "Expression" の3種類に分かれてます。このあたりは Python の流儀に沿っていると考えてください。
Expression(式)
例えば Ast クラスには次のような名前の static メソッドが用意されています。これらは全て Expression クラスのサブクラスを返すメソッドです。
ちなみにこれで全部じゃないです。まだありますが主なものだけ抜き出しました。
定数 | Constant, True, False, Null, Zero, Void |
四則演算 | Add, Subtract, Multiply, Divide, TrueDivide, Modulo, Negate |
ビット演算 | And, Or, ExclusiveOr |
等値演算 | Equal, NotEqual |
比較演算 | GreaterThan, GreaterThanEquals, LessThan, LessThanEquals |
論理演算 | CoalesceTrue, CoalesceFalse, Not |
代入演算 | Assign, AssignField, AssignProperty |
変数参照 | Read, ReadField, ReadProperty |
del演算 | Delete |
new演算 | New, NewArray |
シフト演算 | LeftShift, RightShift |
メソッド呼び出し | Call, CallWithThis |
型演算 | Cast, TypeIs |
条件演算 | Condition |
コンマ演算 | Comma |
その他 | CodeBlockExpression, CodeContext |
例えば、1 + 2 * 3 を行うときは
Ast.Add(Ast.Constant(1), Ast.Multiply(Ast.Constant(2), Ast.Constant(3)))
といった感じになります。
型付きの Expression
面白いことに、DLR の Expression は型付きです。しかもこれらのメソッドはだいぶ型にうるさいです。
例えば Add は Expression を2つとりますが、その2つの式の型が異なっていたり、型が数値型でない場合には容赦なく例外を出してきます。
そのため 1 + 2.0 を Ast.Add を用いて行いたい場合などでは
Ast.Add(Ast.Cast(Ast.Constant(1), typeof(double)), Ast.Constant(2.0))
とする必要があります。
デフォルトアクションとカスタムアクション
しかしさすがに記述が煩わしいですし、そもそも "abc" + "def" のような場合には Ast.Add を使用することができません。しかし文字列加算のような数値加算以外の動作―アクションは DLR には用意されていないので、アクションを自分で用意する必要があります。
上で紹介したメソッドは、全て DLR のデフォルトアクションを実行する AST を作成するメソッドです。一方、言語製作者が自分で定義したカスタムアクションを実行する AST を作成することも出来ます。
Ast.Action.Operator(Operators.Add, typeof(string), Ast.Constant("abc"), Ast.Constant("def"))
このようにすると "abc" + "def" を実行して string を返す Expression を作成することが出来ます。
何を実行するかはカスタムアクションとして ActionBinder にて定義することになりますが、その解説は後の記事にて行うことにして、次は Statement の解説と行こうかと思ってます。
まとめ
- DLR の AST は主に CodeBlock, Statement, Expression の3要素から構成される
- Expression は式を表す。Expression には型がある。
- DLR にはデフォルトとなるアクションが既に定義されている
- デフォルトアクションを実行する Expression を作成するメソッドが Microsoft.Scripting.Ast.Ast クラスに固められている
- 凝ったことをする場合にはカスタムアクションの定義が必要