Пример #1
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 Binary(Expr left, Operator op, Expr right, TokenData token)
 {
     var exp = new BinaryExpr();
     exp.Left = left;
     exp.Op = op;
     exp.Right = right;
     SetupContext(exp, token);
     return exp;
 }
Пример #2
0
 /// <summary>
 /// Visits the binary expression tree
 /// </summary>
 /// <param name="exp"></param>
 public object VisitBinary(BinaryExpr exp)
 {
     _callBackOnNodeStart(exp);
     _callBackOnNodeStart(exp.Left);
     _callBackOnNodeStart(exp.Right);
     return null;
 }
Пример #3
0
        /// <summary>
        /// Checks for division by zero.
        /// </summary>
        /// <param name="semActs"></param>
        /// <param name="exp"></param>
        private SemanticCheckResult CheckDivisionByZero(SemActs semActs, BinaryExpr exp)
        {
            if(exp.Op != Operator.Divide) return SemanticCheckResult.Valid;
            if (!(exp.Right.IsNodeType(NodeTypes.SysConstant))) return SemanticCheckResult.Valid;

            var val = (LObject)((ConstantExpr)exp.Right).Value;
            if (val.Type == LTypes.Number)
            {
                var d = ((LNumber)val).Value;
                if (d == 0)
                    AddError("Division by zero", exp.Right);
            }
            return SemanticCheckResult.Valid;
        }
Пример #4
0
        /// <summary>
        /// Evaluate * / + - % 
        /// </summary>
        /// <returns></returns>
        public static object EvalBinary(BinaryExpr expr)
        {
            // Validate
            object result = 0;
            var node = expr;
            var op = expr.Op;
            var left = (LObject)expr.Left.Evaluate();
            var right = (LObject)expr.Right.Evaluate();

            // 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.
                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.Name == "LUnit" && right.Type.Name == "LUnit")
            {
                result = EvalHelper.CalcUnits(node, (LUnit)((LClass)left).Value, (LUnit)((LClass)right).Value, op, Ctx.Units);
            }
            else
            {
                var st3 = left.GetValue().ToString() + right.GetValue().ToString();
                result = new LString(st3);
            }
            return result;
        }
Пример #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 Expr ToBinaryExpr(Expr left, Operator op, Expr right, TokenData token)
 {
     var exp = new BinaryExpr(left, op, right);
     this.SetupContext(exp, token);
     return exp;
 }