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));
        }
Ejemplo n.º 2
0
        public static Expression TypePromotion(Expression expression)
        {
            Type type = expression.Symbol.Type;

            if (type.IsChar() || type.IsShort())
            {
                if (type.IsSigned())
                {
                    return(ImplicitCast(expression, Type.SignedIntegerType));
                }
                else
                {
                    return(ImplicitCast(expression, Type.UnsignedIntegerType));
                }
            }
            else if (type.IsFloat())
            {
                return(TypeCast.ImplicitCast(expression, Type.DoubleType));
            }
            else
            {
                return(expression);
            }
        }
        public static Symbol ArithmeticIntegral(MiddleOperator middleOp,
                                                Symbol leftSymbol,
                                                Symbol rightSymbol)
        {
            Type leftType  = leftSymbol.Type,
                 rightType = rightSymbol.Type;

            BigInteger leftValue   = (BigInteger)leftSymbol.Value,
                       rightValue  = (BigInteger)rightSymbol.Value,
                       resultValue = 0;

            switch (middleOp)
            {
            case MiddleOperator.Add:
                if (leftType.IsPointerOrArray())
                {
                    resultValue = leftValue +
                                  (rightValue * leftType.PointerOrArrayType.Size());
                }
                else if (leftType.IsPointerOrArray())
                {
                    resultValue = (leftValue * rightType.PointerOrArrayType.Size()) +
                                  rightValue;
                }
                else
                {
                    resultValue = leftValue + rightValue;
                }
                break;

            case MiddleOperator.Subtract:
                if (leftType.IsPointerOrArray() && rightType.IsPointerOrArray())
                {
                    resultValue = (leftValue - rightValue) /
                                  leftType.PointerOrArrayType.Size();
                }
                else if (leftType.IsPointerOrArray())
                {
                    resultValue = leftValue -
                                  (rightValue * leftType.PointerOrArrayType.Size());
                }
                else
                {
                    resultValue = leftValue - rightValue;
                }
                break;

            case MiddleOperator.Multiply:
                resultValue = leftValue * rightValue;
                break;

            case MiddleOperator.Divide:
                resultValue = leftValue / rightValue;
                break;

            case MiddleOperator.Modulo:
                resultValue = leftValue % rightValue;
                break;

            case MiddleOperator.BitwiseOr:
                resultValue = leftValue | rightValue;
                break;

            case MiddleOperator.BitwiseXOr:
                resultValue = leftValue ^ rightValue;
                break;

            case MiddleOperator.BitwiseAnd:
                resultValue = leftValue & rightValue;
                break;

            case MiddleOperator.ShiftLeft:
                resultValue = leftValue << ((int)rightValue);
                break;

            case MiddleOperator.ShiftRight:
                resultValue = leftValue >> ((int)rightValue);
                break;
            }

            Type maxType = TypeCast.MaxType(leftSymbol.Type, rightSymbol.Type);

            return(new Symbol(maxType, resultValue));
        }
        public static List <MiddleCode> GenerateAuto(Symbol toSymbol,
                                                     object fromInitializer, int extraOffset,
                                                     List <MiddleCode> codeList)
        {
            Type toType = toSymbol.Type;

            if (fromInitializer is Expression)
            {
                Expression fromExpression = (Expression)fromInitializer;

                if (toType.IsArray() && toType.ArrayType.IsChar() &&
                    fromExpression.Symbol.Type.IsString())
                {
                    string        text = ((string)fromExpression.Symbol.Value) + "\0";
                    List <object> list = new List <object>();

                    foreach (char c in text)
                    {
                        Symbol charSymbol =
                            new Symbol(toType.ArrayType, (BigInteger)((int)c));
                        Expression charExpression = new Expression(charSymbol, null, null);
                        list.Add(charExpression);
                    }

                    return(GenerateAuto(toSymbol, list, extraOffset, codeList));
                }
                else
                {
                    fromExpression = TypeCast.ImplicitCast(fromExpression, toType);

                    foreach (MiddleCode middleCode in fromExpression.LongList)
                    {
                        switch (middleCode.Operator)
                        {
                        case MiddleOperator.PreCall:
                        case MiddleOperator.ParameterInitSize:
                        case MiddleOperator.Parameter:
                        case MiddleOperator.Call:
                        case MiddleOperator.PostCall:
                            middleCode[0] = ((int)middleCode[0]) + extraOffset;
                            break;
                        }
                    }

                    codeList.AddRange(fromExpression.LongList);

                    if (toSymbol.Type.IsFloating())
                    {
                        codeList.Add(new MiddleCode(MiddleOperator.PopFloat, toSymbol));
                    }
                    else
                    {
                        if (fromExpression.Symbol.Type.IsStructOrUnion())
                        {
                            codeList.Add(new MiddleCode(MiddleOperator.AssignInitSize,
                                                        toSymbol, fromExpression.Symbol));
                        }

                        codeList.Add(new MiddleCode(MiddleOperator.Assign, toSymbol,
                                                    fromExpression.Symbol));
                    }
                }
            }
            else
            {
                List <object> fromList = (List <object>)fromInitializer;

                switch (toType.Sort)
                {
                case Sort.Array: {
                    fromList = ModifyInitializer.ModifyArray(toType, fromList);

                    if (toType.ArraySize == 0)
                    {
                        toType.ArraySize = fromList.Count;
                    }
                    else
                    {
                        Assert.Error(fromList.Count <= toType.ArraySize,
                                     toType, Message.Too_many_initializers_in_array);
                    }

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

                case Sort.Struct: {
                    List <Symbol> memberList = toType.MemberList;
                    Assert.Error(fromList.Count <= memberList.Count, toType,
                                 Message.Too_many_initializers_in_struct);

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

                case Sort.Union: {
                    List <Symbol> memberList = toType.MemberList;
                    Assert.Error(fromList.Count == 1, toType,
                                 Message.Only_one_Initlizer_allowed_in_unions);
                    Symbol memberSymbol = memberList[0];
                    Symbol subSymbol    = new Symbol(memberSymbol.Type);
                    subSymbol.Name   = toSymbol.Name + "." + memberSymbol.Name;
                    subSymbol.Offset = toSymbol.Offset;
                    GenerateAuto(subSymbol, fromList[0], extraOffset, codeList);
                }
                break;

                default:
                    Assert.Error(toType, Message.
                                 Only_array_struct_or_union_can_be_initialized_by_a_list);
                    break;
                }
            }

            return(codeList);
        }
Ejemplo n.º 5
0
        public static List <MiddleCode> GenerateStatic(Type toType,
                                                       object fromInitializer)
        {
            List <MiddleCode> codeList = new List <MiddleCode>();

            if (fromInitializer is Expression)
            {
                Expression fromExpression = (Expression)fromInitializer;
                Symbol     fromSymbol     = fromExpression.Symbol;
                Assert.Error(fromSymbol.IsExternOrStatic(), fromSymbol,
                             Message.Non__static_initializer);
                Type fromType = fromSymbol.Type;

                if (toType.IsArray() && toType.ArrayType.IsChar() &&
                    fromType.IsString())
                {
                    string text = (string)fromSymbol.Value;

                    if (toType.ArraySize == 0)
                    {
                        toType.ArraySize = text.Length + 1;
                    }
                    else
                    {
                        Assert.Error(text.Length < toType.ArraySize, toType,
                                     Message.Too_many_initializers_in_array);
                    }

                    codeList.Add(new MiddleCode(MiddleOperator.Initializer,
                                                fromSymbol.Type.Sort, text));
                }
                else if (toType.IsPointer() && fromType.IsArrayFunctionOrString())
                {
                    Assert.ErrorXXX((fromType.IsString() && toType.PointerType.IsChar()) ||
                                    (fromType.IsArray() &&
                                     fromType.ArrayType.Equals(toType.PointerType)) ||
                                    (fromType.IsFunction() &&
                                     fromType.Equals(toType.PointerType)));
                    StaticAddress staticAddress =
                        new StaticAddress(fromSymbol.UniqueName, 0);
                    codeList.Add(new MiddleCode(MiddleOperator.Initializer,
                                                toType.Sort, staticAddress));
                }
                else
                {
                    Expression toExpression =
                        TypeCast.ImplicitCast(fromExpression, toType);
                    Symbol toSymbol = toExpression.Symbol;
                    Assert.Error(toSymbol.Value != null, toSymbol,
                                 Message.Non__constant_expression);
                    codeList.Add(new MiddleCode(MiddleOperator.Initializer,
                                                toSymbol.Type.Sort, toSymbol.Value));
                }
            }
            else
            {
                List <object> fromList = (List <object>)fromInitializer;

                switch (toType.Sort)
                {
                case Sort.Array: {
                    fromList = ModifyInitializer.ModifyArray(toType, fromList);

                    if (toType.ArraySize == 0)
                    {
                        toType.ArraySize = fromList.Count;
                    }
                    else
                    {
                        Assert.Error(fromList.Count <= toType.ArraySize,
                                     toType, Message.Too_many_initializers_in_array);
                    }

                    foreach (object value in fromList)
                    {
                        codeList.AddRange(GenerateStatic(toType.ArrayType, value));
                    }

                    int restSize = toType.Size() -
                                   (fromList.Count * toType.ArrayType.Size());
                    if (restSize > 0)
                    {
                        codeList.Add(new MiddleCode(MiddleOperator.InitializerZero,
                                                    restSize));
                    }
                }
                break;

                case Sort.Struct: {
                    List <Symbol> memberList = toType.MemberList;
                    Assert.Error(fromList.Count <= memberList.Count, toType,
                                 Message.Too_many_initializers_in_struct);

                    int initSize = 0;
                    for (int index = 0; index < fromList.Count; ++index)
                    {
                        Symbol memberSymbol = memberList[index];
                        codeList.AddRange(GenerateStatic(memberSymbol.Type,
                                                         fromList[index]));
                        initSize += memberSymbol.Type.Size();
                    }

                    int restSize = toType.Size() - initSize;
                    if (restSize > 0)
                    {
                        codeList.Add(new MiddleCode(MiddleOperator.InitializerZero,
                                                    restSize));
                    }
                }
                break;

                case Sort.Union: {
                    List <Symbol> memberList = toType.MemberList;
                    Assert.Error(fromList.Count == 1, toType,
                                 Message.Only_one_Initlizer_allowed_in_unions);

                    Symbol memberSymbol = memberList[0];
                    codeList.AddRange(GenerateStatic(memberSymbol.Type,
                                                     fromList[0]));

                    int restSize = toType.Size() - memberSymbol.Type.Size();
                    if (restSize > 0)
                    {
                        codeList.Add(new MiddleCode(MiddleOperator.InitializerZero,
                                                    restSize));
                    }
                }
                break;

                default:
                    Assert.Error(toType, Message.
                                 Only_array_struct_or_union_can_be_initialized_by_a_list);
                    break;
                }
            }

            return(codeList);
        }
        public static void GenerateStatic(Type toType, object fromInit,
                                          List <sbyte> byteList, IDictionary <int, string> accessMap)
        {
            if (fromInit is Expression)
            {
                Symbol fromSymbol = ((Expression)fromInit).Symbol();
                Assert.Error(fromSymbol.IsStaticOrExtern(), fromSymbol,
                             Message.Non__static_initializer);
                Type fromType = fromSymbol.Type;

                if (toType.IsArray() && fromType.IsString())
                {
                    Assert.Error(toType.ArrayType.IsChar());
                    fromInit = TextToCharList((string)fromSymbol.Value);
                }

                if (fromType.IsArrayFunctionOrString() && toType.IsPointer())
                {
                    Assert.Error((fromType.IsString() && toType.PointerType.IsChar()) ||
                                 (fromType.IsArray() && fromType.ArrayType.Equals(toType.PointerType)) ||
                                 (fromType.IsFunction() && fromType.Equals(toType.PointerType)));
                    accessMap[byteList.Count] = fromSymbol.UniqueName;
                    byteList.Add((sbyte)0);
                    byteList.Add((sbyte)0);
                }
                else if (fromSymbol.Value is StaticAddress)
                {
                    Assert.Error(fromType.IsPointer() && toType.IsPointer());
                    StaticAddress staticAddress = (StaticAddress)fromSymbol.Value;
                    accessMap[byteList.Count] = staticAddress.UniqueName;
                    byteList.Add((sbyte)staticAddress.Offset);
                    byteList.Add((sbyte)(staticAddress.Offset >> 8));
                }
                else if (fromSymbol.Value is StaticValue)
                {
                    Assert.Error(fromType.Equals(toType));
                    StaticValue staticValue = (StaticValue)fromSymbol.Value;

                    foreach (KeyValuePair <int, string> entry in staticValue.AccessMap)
                    {
                        accessMap[byteList.Count + entry.Key] = entry.Value;
                    }

                    byteList.AddRange(staticValue.ByteList);
                }
                else
                {
                    Symbol toSymbol = TypeCast.ImplicitCast(null, fromSymbol, toType);

                    foreach (KeyValuePair <int, string> entry in toSymbol.StaticSymbol.AccessMap)
                    {
                        accessMap[byteList.Count + entry.Key] = entry.Value;
                    }

                    byteList.AddRange(toSymbol.StaticSymbol.ByteList);
                }
            }
            else
            {
                List <object> fromList = (List <object>)fromInit;

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

                    int toByteListSize = byteList.Count + toType.Size();
                    Assert.Error(fromList.Count <= toType.ArraySize, toType, Message.Too_many_initializers);
                    //Assert.Warning(fromList.Count == toType.ArraySize, toType, Message.Too_few_initializers);
                    Type subType = toType.ArrayType;

                    foreach (object value in fromList)
                    {
                        GenerateStatic(subType, value, byteList, accessMap);
                    }

                    GenerateZeroByteList(toByteListSize - byteList.Count, byteList);
                }
                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);*/

                    int toByteListSize = byteList.Count + toType.Size();
                    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;
                        object init         = ModifyInitializer.DoInit(memberSymbol.Type, fromList[index]);
                        GenerateStatic(memberSymbol.Type, init, byteList, accessMap);
                    }

                    GenerateZeroByteList(toByteListSize - byteList.Count, byteList);
                }
                break;

                case Sort.Union: {
                    Assert.Error(fromList.Count == 1, toType, Message.A_union_can_be_initalized_by_one_value_only);
                    int toByteListSize = byteList.Count + toType.Size();
                    IDictionary <string, Symbol> memberMap = toType.MemberMap;
                    Symbol firstSymbol = memberMap.Values.GetEnumerator().Current;
                    object init        = ModifyInitializer.DoInit(firstSymbol.Type, fromList[0]);
                    GenerateStatic(firstSymbol.Type, init, byteList, accessMap);
                    GenerateZeroByteList(toByteListSize - byteList.Count, byteList);
                }
                break;
                }
            }
        }
        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;
                }
            }
        }