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 クラスに固められている
  • 凝ったことをする場合にはカスタムアクションの定義が必要