Ejemplo n.º 1
0
        public Expression ParseAdditive()
        {
            Expression node;

            if (Match(tkMinus))
            {
                node = ParseUnaryMinusExpression();
            }
            else
            {
                node = ParseMultiplicative();
            }

            switch (Lexer.CurrentToken.TokenType)
            {
            case tkPlus: Lexer.GetNextToken(); node = new BinaryArithExpression(node, BinaryExpression.BinaryOperator.Addition, ParseAdditive()); break;

            case tkMinus:
                Lexer.GetNextToken();
                node = new BinaryArithExpression(node, BinaryExpression.BinaryOperator.Substraction, ParseMultiplicative());
                switch (Lexer.CurrentToken.TokenType)
                {
                case tkPlus:
                    Lexer.GetNextToken();
                    node = new BinaryArithExpression(node, BinaryExpression.BinaryOperator.Addition, ParseAdditive());
                    break;

                case tkMinus:
                    node = new BinaryArithExpression(node, BinaryExpression.BinaryOperator.Addition, ParseAdditive());
                    break;
                }
                break;
            }
            return(node);
        }
Ejemplo n.º 2
0
        private static void EmitBinaryArithExpression(BinaryArithExpression binaryArith, ILGenerator methodIL)
        {
            switch (binaryArith.OperatorKind)
            {
            case BinaryExpression.BinaryOperator.FDiv:
                EmitPrimitiveBinaryOperation(binaryArith.LeftOperand, binaryArith.RightOperand, OpCodes.Div, methodIL);
                break;

            case BinaryExpression.BinaryOperator.IDiv:
                EmitPrimitiveBinaryOperation(binaryArith.LeftOperand, binaryArith.RightOperand, OpCodes.Rem, methodIL);
                break;

            case BinaryExpression.BinaryOperator.Mult:
                EmitPrimitiveBinaryOperation(binaryArith.LeftOperand, binaryArith.RightOperand, OpCodes.Mul, methodIL);
                break;

            case BinaryExpression.BinaryOperator.Substraction:
                EmitPrimitiveBinaryOperation(binaryArith.LeftOperand, binaryArith.RightOperand, OpCodes.Sub, methodIL);
                break;

            case BinaryExpression.BinaryOperator.Addition:
                if (OperandsHaveSameTypes(binaryArith, new InnerTypes.String()))
                {
                    EmitStringConcatenation(binaryArith.LeftOperand, binaryArith.RightOperand, methodIL);
                }
                else
                {
                    EmitPrimitiveBinaryOperation(binaryArith.LeftOperand, binaryArith.RightOperand, OpCodes.Add, methodIL);
                }
                break;

            case BinaryExpression.BinaryOperator.Power:
                EmitPowerOperation(binaryArith.LeftOperand, binaryArith.RightOperand, methodIL);
                break;

            case BinaryExpression.BinaryOperator.BitwiseAnd:
                EmitPrimitiveBinaryOperation(binaryArith.LeftOperand, binaryArith.RightOperand, OpCodes.And, methodIL);
                break;

            case BinaryExpression.BinaryOperator.BitwiseOr:
                EmitPrimitiveBinaryOperation(binaryArith.LeftOperand, binaryArith.RightOperand, OpCodes.Or, methodIL);
                break;

            case BinaryExpression.BinaryOperator.BitwiseXor:
                EmitPrimitiveBinaryOperation(binaryArith.LeftOperand, binaryArith.RightOperand, OpCodes.Xor, methodIL);
                break;

            case BinaryExpression.BinaryOperator.LShift:
                EmitPrimitiveBinaryOperation(binaryArith.LeftOperand, binaryArith.RightOperand, OpCodes.Shl, methodIL);
                break;

            case BinaryExpression.BinaryOperator.RShift:
                EmitPrimitiveBinaryOperation(binaryArith.LeftOperand, binaryArith.RightOperand, OpCodes.Shr, methodIL);
                break;

            default:
                throw new Exception();
            }
        }
Ejemplo n.º 3
0
        public Expression ParseBitwiseOr()
        {
            Expression node = ParseBitwiseXor();

            if (Match(tkBitwiseOr))
            {
                Lexer.GetNextToken();
                node = new BinaryArithExpression(node, BinaryExpression.BinaryOperator.BitwiseOr, ParseBitwiseOr());
            }
            return(node);
        }
Ejemplo n.º 4
0
        public Expression ParseExponentiation()
        {
            Expression node = ParseFactor();

            if (Match(tkPower))
            {
                Lexer.GetNextToken();
                node = new BinaryArithExpression(node, BinaryExpression.BinaryOperator.Power, ParseExponentiation());
            }
            return(node);
        }
Ejemplo n.º 5
0
        public static void TryToCastBinaryArithExpression(BinaryArithExpression binaryArith, InnerType toType, bool inCastedBinary = false)
        {
            SyntaxTreeNode parent       = binaryArith.Parent;
            InnerType      LOperandType = TypeResolver.ResolveExpressionType(binaryArith.LeftOperand);
            InnerType      ROperandType = TypeResolver.ResolveExpressionType(binaryArith.RightOperand);

            switch (binaryArith.OperatorKind)
            {
            case BinaryExpression.BinaryOperator.LShift:
            case BinaryExpression.BinaryOperator.RShift:
            case BinaryExpression.BinaryOperator.BitwiseOr:
            case BinaryExpression.BinaryOperator.BitwiseAnd:
            case BinaryExpression.BinaryOperator.BitwiseXor:
                if (DefineCastCase(LOperandType, toType) != CastCase.Undefined)
                {
                    if (binaryArith.LeftOperand.NodeKind == NodeType.BinaryArithExpression)
                    {
                        TryToCastBinaryArithExpression((BinaryArithExpression)binaryArith.LeftOperand, new Int32(), true);
                    }
                    else
                    {
                        TryToCastExpression(binaryArith.LeftOperand, new Int32());
                    }
                }
                if (DefineCastCase(ROperandType, toType) != CastCase.Undefined)
                {
                    if (binaryArith.RightOperand.NodeKind == NodeType.BinaryArithExpression)
                    {
                        TryToCastBinaryArithExpression((BinaryArithExpression)binaryArith.RightOperand, new Int32(), true);
                    }
                    else
                    {
                        TryToCastExpression(binaryArith.RightOperand, new Int32());
                    }
                }
                if (!inCastedBinary)
                {
                    if (CanCast(TypeResolver.ResolveBinaryArithExpressionType(binaryArith), toType, false))
                    {
                        CastCase   castCase   = DefineCastCase(TypeResolver.ResolveBinaryArithExpressionType(binaryArith), toType);
                        Expression castMethod = CreateCastMethod(parent, toType, new ParameterDeclaration[] { new ParameterDeclaration(binaryArith) }, castCase);
                        Replace(parent, binaryArith, castMethod);
                    }
                }
                break;

            default:
                TryToCastExpression(binaryArith.LeftOperand, toType);
                TryToCastExpression(binaryArith.RightOperand, toType);
                break;
            }
        }
Ejemplo n.º 6
0
        public Expression ParseShift()
        {
            Expression node = ParseAdditive();

            switch (Lexer.CurrentToken.TokenType)
            {
            case tkLShift:
                Lexer.GetNextToken();
                node = new BinaryArithExpression(node, BinaryExpression.BinaryOperator.LShift, ParseShift());
                break;

            case tkRShift:
                Lexer.GetNextToken();
                node = new BinaryArithExpression(node, BinaryExpression.BinaryOperator.RShift, ParseShift());
                break;
            }
            return(node);
        }
Ejemplo n.º 7
0
        public Expression ParseMultiplicative()
        {
            Expression node = ParseExponentiation();

            switch (Lexer.CurrentToken.TokenType)
            {
            case tkMult:
                Lexer.GetNextToken();
                node = new BinaryArithExpression(node, BinaryExpression.BinaryOperator.Mult, ParseMultiplicative());
                break;

            case tkIDiv:
                Lexer.GetNextToken();
                node = new BinaryArithExpression(node, BinaryExpression.BinaryOperator.IDiv, ParseMultiplicative());
                break;

            case tkFDiv:
                Lexer.GetNextToken();
                node = new BinaryArithExpression(node, BinaryExpression.BinaryOperator.FDiv, ParseMultiplicative());
                break;
            }
            return(node);
        }
Ejemplo n.º 8
0
        public static InnerType ResolveBinaryArithExpressionType(BinaryArithExpression binaryArithExpression)
        {
            InnerType LOperandType = ResolveExpressionType(binaryArithExpression.LeftOperand);
            InnerType ROperandType = ResolveExpressionType(binaryArithExpression.RightOperand);

            switch (binaryArithExpression.OperatorKind)
            {
            case BinaryExpression.BinaryOperator.FDiv:
            case BinaryExpression.BinaryOperator.IDiv:
                if (LOperandType is NumericType && ROperandType is NumericType)
                {
                    if (TypeCaster.CanCast(LOperandType, ROperandType, true))
                    {
                        return(TypeCaster.HigherPriorityType(LOperandType, ROperandType));
                    }
                }
                ReportErrorInArithExpression(new OperatorWithWrongOperandTypes($"Operator [{binaryArithExpression.GetOperatorRepresentation()}] must be located between two numeric operands", binaryArithExpression.SourceContext));
                if (!(LOperandType is NumericType))
                {
                    return(LOperandType);
                }
                else
                {
                    return(ROperandType);
                }

            case BinaryExpression.BinaryOperator.Power:
                if (LOperandType is NumericType && ROperandType is NumericType)
                {
                    return(new Single());
                }
                ReportErrorInArithExpression(new OperatorWithWrongOperandTypes($"Operator [**] must be located between two numeric operands", binaryArithExpression.SourceContext));
                if (!(LOperandType is NumericType))
                {
                    return(LOperandType);
                }
                else
                {
                    return(ROperandType);
                }

            case BinaryExpression.BinaryOperator.Mult:
            case BinaryExpression.BinaryOperator.Substraction:
                if (LOperandType is Char && ROperandType is Char)
                {
                    return(new Int32());
                }
                if (LOperandType is NumericType && ROperandType is NumericType)
                {
                    if (TypeCaster.CanCast(LOperandType, ROperandType, true))
                    {
                        return(TypeCaster.HigherPriorityType(LOperandType, ROperandType));
                    }
                }
                ReportErrorInArithExpression(new OperatorWithWrongOperandTypes($"Operator [{binaryArithExpression.GetOperatorRepresentation()}] must be located between two numeric operands", binaryArithExpression.SourceContext));
                if (!(LOperandType is NumericType))
                {
                    return(LOperandType);
                }
                else
                {
                    return(ROperandType);
                }

            case BinaryExpression.BinaryOperator.Addition:
                if (LOperandType is Char && ROperandType is Char)
                {
                    return(new Int32());
                }
                if ((LOperandType is NumericType && ROperandType is NumericType) | (LOperandType is String && ROperandType is String))
                {
                    if (LOperandType is String)
                    {
                        return(new String());
                    }
                    else
                    if (TypeCaster.CanCast(LOperandType, ROperandType, true))
                    {
                        return(TypeCaster.HigherPriorityType(LOperandType, ROperandType));
                    }
                }
                ReportErrorInArithExpression(new OperatorWithWrongOperandTypes($"Operator [+] must be located between two numeric operands, or between two strings for concatenation", binaryArithExpression.SourceContext));
                if (!(LOperandType is NumericType) && !(LOperandType is String))
                {
                    return(LOperandType);
                }
                else
                {
                    return(ROperandType);
                }

            case BinaryExpression.BinaryOperator.LShift:
            case BinaryExpression.BinaryOperator.RShift:
            case BinaryExpression.BinaryOperator.BitwiseOr:
            case BinaryExpression.BinaryOperator.BitwiseAnd:
            case BinaryExpression.BinaryOperator.BitwiseXor:
                if (LOperandType is IntegralType && ROperandType is IntegralType)
                {
                    if (TypeCaster.CanCast(LOperandType, ROperandType, true))
                    {
                        return(TypeCaster.HigherPriorityType(LOperandType, ROperandType));
                    }
                }
                ReportErrorInArithExpression(new OperatorWithWrongOperandTypes($"Operator [{binaryArithExpression.GetOperatorRepresentation()}] must be located between two integral operands", binaryArithExpression.SourceContext));
                if (!(LOperandType is IntegralType))
                {
                    return(LOperandType);
                }
                else
                {
                    return(ROperandType);
                }

            default:
                return(new Undefined());
            }
        }