Skip to content

Instantly share code, notes, and snippets.

@takeshik
Created June 18, 2011 10:51
Show Gist options
  • Save takeshik/1032988 to your computer and use it in GitHub Desktop.
Save takeshik/1032988 to your computer and use it in GitHub Desktop.
Yacq クエリ言語の簡単な説明
使用方法
using XSpect.Yacq;
Yacq.Parse("'write code here!'");
// コードを表す何らかの Expression が返る
Yacq.ParseLambda<Func<int, int>>(@"(\ [x:Int32] (+ x 10))");
// Expression<Func<int, int>> が返る
Expression.Lambda(Yacq.Parse("...")); // LambdaExpression
とか。
Expression Trees に不慣れな方へ。
Yacq.ParseLambda<Func<int, int>>(@"(\ [x:Int32] (+ x 10))")
// ↑ is Expression<Func<int, int>>
.Compile()
// ↑ is Func<int, int>
(123);
// ↑ is int
Expression.Lambda(Yacq.Parse("..."))
// ↑ is LambdaExpression
.Compile()
// ↑ is Delegate
.DynamicInvoke(); // or cast this delegate!
// ↑ is object
全ての識別子および文字列は大小文字を区別されます。
コメント
; コメント (行末まで)
一般的なリテラル
数値
-123
1_23_4 ; 1234。_ は全て無視される
0b10101 ; 2進
0o644 ; 8進
0xbeef ; 16進
1.23e-4 ; 指数表記
1.234f ; Single 型強制
型は値の範囲により適切に決定されるはずです。
文字列
"foo" ; String
'foo' ; String
"f" ; String
'f' ; Char
`foo` も `f` も String として扱われていたような気がする。
エスケープ文字、コード埋め込み文字列その他は未実装です。
真偽値
true
false
null
nil
動作としては VB の Nothing (C# の default(T)) と同等にするつもりですが未実装。
現状は null と同等…なはず。
配列
[1 2 3 4 5] ; new int[] { 1, 2, 3, 4, 5, }
[1 2 'foo'] ; new object[] { 1, 2, 'foo', }
要素の型が一致しない場合は全て object[] になります。
算術演算子
+ 加算 / 単項 +
- 減算 / 単項 -
* 乗算
/ 除算
** 冪乗
% 剰余
<< 左シフト
>> 右シフト
++ インクリメント
-- デクリメント
論理演算子
! 論理否定
~ 1 の補数
< 未満
<= 以下
> 超過
>= 以上
== 等価
!= 不等価
=== 参照等価
!== 参照不等価
& 論理積
| 論理和
^ 排他的論理和
&& 論理積 (短絡評価)
|| 論理和 (短絡評価)
使用例
(+ 1 2 (- 3)) ; 1 + 2 + (-3)
(* (- 3 1) (+ 2 4)) ; (3 - 1) * (2 + 4)
代入演算は未実装です。
大抵の算術演算子は (/ x y z) と書くと (/ (/ x y) z) となったり左結合。
あるいは (&& x y z) で (&& (&& x y) z) と。
(不)等号の類は (< x y z) だと (&& (< x y) (< y z)) と展開される。
関数リテラルおよびコードリテラル
(\ [x y] (+ x y))
; (x, y) => x + y
(\ [x:Int32 y:Int32] (+ x y))
; (int x, int y) => x + y
(\ [x:Int32 y:Int32] (+ x y) (- x y))
; (int x, int y) => { x + y; return x - y; }
(\ [x:Int32] (\ [y:Int32] (\ [z:Int32] (+ x y z))))
; (int x) => (int y) => (int z) => x + y + z
(\ (+ x y))
; { x + y; }
(\ (+ x y) (- x y))
; { x + y; x - y; }
型推論が実装されました。だいたい動くと思います。たぶん。
foo:T と書けば型を明示することも出来ます。
全ての引数の型を明示してください。
関数適用
((\ [x:Int32 y:Int32] (+ x y)) 123 456)
; ((int x, int y) => x + y)(123, 456)
関数オブジェクトが最初の値であるリストは関数適用式となり、リストの残りの部分が引数になります。
オブジェクト操作
Action.[Int32 Int32]
型パラメタの指定
str.Length
プロパティおよびフィールド呼び出し
Int32.MaxValue
同上 (static 呼び出し)
value.(ToString)
メソッド呼び出し
str.(Replace 'a' 'b')
同上
String.(Concat "a" "b")
同上 (static 呼び出し)
list.(OfType.[Int32])
同上 (ジェネリックメソッド呼び出し)
list.(Sum)
同上 (ジェネリックメソッド呼び出し: 型の推論)
(Tuple.[Int32 Int32] 123 456)
コンストラクタ呼び出し
(Double 123)
型キャスト
(引数の一致するコンストラクタが無い場合の挙動)
マクロ
obj.(as T)
C# における obj as T。
obj.(is T)
C# における obj is T。
obj.(let x (* x 2))
第 1 引数で提示された識別子に obj を束縛し、その環境下で第 2 引数の式を返す。
上の例では (* obj 2) となる。
obj.(cond 'true' 'false')
obj を評価し true なら第 1 引数の、false なら第 2 引数の式を返す。
C# における ?: 演算子。
(input)
標準入力から入力を受ける。Console.ReadLine()。
obj.(print)
標準出力にオブジェクトを出力する。Console.WriteLine(obj)。
デフォルトでインポートされている型
Object
Boolean
Char
String
SByte
Byte
Int16
UInt16
Int32
UInt32
Int64
UInt64
IntPtr
Single
Double
Decima
DateTime
DateTimeOffset
TimeSpan
Guid
Math
Convert
Tuple
Regex
Enumerable
EnumerableEx
Queryable
Observable
Qbservable
Action (Action, ..., Action`16)
Func (Func`1, ..., Func`17)
バグ
たくさん。
* コメントの挙動が変。tokenize で停止する可能性があるらしい?
* うそっ…私の謎クエリ、重すぎ…?
* たまにメンバの解決や型推論がうまくいかないことがあるかも
* 他
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment