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 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); }
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; } } }