Skip to content

Instantly share code, notes, and snippets.

@moiseev
Created February 3, 2010 11:43
Show Gist options
  • Save moiseev/293559 to your computer and use it in GitHub Desktop.
Save moiseev/293559 to your computer and use it in GitHub Desktop.
let rec toExpr (par:ParameterExpression) (clause: Clause) =
let constExpr (x:'a) =
Expression.Constant(x, typeof<'a>) |> asExpr
let callExpr (i:Expression) (m:String) (p:Expression) =
Expression.Call(i, m, Array.empty, p)
let arrExpr (xs:'a array) =
Expression.NewArrayInit(typeof<'a>, Array.map (constExpr >> asExpr) xs) |> asExpr
let inExpr (vEx:Expression) (arrEx:Expression) =
Expression.Call(typeof<Enumerable>, "Contains", [|vEx.Type|], arrEx, vEx) |> asExpr
match clause with
| Simple (l, op, r) ->
let lEx = toProperty par l
let rEx = match r with
| Number n -> constExpr n
| Str s -> constExpr s
| Numbers ns -> arrExpr ns
| Strs ss -> arrExpr ss
let equality (f:(Expression * Expression) -> BinaryExpression) =
f (lEx, rEx) |> asExpr
let call name =
callExpr lEx name rEx |> asExpr
match op with
| Eq -> equality Expression.Equal
| Neq -> equality Expression.NotEqual
| Greater -> equality Expression.GreaterThan
| Less -> equality Expression.LessThan
| GreaterOrEqual -> equality Expression.GreaterThanOrEqual
| LessOrEqual -> equality Expression.LessThanOrEqual
| Contains -> call "Contains"
| StartsWith -> call "StartsWith"
| EndsWith -> call "EndsWith"
| In -> inExpr lEx rEx
| Complex (l, logOp, r) ->
let lEx = toExpr par l
let rEx = toExpr par r
let logical (f: Expression * Expression -> BinaryExpression) =
f (lEx, rEx) |> asExpr
match logOp with
| Or -> logical Expression.Or
| And -> logical Expression.And
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment