Edited at
HaxeDay 2

Haxeの式

More than 3 years have passed since last update.

C言語の伝統に則った言語には文 statement と式 expression の区別があり、+,&&といった演算子は式を作り、ifforreturn;といったキーワードは文を作ります。一方、Haxeには構文上、文と式の区別がが存在せず、Rubyのように、C言語では文だったような構文もすべて式です。

多くの式は型と値を持ちますが、Void型の式や、単独で型や値といった意味を持たない式もあります。そのような意味を持たない式もマクロで使うことができます。


イカしたエクスプレッション紹介

enum haxe.macro.ExprDefのメンバーを紹介します。


定数式 EConst

リテラルや識別子。以下の種類があります。


  • 整数 CInt

  • 浮動小数点数 CFloat

  • 文字列 CString

  • 識別子 CIdent

  • 正規表現 CRegexp


添字アクセス式 EArray

e1[e2]の形をした、添字アクセスの式。


単項演算子式 EUnop

op eまたはe opの形をした式。opには次の種類があります。



  • OpIncrement ++


  • OpDecrement --


  • OpNot !


  • OpNeg -


  • OpNegBits ~


二項演算子式 EBinop

e1 op e2の形をした式。opには以下の種類があります。



  • OpAdd +


  • OpMult *


  • OpDiv /


  • OpSub -


  • OpAssign =


  • OpEq ==


  • OpNotEq !=


  • OpGt >


  • OpGte >=


  • OpLt <


  • OpLte <=


  • OpAnd &


  • OpOr |


  • OpXor ^


  • OpBoolAnd &&


  • OpBoolOr ||


  • OpShl <<


  • OpShr >>


  • OpUShr >>>


  • OpMod %


  • OpInterval ...


  • OpArrow =>


  • OpAssignOp(op:Binop) += -= /= *= <<= >>= >>>= |= &= ^= %=


フィールドアクセス式 EField

e.fieldの形をした式。


括弧式 EParenthesis

(e) の形をした式。


オブジェクト宣言式 EObjectDecl

{field: expr, ...}の形をした、匿名構造体を宣言する式。


配列宣言式 EArrayDecl

[e, ...]の形をした、配列を宣言する式。連想配列や内包記法も内部表現はこの式になります。


呼出し式 ECall

e1(e2, ...)の形をした、関数呼出しの式。


newENew

new T(e, ...)の形をした式。


varEVar

var x = e, ...の形をした、変数を宣言する式。値はVoid


functionEFunction

function f<T>(arg, ...) eの形をした、関数を宣言する式。


ブロック式 EBlock

{e; ...}の形をした式。ブロック式中一番最後の式の値が、ブロック式全体の値となります。


forEFor

for (e1) e2の形をした式。値はVoid。内包記法にも使われます。


inEIn

e1 in e2の形をした式。基本的にfor式の中で使われます。


ifEIf

if (e1) e2 else e3の形をした式。else節がある場合、e1の値に応じて、e2またはe3の値がif式全体の値となります。


whileEWhile

while (e1) e2またはdo e1 while(e2)の形をした式。値はVoid


switchESwitch

switch e1 {case e2, ... if (e3): e4; ...}の形をした式。e1の値に応じて、各ケースいずれかがswitch式全体の値となる。マクロ以外ではe1の部分を括弧で括られた(e)か配列の[e, ...]の形のどちらかにしなければなりません。


tryETry

try e1 catch (x: T) e2 ...の形をした式。e1または例外を捕捉したcatch節の値を返します。


returnEReturn

return eの形をした式。Dynamic型として扱われます。


breakEBreak, continueEContinue

breakcontinueも式。return式同様Dynamic型として扱われます。


untypedEUntyped

untyped eの形をした式。eの型を無視した型が付きます。


throwEThrow

throw eの形をした式。例外を投げます。


castECast

cast eまたはcast(e, T)の形をした式。型キャストを行います


三項演算子式 ETernary

e1 ? e2 : e3の形をした式。これの代わりにif式があるので必要ありません。


型検査式 ECheckType

e : Tの形をした式。eの型がTであることをコンパイル時に検査する。マクロ以外では全体を括弧で括って(e : T)の形で使わなければなりません。


メタデータ式 EMeta

@m(p, ...) e@:m(p, ...) e, $m{e}の形をした式。マクロなどで使います。


macro

抽象構文木にmacro式は存在しません。これはシンタックスシュガーで、macroを使った表現は、内部で他の式を使った表現に置き換わります。


意味を持たない式

例えばin式は単独では意味を持たず、普通はfor式と組み合わせて使う必要があります。しかし、マクロに与える式の場合には、抽象構文木を書き換えてしまうわけで、式が意味を持たないことは問題となりません。意味を持たない式を使っている具体例として、hxparseのパーサーswitch streamを使った記法が挙げられます。


曖昧な式

空のオブジェクト宣言式と空のブロック式はどちらも{}という表現で、区別が付きません。構文解析の段階では空のブロック式としてパースしておき、その後の処理で文脈を見て空のオブジェクト宣言か空のブロックかを判断しているようです。気をつけておかないと、マクロを書くときに引っかかりそうですね。


ASTを簡単に調べる方法

ihxを使うと簡単に抽象構文木を調べられます。

% haxelib run ihx

haxe interactive shell v0.3.4
type "help" for help
>> macro [for (x in a) if (p(x)) f(x)]
haxe.macro.Expr : { expr => EArrayDecl([{ expr => EFor({ expr => EIn({ expr => EConst(CIdent(x)), pos => { file => /tmp/IhxProgram_8249.hx, max => 235, min => 234 } },{ expr => EConst(CIdent(a)), pos => { file => /tmp/IhxProgram_8249.hx, max => 240, min => 239 } }), pos => { file => /tmp/IhxProgram_8249.hx, max => 240, min => 234 } },{ expr => EIf({ expr => ECall({ expr => EConst(CIdent(p)), pos => { file => /tmp/IhxProgram_8249.hx, max => 247, min => 246 } },[{ expr => EConst(CIdent(x)), pos => { file => /tmp/IhxProgram_8249.hx, max => 249, min => 248 } }]), pos => { file => /tmp/IhxProgram_8249.hx, max => 250, min => 246 } },{ expr => ECall({ expr => EConst(CIdent(f)), pos => { file => /tmp/IhxProgram_8249.hx, max => 253, min => 252 } },[{ expr => EConst(CIdent(x)), pos => { file => /tmp/IhxProgram_8249.hx, max => 255, min => 254 } }]), pos => { file => /tmp/IhxProgram_8249.hx, max => 256, min => 252 } },null), pos => { file => /tmp/IhxProgram_8249.hx, max => 256, min => 242 } }), pos => { file => /tmp/IhxProgram_8249.hx, max => 256, min => 229 } }]), pos => { file => /tmp/IhxProgram_8249.hx, max => 257, min => 228 } }

よきマクロ生活をお過ごしください。