private static Expression CompileExistence(Op op, Scope scope) { var p = scope.FreeVariable("ref"); var @ref = new Literal {Value = p.Name}; var fst = new Parens {Body = new Assign {Variable = @ref, Value = op.First}}; return Compile(new If {Condition = new Existence {Expression = fst}, Body = @ref, ElseBody = op.Second}, scope); }
public static Expression CompileOp(Op op, Scope scope) { var ischain = op.IsChainable && op.First is Op && ((Op)op.First).IsChainable; if (op.Second == null) return CompileUnary(op, scope); if (ischain) return CompileChain(op, scope); if (op.Operator == "?") return CompileExistence(op, scope); var first = Compile(op.First, scope); var second = Compile(op.Second, scope); var operation = GetExpressionType(op.Operator); return Expression.Dynamic( scope.GetRuntime().BinaryOperationBinders.Get(operation), typeof(object), first, second ); }
public static Expression CompileUnary(Op op, Scope scope) { throw new NotImplementedException(); }
public static Expression CompileChain(Op op, Scope scope) { //for a chain we need to convert the second param of the first to a local. then we can do two comparisons and merge them with && var first = op.First as Op; var refName = scope.FreeVariableName("ref"); first.Second = first.Second.Cache(refName); var fst = Compile(first, scope); var scd = Compile(new Op {First = first.Second, Second = op.Second, Operator = op.Operator}, scope); return Expression.Dynamic( scope.GetRuntime().BinaryOperationBinders.Get(ExpressionType.And), typeof (object), fst, scd); }