Example #1
0
        private Expression CompileBinaryExpression(int baseLevel, int lambdaLevel)
        {
            Expression current = CompileUnaryExpression(lambdaLevel);

            PushPosition();


            while (!End)
            {
                BinaryOperator op = ExpressionSnippets.GetBinaryOperator(GetPunctuation());

                if (op == BinaryOperator.None)
                {
                    break;
                }


                if (ExpressionSnippets.GetOperatorLevel(op) <= baseLevel)
                {
                    break;
                }
                else
                {
                    Move();

                    int fromPos = PeekPos();
                    int toPos   = Pos;

                    current = new BinaryExpression(op, current, CompileBinaryExpression(ExpressionSnippets.GetOperatorLevel(op), lambdaLevel), fromPos, toPos);
                }
            }

            PopPosition();
            return(current);
        }
Example #2
0
        public override Expression Reduce(Expression root, ExpressionReductor reductor)
        {
            if (root is BinaryExpression)
            {
                Expression left  = reductor.Reduce((root as BinaryExpression).Left);
                Expression right = reductor.Reduce((root as BinaryExpression).Right);
                if (left is BinaryExpression && ExpressionSnippets.GetOperatorLevel((left as BinaryExpression).Operator) == ExpressionSnippets.GetOperatorLevel((root as BinaryExpression).Operator))
                {
                    Expression ll = reductor.Reduce((left as BinaryExpression).Left);
                    Expression lr = reductor.Reduce((left as BinaryExpression).Right);

                    if (lr.IsConstantExpression())
                    {
                        return(BinaryExpression.Create((left as BinaryExpression).Operator, ll, BinaryExpression.Create((root as BinaryExpression).Operator, lr, right)));
                    }
                }
            }


            return(root);
        }
Example #3
0
        private void CheckUnaryExpression(UnaryExpression e, TypeCheckingContext context)
        {
            PerformTypeChecking(e.Operand, context);


            Type type = null;

            bool isValid = true;


            if (e.Operator == UnaryOperator.Negation)
            {
                if (Types.IsNumberType(e.Operand.Type))
                {
                    type = e.Operand.Type;
                }
                else
                {
                    isValid = false;
                }
            }
            else if (e.Operator == UnaryOperator.Not)
            {
                if (Types.GetPrimitiveTypeIndex(e.Operand.Type) == 7)
                {
                    type = typeof(bool);
                }
                else
                {
                    isValid = false;
                }
            }
            else if (e.Operator == UnaryOperator.Identity)
            {
                if (Types.IsNumberType(e.Operand.Type))
                {
                    type = e.Operand.Type;
                }
                else
                {
                    isValid = false;
                }
            }


            if (isValid)
            {
                e.Type = type;
            }
            else
            {
                context.ErrorProvider.ThrowException(string.Format("Operator {0} cannot be applied to type {1}.", ExpressionSnippets.SerializeUnaryOperator(e.Operator), e.Operand.Type), e);
            }
        }
Example #4
0
        protected virtual void CheckBinaryExpresionType(BinaryExpression e, TypeCheckingContext context)
        {
            Type type = null;

            bool isValid = true;

            if (e.Left.Type == null && e.Right.Type == null)
            {
                isValid = false;
            }
            else if (e.Operator == BinaryOperator.Assign)
            {
                if (!(e.Left is VariableExpression || e.Left is IndexingExpression))
                {
                    context.ErrorProvider.ThrowException("Can only assign to a variable.", e);
                    return;
                }
            }
            else if (e.Operator == BinaryOperator.Add)
            {
                if (e.Left.Type == typeof(char) || e.Right.Type == typeof(char))
                {
                    type = typeof(string);
                }
                else if (e.Left.Type == typeof(string) || e.Right.Type == typeof(string))
                {
                    type = typeof(string);
                }
                else if (Types.IsNumberType(e.Left.Type) && Types.IsNumberType(e.Right.Type))
                {
                    int index = Types.ResolvePrimitiveTypeIndex(e.Left.Type, e.Right.Type);
                    type = Types.GetPrimitiveType(index);
                }
                else
                {
                    isValid = false;
                }
            }
            else if (e.Operator == BinaryOperator.Subtract ||
                     e.Operator == BinaryOperator.Multiply ||
                     e.Operator == BinaryOperator.Divide)
            {
                if (Types.IsNumberType(e.Left.Type) && Types.IsNumberType(e.Right.Type))
                {
                    int index = Types.ResolvePrimitiveTypeIndex(e.Left.Type, e.Right.Type);
                    type = Types.GetPrimitiveType(index);
                }
                else if (e.Left.Type.Name == "Matrix" && e.Right.Type.Name == "Matrix")
                {
                    type = e.Left.Type;
                }
                else
                {
                    isValid = false;
                }
            }
            else if (e.Operator == BinaryOperator.LessThan ||
                     e.Operator == BinaryOperator.LessEqualThan ||
                     e.Operator == BinaryOperator.GreaterThan ||
                     e.Operator == BinaryOperator.GreaterEqualThan)
            {
                if (e.Left.Type == typeof(string) && e.Right.Type == typeof(string))
                {
                    type = typeof(bool);
                }
                else if (Types.IsNumberType(e.Left.Type) && Types.IsNumberType(e.Right.Type))
                {
                    type = typeof(bool);
                }
                else
                {
                    isValid = false;
                }
            }
            else if (e.Operator == BinaryOperator.Equal ||
                     e.Operator == BinaryOperator.NotEqual)
            {
                if (e.Left.Type == typeof(string) && e.Right.Type == typeof(string))
                {
                    type = typeof(bool);
                }
                else if (Types.IsNumberType(e.Left.Type) && Types.IsNumberType(e.Right.Type))
                {
                    type = typeof(bool);
                }
                else if (Types.GetPrimitiveTypeIndex(e.Left.Type) == 7 && Types.GetPrimitiveTypeIndex(e.Right.Type) == 7)
                {
                    type = typeof(bool);
                }
                else if (e.Left is ConstantExpression &&
                         ((ConstantExpression)e.Left).Value == null &&
                         !Types.IsPrimitiveType(e.Right.Type))
                {
                    type = typeof(bool);
                }
                else if (e.Right is ConstantExpression &&
                         ((ConstantExpression)e.Right).Value == null &&
                         !Types.IsPrimitiveType(e.Left.Type))
                {
                    type = typeof(bool);
                }
                else
                {
                    isValid = false;
                }
            }
            else if (e.Operator == BinaryOperator.And ||
                     e.Operator == BinaryOperator.Or)
            {
                if (e.Left.Type == typeof(bool) || e.Right.Type == typeof(bool))
                {
                    type = typeof(bool);
                }
                else
                {
                    isValid = false;
                }
            }

            if (isValid)
            {
                e.Type = type;
            }
            else if (context != null)
            {
                context.ErrorProvider.ThrowException(string.Format("Operator {0} cannot be applied to types of {1} and {2}.", ExpressionSnippets.SerializeBinaryOperator(e.Operator), e.Left.Type, e.Right.Type), e);
            }
        }