Example #1
0
        /// <summary>
        /// Evaluate object[index]
        /// </summary>
        /// <returns></returns>
        public object VisitIndex(IndexExpr expr)
        {
            var ndxVal     = expr.IndexExp.Evaluate(this);
            var listObject = expr.VarExp.Evaluate(this);

            // Check for empty objects.
            ExceptionHelper.NotNull(expr, listObject, "indexing");
            ExceptionHelper.NotNull(expr, ndxVal, "indexing");

            var lobj = (LObject)listObject;

            // CASE 1. Access
            //      e.g. Array: users[0]
            //      e.g. Map:   users['total']
            if (!expr.IsAssignment)
            {
                var result = EvalHelper.AccessIndex(Ctx.Methods, expr, lobj, (LObject)ndxVal);
                return(result);
            }

            // CASE 2.  Assignment
            //      e.g. Array: users[0]        = 'john'
            //      e.g. Map:   users['total']  = 200
            // NOTE: In this case of assignment, return back a MemberAccess object descripting what is assign
            var indexAccess = new IndexAccess();

            indexAccess.Instance   = lobj;
            indexAccess.MemberName = (LObject)ndxVal;
            return(indexAccess);
        }
Example #2
0
        /// <summary>
        /// Visit the anyof expression.
        /// </summary>
        /// <param name="expr">AnyOf expression.</param>
        /// <returns></returns>
        public object VisitAnyOf(AnyOfExpr expr)
        {
            var result     = false;
            var leftExpr   = expr.CompareExpr;
            var leftResult = leftExpr.Evaluate(this) as LObject;

            if (expr.ParamListExpressions == null || expr.ParamListExpressions.Count == 0)
            {
                return(new LBool(result));
            }

            // Resolve the parameters.
            ParamHelper.ResolveNonNamedParameters(expr.ParamListExpressions, expr.ParamList, this);

            foreach (var rvalue in expr.ParamList)
            {
                var rightResult   = rvalue as LObject;
                var compareResult = EvalHelper.Compare(expr, Operator.EqualEqual, leftResult, rightResult) as LObject;
                if (compareResult != null && compareResult.Type == LTypes.Bool && ((LBool)compareResult).Value == true)
                {
                    result = true;
                    break;
                }
            }
            return(new LBool(result));
        }
Example #3
0
        /// <summary>
        /// Execute each expression.
        /// </summary>
        /// <returns></returns>
        public object VisitFor(ForExpr expr)
        {
            expr.Start.Evaluate(this);
            expr.DoContinueRunning = true;
            expr.DoBreakLoop       = false;
            expr.DoContinueLoop    = false;
            var result = expr.Condition.Evaluate(this) as LObject;

            expr.DoContinueRunning = EvalHelper.IsTrue(result);

            while (expr.DoContinueRunning)
            {
                if (expr.Statements != null && expr.Statements.Count > 0)
                {
                    foreach (var stmt in expr.Statements)
                    {
                        stmt.Evaluate(this);

                        this.Ctx.Limits.CheckLoop(expr);

                        // If Break statment executed.
                        if (expr.DoBreakLoop)
                        {
                            expr.DoContinueRunning = false;
                            break;
                        }
                        // Continue statement.
                        else if (expr.DoContinueLoop)
                        {
                            break;
                        }
                    }
                }
                else
                {
                    break;
                }

                // Break loop here.
                if (expr.DoContinueRunning == false)
                {
                    break;
                }

                expr.Increment.Evaluate(this);
                result = expr.Condition.Evaluate(this) as LObject;
                expr.DoContinueRunning = EvalHelper.IsTrue(result);
            }
            return(LObjects.Null);
        }
        public static LNumber IncrementNumber(UnaryExpr expr, LNumber val, IAstVisitor visitor)
        {
            var inc = expr.Increment == 0 ? 1 : expr.Increment;

            if (expr.Expression != null)
            {
                var incval = expr.Expression.Evaluate(visitor);
                // TODO: Check if null and throw langexception?
                inc = ((LNumber)incval).Value;
            }

            // 1. Calculate the unary value
            val = EvalHelper.CalcUnary(val, expr.Op, inc);

            // 2. Set the value back into scope
            expr.Ctx.Memory.SetValue(expr.Name, val);
            return(val);
        }
Example #5
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));
        }
Example #6
0
        /// <summary>
        /// Execute
        /// </summary>
        public object VisitIf(IfExpr expr)
        {
            // Case 1: If is true
            var    result    = expr.Condition.Evaluate(this) as LObject;
            bool   execIf    = EvalHelper.IsTrue(result);
            object returnVal = LObjects.Null;

            if (execIf)
            {
                if (expr.Statements != null && expr.Statements.Count > 0)
                {
                    foreach (var stmt in expr.Statements)
                    {
                        returnVal = stmt.Evaluate(this);
                    }
                }
            }
            // Case 2: Else available to execute
            else if (expr.Else != null)
            {
                returnVal = expr.Else.Evaluate(this);
            }
            return(returnVal);
        }
Example #7
0
        /// <summary>
        /// Evaluate
        /// </summary>
        /// <returns></returns>
        public object VisitUnary(UnaryExpr expr)
        {
            // Logical not?
            if (expr.Op == Operator.LogicalNot)
            {
                return(EvalHelper.HandleLogicalNot(expr, this));
            }

            var valobj = (LObject)expr.Ctx.Memory.Get <object>(expr.Name);

            // Double ?
            if (valobj.Type == LTypes.Number)
            {
                return(EvalHelper.IncrementNumber(expr, (LNumber)valobj, this));
            }

            // String ?
            if (valobj.Type == LTypes.String)
            {
                return(EvalHelper.IncrementString(expr, (LString)valobj, this));
            }

            throw new LangException("Syntax Error", "Unexpected operation", expr.Ref.ScriptName, expr.Ref.Line, expr.Ref.CharPos);
        }
        /// <summary>
        /// Visita a compare expression with the values evaluated.
        /// </summary>
        /// <param name="node"></param>
        /// <param name="op"></param>
        /// <param name="left"></param>
        /// <param name="right"></param>
        /// <returns></returns>
        public static object Compare(AstNode node, Operator op, LObject left, LObject right)
        {
            object result = null;

            // Both double
            if (left.Type == LTypes.Number && right.Type == LTypes.Number)
            {
                result = EvalHelper.CompareNumbers(node, (LNumber)left, (LNumber)right, op);
            }

            // Both strings
            else if (left.Type == LTypes.String && right.Type == LTypes.String)
            {
                result = EvalHelper.CompareStrings(node, (LString)left, (LString)right, op);
            }

            // Both bools
            else if (left.Type == LTypes.Bool && right.Type == LTypes.Bool)
            {
                result = EvalHelper.CompareBools(node, (LBool)left, (LBool)right, op);
            }

            // Both dates
            else if (left.Type == LTypes.Date && right.Type == LTypes.Date)
            {
                result = EvalHelper.CompareDates(node, (LDate)left, (LDate)right, op);
            }

            // Both Timespans
            else if (left.Type == LTypes.Time && right.Type == LTypes.Time)
            {
                result = EvalHelper.CompareTimes(node, (LTime)left, (LTime)right, op);
            }

            // 1 or both null
            else if (left == LObjects.Null || right == LObjects.Null)
            {
                result = EvalHelper.CompareNull(left, right, op);
            }

            // Day of week ?
            else if (left.Type == LTypes.DayOfWeek || right.Type == LTypes.DayOfWeek)
            {
                result = EvalHelper.CompareDays(node, left, right, op);
            }

            // Date and time ?
            else if ((left.Type == LTypes.Date && right.Type == LTypes.Time) ||
                     (left.Type == LTypes.Time && right.Type == LTypes.Date))
            {
                result = EvalHelper.CompareDayDifference(node, left, right, op);
            }

            // Units
            //else if (left.Type == LTypes.Unit || right.Type == LTypes.Unit)
            else if (left.Type.Name == "LUnit" || right.Type.Name == "LUnit")
            {
                result = EvalHelper.CompareUnits(node, (LUnit)((LClass)left).Value, (LUnit)((LClass)right).Value, op);
            }

            return(result);
        }
Example #9
0
        /// <summary>
        /// Evaluate * / + - %
        /// </summary>
        /// <returns></returns>
        public object VisitBinary(BinaryExpr expr)
        {
            // Validate
            object result = 0;
            var    node   = expr;
            var    op     = expr.Op;
            var    left   = (LObject)expr.Left.Evaluate(this);
            var    right  = (LObject)expr.Right.Evaluate(this);

            // Case 1: Both numbers
            if (IsTypeMatch(LTypes.Number, left, right))
            {
                result = EvalHelper.CalcNumbers(node, (LNumber)left, (LNumber)right, op);
            }
            // Case 2: Both times
            else if (IsTypeMatch(LTypes.Time, left, right))
            {
                result = EvalHelper.CalcTimes(node, (LTime)left, (LTime)right, op);
            }
            // Case 3: Both dates
            else if (IsTypeMatch(LTypes.Date, left, right))
            {
                result = EvalHelper.CalcDates(node, (LDate)left, (LDate)right, op);
            }
            // Case 4: Both strings.
            else if (IsTypeMatch(LTypes.String, left, right))
            {
                var strleft  = ((LString)left).Value;
                var strright = ((LString)right).Value;

                // Check string limit.
                this.Ctx.Limits.CheckStringLength(node, strleft, strright);
                result = new LString(strleft + strright);
            }

            // MIXED TYPES
            // TODO: Needs to be improved with new code for types.
            // Case 5 : Double and Bool
            else if (left.Type == LTypes.Number && right.Type == LTypes.Bool)
            {
                var r    = ((LBool)right).Value;
                var rval = r ? 1 : 0;
                result = EvalHelper.CalcNumbers(node, (LNumber)left, new LNumber(rval), op);
            }
            // Bool Double
            else if (left.Type == LTypes.Bool && right.Type == LTypes.Number)
            {
                var l    = ((LBool)left).Value;
                var lval = l ? 1 : 0;
                result = EvalHelper.CalcNumbers(node, new LNumber(lval), (LNumber)right, op);
            }
            // Append as strings.
            else if (left.Type == LTypes.String && right.Type == LTypes.Bool)
            {
                var st1 = ((LString)left).Value + ((LBool)right).Value.ToString().ToLower();
                result = new LString(st1);
            }
            // Append as strings.
            else if (left.Type == LTypes.Bool && right.Type == LTypes.String)
            {
                var st2 = ((LBool)left).Value.ToString().ToLower() + ((LString)right).Value;
                result = new LString(st2);
            }
            // TODO: Need to handle LUnit and LVersion better
            //else if (left.Type == LTypes.Unit && right.Type == LTypes.Unit)
            else if (left.Type.TypeVal == TypeConstants.Unit && right.Type.TypeVal == TypeConstants.Unit)
            {
                result = EvalHelper.CalcUnits(node, (LUnit)((LClass)left).Value, (LUnit)((LClass)right).Value, op, this.Ctx.Units);
            }
            else
            {
                // Check for null
                var lStringVal = "";
                var rStringVal = "";
                if (left != LObjects.Null)
                {
                    lStringVal = left.GetValue().ToString();
                }
                if (right != LObjects.Null)
                {
                    rStringVal = right.GetValue().ToString();
                }

                var st3 = lStringVal + rStringVal;
                result = new LString(st3);
            }
            return(result);
        }
Example #10
0
 /// <summary>
 /// Evaluate
 /// </summary>
 /// <returns></returns>
 public object VisitNegate(NegateExpr expr)
 {
     return(EvalHelper.Negate(expr, this));
 }