Io における演算子拡張
Io は演算子の Map を内部に持っていて、パース時にそれを参照する。
例えば =~ は定義されていないので
Message fromString("\"abc\" =~ \"a.\"") code print
#=> "abc" =~ "a."となり、これだと =~ というメッセージを定義しても、後ろの文字列 (Sequence) は =~ メッセージの引数とは解釈されない。"abc" =~ と "a." は別の文になるわけです。
しかしながらこれは拡張することができて
OperatorTable addOperator("=~", 7)
Message fromString("\"abc\" =~ \"a.\"") code print
#=> "abc" =~("a.")ということができる。7 は演算子の優先順で、OperatorTable print すれば登録済みの演算子とその優先順位がわかる。
Operators
0 ' ( ) . ? @ @@
1 **
2 ++ --
3 % * /
4 + -
5 << >>
6 < <= > >=
7 != ==
8 &
9 ^
10 |
11 && and
12 or ||
13 ..
14 %= &= *= += -= -> /= <- <-> <<= >>= ^= |=
15 return
16 ,
Assign Operators
::= newSlot
:= setSlot
= updateSlot
To add a new operator: OperatorTable addOperator("+", 4) and implement the + message.
To add a new assign operator: OperatorTable addAssignOperator("=", "updateSlot") and implement the updateSlot message.ところで若干のハマりどころなのは、
Object =~ := method(s,
call message print
)
OperatorTable addOperator("=~", 7)
"abc" =~ "a."とやっても、"abc" =~ "a." をパースする時点では addOperator はまだ評価されていないので、演算子にはならない。doString とかでこのあとにパースされるようにしないといけない。実際つかうとするとファイルをわけて doFile みたいになると思う。
Io かっけー