Skip to content

Instantly share code, notes, and snippets.

@moiseev
Created February 5, 2010 09:02
Show Gist options
  • Save moiseev/295663 to your computer and use it in GitHub Desktop.
Save moiseev/295663 to your computer and use it in GitHub Desktop.
let 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
let simpleF props condition value =
let lEx = toProperty par props
let rEx = match value 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 condition 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
let complexF left logOp right =
let logical (f: Expression * Expression -> BinaryExpression) =
f (left, right) |> asExpr
match logOp with
| Or -> logical Expression.Or
| And -> logical Expression.And
Clause.Fold simpleF complexF clause
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment