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();
            }
        }
Пример #2
0
 /// <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);
 }
Пример #3
0
        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>());
        }
Пример #4
0
        public dynamic Visit(CompareExpr expr)
        {
            var node = Visit((ExpressionBase)expr);

            node.Text = expr.Type.ToString();
            return(node);
        }
Пример #5
0
        /// <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);
        }
Пример #6
0
        /// <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);
        }
Пример #9
0
        /// <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);
        }
Пример #10
0
        /// <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));
        }
Пример #11
0
        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;
        }
Пример #12
0
        /// <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);
 }
Пример #14
0
 /// <summary>
 /// Visits the compare expression tree
 /// </summary>
 /// <param name="exp"></param>
 public void Compare(CompareExpr exp)
 {
     _callBack(exp);
     _callBack(exp.Left);
     _callBack(exp.Right);
 }
Пример #15
0
        /// <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);
        }
Пример #16
0
 /// <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();
 }