private static Expression ArithmeticFloating(MiddleOperator middleOp,
                                                     Expression leftExpression,
                                                     Expression rightExpression)
        {
            leftExpression  = TypeCast.LogicalToFloating(leftExpression);
            rightExpression = TypeCast.LogicalToFloating(rightExpression);

            Type maxType = TypeCast.MaxType(leftExpression.Symbol.Type,
                                            rightExpression.Symbol.Type);

            leftExpression  = ConstantCast(leftExpression, maxType);
            rightExpression = ConstantCast(rightExpression, maxType);

            decimal leftDecimal   = (decimal)leftExpression.Symbol.Value,
                    rightDecimal  = (decimal)rightExpression.Symbol.Value,
                    resultDecimal = 0;

            switch (middleOp)
            {
            case MiddleOperator.Add:
                resultDecimal = leftDecimal + rightDecimal;
                break;

            case MiddleOperator.Subtract:
                resultDecimal = leftDecimal - rightDecimal;
                break;

            case MiddleOperator.Multiply:
                resultDecimal = leftDecimal * rightDecimal;
                break;

            case MiddleOperator.Divide:
                resultDecimal = leftDecimal / rightDecimal;
                break;
            }

            Symbol            resultSymbol = new Symbol(maxType, resultDecimal);
            List <MiddleCode> longList     = new List <MiddleCode>();

            MiddleCodeGenerator.AddMiddleCode(longList, MiddleOperator.PushFloat,
                                              resultSymbol);
            return(new Expression(resultSymbol, null, longList));
        }
        private static Expression ArithmeticFloating(MiddleOperator middleOp,
                                                     Expression expression)
        {
            expression = LogicalToFloating(expression);
            decimal value        = (decimal)expression.Symbol.Value;
            Symbol  resultSymbol = null;

            switch (middleOp)
            {
            case MiddleOperator.Plus:
                resultSymbol = new Symbol(expression.Symbol.Type, value);
                break;

            case MiddleOperator.Minus:
                resultSymbol = new Symbol(expression.Symbol.Type, -value);
                break;
            }

            List <MiddleCode> longList = new List <MiddleCode>();

            MiddleCodeGenerator.AddMiddleCode(longList, MiddleOperator.PushFloat,
                                              resultSymbol);
            return(new Expression(resultSymbol, null, longList));
        }
Exemplo n.º 3
0
        public static Expression ExplicitCast(Expression sourceExpression,
                                              Type targetType)
        {
            Expression constantExpression =
                ConstantExpression.ConstantCast(sourceExpression, targetType);

            if (constantExpression != null)
            {
                return(constantExpression);
            }

            Symbol            sourceSymbol = sourceExpression.Symbol, targetSymbol = null;
            Type              sourceType = sourceSymbol.Type;
            List <MiddleCode> shortList  = sourceExpression.ShortList,
                              longList   = sourceExpression.LongList;

            if (targetType.IsVoid())
            {
                targetSymbol = new Symbol(targetType);
            }
            else if (sourceType.IsStructOrUnion() && targetType.IsStructOrUnion())
            {
                Assert.Error(sourceType.Equals(targetType), sourceType + " to " +
                             targetType, Message.Invalid_type_cast);
                targetSymbol = new Symbol(targetType);
            }
            else if (sourceType.IsLogical() &&
                     targetType.IsIntegralPointerOrArray())
            {
                targetSymbol = new Symbol(targetType);

                Symbol     oneSymbol = new Symbol(targetType, BigInteger.One);
                MiddleCode trueCode  =
                    new MiddleCode(MiddleOperator.Assign, targetSymbol, oneSymbol);
                MiddleCodeGenerator.Backpatch(sourceSymbol.TrueSet, trueCode);
                longList.Add(trueCode);

                MiddleCode targetCode = new MiddleCode(MiddleOperator.Empty);
                longList.Add(new MiddleCode(MiddleOperator.Jump, targetCode));

                Symbol     zeroSymbol = new Symbol(targetType, BigInteger.Zero);
                MiddleCode falseCode  =
                    new MiddleCode(MiddleOperator.Assign, targetSymbol, zeroSymbol);
                MiddleCodeGenerator.Backpatch(sourceSymbol.FalseSet, falseCode);
                longList.Add(falseCode);

                longList.Add(targetCode);
            }
            else if (sourceType.IsLogical() && targetType.IsFloating())
            {
                targetSymbol = new Symbol(targetType);

                MiddleCode trueCode = new MiddleCode(MiddleOperator.PushOne);
                MiddleCodeGenerator.Backpatch(sourceSymbol.TrueSet, trueCode);
                longList.Add(trueCode);

                MiddleCode targetCode = new MiddleCode(MiddleOperator.Empty);
                longList.Add(new MiddleCode(MiddleOperator.Jump, targetCode));

                MiddleCode falseCode = new MiddleCode(MiddleOperator.PushZero);
                MiddleCodeGenerator.Backpatch(sourceSymbol.FalseSet, falseCode);
                longList.Add(falseCode);

                longList.Add(targetCode);
            }
            else if ((sourceType.IsArithmetic() || sourceType.IsPointerArrayStringOrFunction()) &&
                     targetType.IsLogical())
            {
                object zeroValue = sourceType.IsLogical() ? ((object)decimal.Zero)
                                                  : ((object)BigInteger.Zero);
                Symbol zeroSymbol = new Symbol(targetType, zeroValue);

                MiddleCode testCode =
                    new MiddleCode(MiddleOperator.NotEqual, null,
                                   sourceSymbol, zeroSymbol);
                ISet <MiddleCode> trueSet = new HashSet <MiddleCode>();
                trueSet.Add(testCode);
                longList.Add(testCode);

                MiddleCode        gotoCode = new MiddleCode(MiddleOperator.Jump);
                ISet <MiddleCode> falseSet = new HashSet <MiddleCode>();
                falseSet.Add(gotoCode);
                longList.Add(gotoCode);

                targetSymbol = new Symbol(trueSet, falseSet);
            }
            else if (sourceType.IsFloating() && targetType.IsFloating())
            {
                targetSymbol = new Symbol(targetType);
            }
            else if (sourceType.IsFloating() &&
                     targetType.IsIntegralPointerOrArray())
            {
                targetSymbol = new Symbol(targetType);

                if (targetType.Size() == 1)
                {
                    Type tempType = sourceType.IsSigned() ? Type.SignedIntegerType
                                                : Type.UnsignedIntegerType;
                    Symbol     tempSymbol = new Symbol(tempType);
                    MiddleCode tempCode   =
                        new MiddleCode(MiddleOperator.FloatingToIntegral, tempSymbol,
                                       sourceSymbol);
                    longList.Add(tempCode);
                    MiddleCode resultCode =
                        new MiddleCode(MiddleOperator.IntegralToIntegral, targetSymbol,
                                       tempSymbol);
                    longList.Add(resultCode);
                }
                else
                {
                    MiddleCode resultCode =
                        new MiddleCode(MiddleOperator.FloatingToIntegral, targetSymbol,
                                       sourceSymbol);
                    longList.Add(resultCode);
                }
            }
            else if (sourceType.IsIntegralPointerArrayStringOrFunction() &&
                     targetType.IsFloating())
            {
                targetSymbol = new Symbol(targetType);

                if (sourceType.Size() == 1)
                {
                    Type tempType = sourceType.IsSigned() ? Type.SignedIntegerType
                                                : Type.UnsignedIntegerType;
                    Symbol tempSymbol = new Symbol(tempType);
                    MiddleCodeGenerator.
                    AddMiddleCode(longList, MiddleOperator.IntegralToIntegral,
                                  tempSymbol, sourceSymbol);
                    MiddleCodeGenerator.
                    AddMiddleCode(longList, MiddleOperator.IntegralToFloating,
                                  targetSymbol, tempSymbol);
                }
                else
                {
                    MiddleCodeGenerator.
                    AddMiddleCode(longList, MiddleOperator.IntegralToFloating,
                                  targetSymbol, sourceSymbol);
                }
            }
            else if (sourceType.IsIntegralPointerArrayStringOrFunction() &&
                     targetType.IsIntegralPointerOrArray())
            {
                targetSymbol = new Symbol(targetType);
                MiddleCodeGenerator.
                AddMiddleCode(longList, MiddleOperator.IntegralToIntegral,
                              targetSymbol, sourceSymbol);
            }

            Assert.Error(targetSymbol != null, sourceType + " to " +
                         targetType, Message.Invalid_type_cast);
            return(new Expression(targetSymbol, shortList, longList));
        }
        public static void GenerateAuto(List <MiddleCode> codeList, Symbol toSymbol, object fromInit)
        {
            Type toType = toSymbol.Type;

            if (toType.IsArray() && toType.ArrayType.IsChar() &&
                (fromInit is Expression) && ((Expression)fromInit).Symbol().Type.IsString())
            {
                fromInit = TextToCharList((string)((Expression)fromInit).Symbol().Value);
            }

            if (fromInit is Expression)
            {
                Expression initExpr = (Expression)fromInit;
                codeList.AddRange(initExpr.LongList());
                Symbol initSymbol = TypeCast.ImplicitCast(codeList, initExpr.Symbol(), toType);

                if (toType.IsFloating())
                {
                    MiddleCodeGenerator.AddMiddleCode(codeList, MiddleOperator.PopFloat, toSymbol);
                }
                else
                {
                    MiddleCodeGenerator.AddMiddleCode(codeList, MiddleOperator.Assign, toSymbol, initSymbol);
                }
            }
            else
            {
                List <object> fromList = (List <object>)fromInit;

                switch (toType.Sort)
                {
                case Sort.Array: {
                    if (toType.ArraySize == 0)
                    {
                        toType.ArraySize = fromList.Count;
                    }

                    Assert.Error(fromList.Count <= toType.ArraySize, toType, Message.Too_many_initializers);
                    //Assert.Warning(fromList.Count == toType.ArraySize, toType, Message.Too_few_initializers);
                    Type arrayType = toType.ArrayType;

                    for (int index = 0; index < fromList.Count; ++index)
                    {
                        Symbol subSymbol = new Symbol(arrayType, false);
                        subSymbol.Offset = toSymbol.Offset + (index * arrayType.Size());
                        subSymbol.Name   = toSymbol.Name + "[" + index + "]";
                        GenerateAuto(codeList, subSymbol, fromList[index]);
                    }
                }
                break;

                case Sort.Struct: {
                    IDictionary <string, Symbol> memberMap = toType.MemberMap;
                    Assert.Error(fromList.Count <= memberMap.Count,
                                 toType, Message.Too_many_initializers);

                    /*Assert.Warning(fromList.Count == memberMap.Count,
                     *             toType, Message.Too_few_initializers);*/

                    KeyValuePair <string, Symbol>[] memberArray = new KeyValuePair <string, Symbol> [memberMap.Count];
                    memberMap.CopyTo(memberArray, 0);

                    for (int index = 0; index < fromList.Count; ++index)
                    {
                        Symbol memberSymbol = memberArray[index].Value;
                        Symbol subSymbol    = new Symbol(memberSymbol.Type, false);
                        subSymbol.Name   = toSymbol.Name + Symbol.SeparatorId + memberSymbol.Name;
                        subSymbol.Offset = toSymbol.Offset + memberSymbol.Offset;
                        GenerateAuto(codeList, subSymbol, fromList[index]);
                    }
                }
                break;

                case Sort.Union: {
                    Assert.Error(fromList.Count == 1, toType,
                                 Message.A_union_can_be_initalized_by_one_value_only);
                    IDictionary <string, Symbol> memberMap = toType.MemberMap;
                    Symbol firstSymbol = memberMap.Values.GetEnumerator().Current;
                    Symbol subSymbol   = new Symbol(firstSymbol.Type);
                    subSymbol.Name   = toSymbol.Name + Symbol.SeparatorId + firstSymbol.Name;
                    subSymbol.Offset = toSymbol.Offset;
                    GenerateAuto(codeList, subSymbol, fromList[0]);
                }
                break;
                }
            }
        }