public dynamic Visit(CompareExpr expr) { var left = (Visit((dynamic)expr.First)) as Operand; var right = (Visit((dynamic)expr.Second)) as Operand; switch (expr.Type) { case CompareType.Eq: return(left == right); case CompareType.NotEq: return(left != right); case CompareType.More: return(left > right); case CompareType.Less: return(left < right); case CompareType.MoreEq: return(left >= right); case CompareType.LeesEq: return(left <= right); default: throw new ArgumentOutOfRangeException(); } }
/// <summary> /// Visits the compare expression tree /// </summary> /// <param name="exp"></param> public object VisitCompare(CompareExpr exp) { _callBackOnNodeStart(exp); _callBackOnNodeStart(exp.Left); _callBackOnNodeStart(exp.Right); return(null); }
private void Compare(object left, object right, Operator op, bool expected) { // LESS THAN var exp = new CompareExpr(new ConstantExpr(left), op, new ConstantExpr(right)); Assert.AreEqual(expected, exp.EvaluateAs <bool>()); }
public dynamic Visit(CompareExpr expr) { var node = Visit((ExpressionBase)expr); node.Text = expr.Type.ToString(); return(node); }
/// <summary> /// Creates a unary expression with symbol scope, context, script refernce set. /// </summary> /// <param name="name"></param> /// <param name="token"></param> /// <returns></returns> public static Expr Compare(Expr left, Operator op, Expr right, TokenData token) { var exp = new CompareExpr(); exp.Left = left; exp.Op = op; exp.Right = right; SetupContext(exp, token); return(exp); }
/// <summary> /// The shunting yard algorithm that processes a postfix list of expressions/operators. /// </summary> /// <param name="context"></param> /// <param name="parser"></param> /// <param name="stack"></param> /// <returns></returns> public static Expr ProcessShuntingYardList(Context context, Parser parser, List <object> stack) { int index = 0; Expr finalExp = null; // Shunting yard algorithm handles POSTFIX operations. while (index < stack.Count && stack.Count > 0) { // Keep moving forward to the first operator * - + / && that is found // This is a postfix algorithm so it works by creating an expression // from the last 2 items behind an operator. if (!(stack[index] is TokenData)) { index++; continue; } // At this point... we hit an operator // So get the last 2 items on the stack ( they have to be expressions ) // left is 2 behind current position // right is 1 behind current position var left = stack[index - 2] as Expr; var right = stack[index - 1] as Expr; TokenData tdata = stack[index] as TokenData; Token top = tdata.Token; Operator op = Operators.ToOp(top.Text); Expr exp = null; if (Operators.IsMath(op)) { exp = new BinaryExpr(left, op, right); } else if (Operators.IsConditional(op)) { exp = new ConditionExpr(left, op, right); } else if (Operators.IsCompare(op)) { exp = new CompareExpr(left, op, right); } exp.Ctx = context; parser.SetScriptPosition(exp, tdata); stack.RemoveRange(index - 2, 2); index = index - 2; stack[index] = exp; index++; } finalExp = stack[0] as Expr; return(finalExp); }
public dynamic Visit(CompareExpr expr) { var intdouble = new[] { SymbolType.Double, SymbolType.Integer }; if (intdouble.Contains(expr.FirstType) && intdouble.Contains(expr.SecondType)) { return(SymbolType.Bool); } if (expr.FirstType == expr.SecondType && (expr.Type == CompareType.Eq || expr.Type == CompareType.NotEq)) { return(SymbolType.Bool); } throw new ParseException($"Невозможно сравнить типы {expr.FirstType} и {expr.SecondType}", expr.Node); }
public dynamic Visit(CompareExpr expr) { Visit((ExpressionBase)expr); if (OptimizeMode.ExpressionSimplify) { var left = expr.First as LiteralExpr; var right = expr.Second as LiteralExpr; if (left != null && right != null) { var literal = new LiteralExpr { Namespace = expr.Namespace, Node = expr.Node, SymbolType = expr.GetExprType() }; bool result; switch (expr.Type) { case CompareType.Eq: result = left.Value == right.Value; break; case CompareType.NotEq: result = left.Value != right.Value; break; case CompareType.More: result = left.Value > right.Value; break; case CompareType.Less: result = left.Value < right.Value; break; case CompareType.MoreEq: result = left.Value >= right.Value; break; case CompareType.LeesEq: result = left.Value <= right.Value; break; default: throw new ArgumentOutOfRangeException(); } literal.Value = result; return(literal); } } return(expr); }
/// <summary> /// Rule: CompExpr -> AddExpr (COMP AddExpr )? ; /// </summary> protected override object EvalCompExpr(ParseTree tree, params object[] paramlist) { if (GetNode(TokenType.COMP) == null) { return((ExpressionBase)GetNode(TokenType.AddExpr).Eval(tree)); } var boolExpr = new CompareExpr { Node = this, First = (ExpressionBase)nodes.OfTokenType(TokenType.AddExpr).First().Eval(tree), Second = (ExpressionBase)nodes.OfTokenType(TokenType.AddExpr).Last().Eval(tree), OperationText = GetNode(TokenType.COMP).Token.Text }; return(boolExpr); }
/// <summary> /// Evaluate > >= != == less less than /// </summary> /// <returns></returns> public object VisitCompare(CompareExpr expr) { var node = expr; var op = expr.Op; // TODO: This should be here ( find a better solution ) // e.g. allow expression to support comparable ?? if (expr.Right.Nodetype == NodeTypes.SysAnyOf) { var anyOf = ((AnyOfExpr)expr.Right); anyOf.CompareExpr = expr.Left; return(this.VisitAnyOf(anyOf)); } var left = (LObject)expr.Left.Evaluate(this); var right = (LObject)expr.Right.Evaluate(this); return(EvalHelper.Compare(node, op, left, right)); }
public static IReadOnlyList<IReadOnlyList<JoinAlias>> ExtractJoinAliases(IFromListItem join) { var tree = ExtractJoinAliasTree(join); var ret = new List<List<JoinAlias>>(); foreach (var level in tree) { ret.Add(new List<JoinAlias>()); foreach (var rep in level.Items) { if (!ret.SelectMany(x => x).Any(x => x.Find == rep.Find)) { //Agregar el rep: var exAlias = ret.SelectMany(x => x).Where(x => CompareExpr.ExprEquals(x.Replace, rep.Rep) || CompareExpr.ExprEquals(x.Find, rep.Rep) ).Select(x => x.Alias).FirstOrDefault(); string alias; if (exAlias != null) { alias = exAlias; } else { var memberAlias = ExtractMemberStr(rep.Rep); alias = memberAlias; //Si el alias esta repetido, le ponemos un numero consecutivo for (var i = 1; i < 1000 && ret.SelectMany(x => x).Where(x => x.Alias == alias).Any(); i++) { alias = $"\"{memberAlias.Trim('"') + i}\""; } } ret[ret.Count - 1].Add(new JoinAlias(rep.Find, rep.Rep, alias)); } } } return ret; }
/// <summary> /// Remplaza todas las referencias a un elemento del WITH con un SqlTableRefRaw /// </summary> public static Expression SubqueryRawSubs(Expression subquery, ParameterExpression repParam) { if (subquery == null) { return(null); } //Sustituir todo param.X o param por el nombre: var ret = ReplaceVisitor.Replace(subquery, expr => { if (typeof(IFromListItemTarget).GetTypeInfo().IsAssignableFrom(expr.Type.GetTypeInfo())) { var selectInt = expr.Type.GetTypeInfo().ImplementedInterfaces.Concat(new[] { expr.Type }).Where(x => x.GetTypeInfo().IsGenericType&& x.GetGenericTypeDefinition() == typeof(IFromListItemTarget <>)).FirstOrDefault(); if (selectInt == null) { throw new ArgumentException("Debe de ser un IFromListItemTarget<T>"); } var selectType = selectInt.GetTypeInfo().GenericTypeArguments[0]; if (expr is MemberExpression mem && CompareExpr.ExprEquals(mem.Expression, repParam)) { return(RawSqlTableRefExpr(selectType, $"\"{mem.Member.Name}\"")); }
public dynamic Visit(CompareExpr expr) { Visit((ExpressionBase)expr); return(null); }
/// <summary> /// Visits the compare expression tree /// </summary> /// <param name="exp"></param> public void Compare(CompareExpr exp) { _callBack(exp); _callBack(exp.Left); _callBack(exp.Right); }
/// <summary> /// run step 123. /// </summary> /// <returns></returns> public override Expr Parse() { var startToken = _tokenIt.NextToken; _tokenIt.ExpectIdText("repeat"); Expr varname = null; Expr startVal = null; Expr endVal = null; Expr incVal = null; Operator op = Operator.LessThanEqual; // Case 1: repeat to 10 if (_tokenIt.NextToken.Token.Text == "to") { var result = ParseTo(); startVal = new ConstantExpr(1.0); _parser.SetScriptPosition(startVal, startToken); op = result.Item1; endVal = result.Item2; incVal = result.Item3; } // Case 2: repeat 1 to 10 else if (_tokenIt.NextToken.Token.Kind == TokenKind.LiteralNumber) { var num = _tokenIt.ExpectNumber(); var result = ParseTo(); startVal = new ConstantExpr(num); _parser.SetScriptPosition(startVal, startToken); op = result.Item1; endVal = result.Item2; incVal = result.Item3; } // Case 3: repeat ndx to 10 else if (_tokenIt.NextToken.Token.Kind == TokenKind.Ident) { var variableName = _tokenIt.ExpectId(); varname = new VariableExpr(variableName); _parser.SetScriptPosition(varname, startToken); if (_tokenIt.NextToken.Token.Type == TokenTypes.Assignment) { _tokenIt.Advance(); // Upto "to" startVal = ParseExpr(_terminatorForTo); } else { startVal = new ConstantExpr(0); _parser.SetScriptPosition(startVal, startToken); } var result = ParseTo(); op = result.Item1; endVal = result.Item2; incVal = result.Item3; } // auto-create variable name. if (varname == null) { varname = new VariableExpr("it"); _parser.SetScriptPosition(varname, startToken); } // Now setup the stmts var ctx = _parser.Context; var startStmt = new AssignExpr(true, varname, startVal); _parser.SetScriptPositionFromNode(startStmt, varname); startStmt.Ctx = ctx; var condition = new CompareExpr(varname, op, endVal); _parser.SetScriptPositionFromNode(condition, endVal); varname.Ctx = ctx; condition.Ctx = ctx; var incExp = new UnaryExpr(varname.ToQualifiedName(), incVal, Operator.PlusEqual, _parser.Context); _parser.SetScriptPositionFromNode(incExp, incVal); var incStmt = new AssignExpr(false, new VariableExpr(varname.ToQualifiedName()), incExp); _parser.SetScriptPositionFromNode(incStmt, incExp); incStmt.Ctx = ctx; var loopStmt = new ForExpr(startStmt, condition, incStmt); ParseBlock(loopStmt); return(loopStmt); }
/// <summary> /// Devuelve la cadena a la que corresponde la expresión o null en caso de que esta expresión no tenga ningún alias /// </summary> public static string ReplaceStringAliasMembers(Expression ex, IEnumerable<ExprStrRawSql> alias) { return alias.Where(x => CompareExpr.ExprEquals(x.Expr, ex)).Select(x => x.Sql).FirstOrDefault(); }