Пример #1
0
 protected void WriteInitializer(CiArrayType type)
 {
     for (; type != null; type = type.ElementType as CiArrayType)
     {
         Write('[');
         CiArrayStorageType storageType = type as CiArrayStorageType;
         if (storageType != null)
         {
             if (storageType.LengthExpr != null)
             {
                 Write(storageType.LengthExpr);
             }
             else
             {
                 Write(storageType.Length);
             }
         }
         Write(']');
     }
 }
Пример #2
0
 protected void WriteInitializer(CiArrayType type)
 {
     for (; type != null; type = type.ElementType as CiArrayType) {
     Write('[');
     CiArrayStorageType storageType = type as CiArrayStorageType;
     if (storageType != null) {
         if (storageType.LengthExpr != null)
             Write(storageType.LengthExpr);
         else
             Write(storageType.Length);
     }
     Write(']');
     }
 }
Пример #3
0
        CiMaybeAssign Coerce(CiMaybeAssign expr, CiType expected)
        {
            CiType got = expr.Type;

            if (expected.Equals(got))
            {
                return(expr);
            }
            if (expected == CiIntType.Value && got == CiByteType.Value)
            {
                CiConstExpr konst = expr as CiConstExpr;
                if (konst != null)
                {
                    return(new CiConstExpr((object)(int)(byte)konst.Value));
                }
                CiCondExpr cond = expr as CiCondExpr;
                if (cond != null && (cond.OnTrue is CiConstExpr || cond.OnFalse is CiConstExpr))
                {
                    // avoid ((foo ? 1 : 0) & 0xff) in Java
                    return(Coerce(cond, expected));
                }
                if (expr is CiArrayAccess)
                {
                    CiConstAccess ca = ((CiArrayAccess)expr).Array as CiConstAccess;
                    if (ca != null && ca.Const.Is7Bit)
                    {
                        return(expr);
                    }
                }
                return(new CiCoercion {
                    ResultType = expected, Inner = expr
                });
            }
            if (expected == CiByteType.Value && got == CiIntType.Value)
            {
                CiConstExpr konst = expr as CiConstExpr;
                if (konst != null)
                {
                    return(new CiConstExpr((object)(byte)(int)konst.Value));
                }
                return(new CiCoercion {
                    ResultType = expected, Inner = expr
                });
            }
            if (expected == CiStringPtrType.Value && (got == CiType.Null || got is CiStringType))
            {
                return(expr);
            }
            if (expected is CiStringStorageType && got is CiStringType)
            {
                return(expr);
            }
            if (expected is CiClassType)
            {
                if (got == CiType.Null)
                {
                    return(expr);
                }
                if (Extends(got, ((CiClassType)expected).Class))
                {
                    if (expr is CiCondExpr)
                    {
                        // C doesn't like &(cond ? foo : bar)
                        return(Coerce((CiCondExpr)expr, expected));
                    }
                    return(new CiCoercion {
                        ResultType = expected, Inner = expr
                    });
                }
            }
            if (expected is CiArrayPtrType)
            {
                if (got == CiType.Null)
                {
                    return(expr);
                }
                CiArrayType gotArray = got as CiArrayType;
                if (got != null && ((CiArrayPtrType)expected).ElementType.Equals(gotArray.ElementType))
                {
                    return new CiCoercion {
                               ResultType = expected, Inner = expr
                    }
                }
                ;
            }
            throw new ResolveException("Expected {0}, got {1}", expected, got);
        }

        CiExpr Coerce(CiExpr expr, CiType expected)
        {
            return((CiExpr)Coerce((CiMaybeAssign)expr, expected));
        }

        object ResolveConstExpr(CiExpr expr, CiType type)
        {
            expr = Coerce(Resolve(expr), type);
            CiConstExpr ce = expr as CiConstExpr;

            if (ce == null)
            {
                throw new ResolveException("{0} is not constant", expr);
            }
            return(ce.Value);
        }

        object ResolveConstInitializer(ref CiType type, object value)
        {
            if (type is CiArrayType)
            {
                object[] array = value as object[];
                if (array == null)
                {
                    return(value);
                }
                CiType elementType = ((CiArrayType)type).ElementType;
                if (type is CiArrayStorageType)
                {
                    int expected = ((CiArrayStorageType)type).Length;
                    if (array.Length != expected)
                    {
                        throw new ResolveException("Expected {0} array elements, got {1}", expected, array.Length);
                    }
                }
                else
                {
                    type = new CiArrayStorageType {
                        ElementType = elementType, Length = array.Length
                    };
                }
                Array dest = Array.CreateInstance(elementType.DotNetType, array.Length);
                for (int i = 0; i < array.Length; i++)
                {
                    dest.SetValue(ResolveConstInitializer(ref elementType, array[i]), i);
                }
                return(dest);
            }
            if (value is CiExpr)
            {
                return(ResolveConstExpr((CiExpr)value, type));
            }
            return(value);
        }

        void ICiSymbolVisitor.Visit(CiEnum enu)
        {
        }
Пример #4
0
 CiType ICiTypeVisitor.Visit(CiArrayType type)
 {
     type.ElementType = Resolve(type.ElementType);
     return type;
 }