public override void CaseAArrayLvalue(AArrayLvalue node) { InAArrayLvalue(node); if (node.GetIndex() != null) { node.GetIndex().Apply(this); } if (node.GetBase() != null) { node.GetBase().Apply(this); } if (node.GetToken() != null) { node.GetToken().Apply(this); } OutAArrayLvalue(node); }
public override void OutAArrayLvalue(AArrayLvalue node) { PType type = data.ExpTypes[node.GetBase()]; PType argType = data.ExpTypes[node.GetIndex()]; List<APropertyDecl> matchingArrayProperties = new List<APropertyDecl>(); List<APropertyDecl> implicitStructArrayProperties = new List<APropertyDecl>(); if (type is ANamedType && data.StructTypeLinks.ContainsKey((ANamedType)type)) { AStructDecl structDecl = data.StructTypeLinks[(ANamedType) type]; foreach (APropertyDecl property in data.StructProperties[structDecl]) { if (property.GetName().Text == "") { PType proprtyArgType = data.ArrayPropertyLocals[property][0].GetType(); if (Assignable(argType, proprtyArgType)) matchingArrayProperties.Add(property); } } } if (type is APointerType) { APointerType aType = (APointerType)type; PType baseType = aType.GetType(); if (baseType is ANamedType && data.StructTypeLinks.ContainsKey((ANamedType)baseType)) { AStructDecl structDecl = data.StructTypeLinks[(ANamedType)baseType]; foreach (APropertyDecl property in data.StructProperties[structDecl]) { if (property.GetName().Text == "") { PType proprtyArgType = data.ArrayPropertyLocals[property][0].GetType(); if (Assignable(argType, proprtyArgType)) implicitStructArrayProperties.Add(property); } } } } List<IList> visibleDecls = Util.GetVisibleDecls(node, true); foreach (IList declList in visibleDecls) { foreach (PDecl decl in declList) { if (decl is AEnrichmentDecl) { AEnrichmentDecl enrichment = (AEnrichmentDecl)decl; if (Util.TypesEqual(type, enrichment.GetType(), data)) { foreach (PDecl enrichmentDecl in enrichment.GetDecl()) { if (enrichmentDecl is APropertyDecl) { APropertyDecl property = (APropertyDecl) enrichmentDecl; if (property.GetName().Text == "") { PType proprtyArgType = data.ArrayPropertyLocals[property][0].GetType(); if (Assignable(argType, proprtyArgType)) matchingArrayProperties.Add(property); } } } } } } } bool matchesNormalArray = false; ALvalueExp replaceBaseExp = null; if (Assignable(argType, new ANamedType(new TIdentifier("int"), null))) { if (type is AArrayTempType) { AArrayTempType aType = (AArrayTempType) type; type = aType.GetType(); matchesNormalArray = true; } else if (type is ADynamicArrayType) { ADynamicArrayType aType = (ADynamicArrayType) type; type = aType.GetType(); matchesNormalArray = true; } else if (type is APointerType) { //Implicit conversion for a[] to (*a)[] APointerType aType = (APointerType) type; if (aType.GetType() is AArrayTempType || aType.GetType() is ADynamicArrayType) { APointerLvalue pointer = new APointerLvalue(new TStar("*"), node.GetBase()); replaceBaseExp = new ALvalueExp(pointer); matchesNormalArray = true; } } } if (matchingArrayProperties.Count == 0 && !matchesNormalArray && implicitStructArrayProperties.Count == 0) errors.Add(new ErrorCollection.Error(node.GetToken(), currentSourceFile, LocRM.GetString("ErrorText72"))); if (matchingArrayProperties.Count + (matchesNormalArray ? 1 : 0) > 1) { List<ErrorCollection.Error> subErrors = new List<ErrorCollection.Error>(); foreach (APropertyDecl property in matchingArrayProperties) { subErrors.Add(new ErrorCollection.Error(property.GetName(), LocRM.GetString("ErrorText62"))); } if (matchesNormalArray) subErrors.Add(new ErrorCollection.Error(node.GetToken(), LocRM.GetString("ErrorText74"))); errors.Add(new ErrorCollection.Error(node.GetToken(), LocRM.GetString("ErrorText73"), false, subErrors.ToArray())); throw new ParserException(node.GetToken(), "TypeChecking.OutAArrayLvalue"); } if (matchingArrayProperties.Count + (matchesNormalArray ? 1 : 0) == 0 && implicitStructArrayProperties.Count > 1) { List<ErrorCollection.Error> subErrors = new List<ErrorCollection.Error>(); foreach (APropertyDecl property in implicitStructArrayProperties) { subErrors.Add(new ErrorCollection.Error(property.GetName(), LocRM.GetString("ErrorText62"))); } errors.Add(new ErrorCollection.Error(node.GetToken(), LocRM.GetString("ErrorText73"), false, subErrors.ToArray())); throw new ParserException(node.GetToken(), "TypeChecking.OutAArrayLvalue"); } if (matchingArrayProperties.Count == 1) { APropertyDecl property = matchingArrayProperties[0]; type = property.GetType(); data.ArrayPropertyLinks[node] = new Util.Pair<APropertyDecl, bool>(property, false); CheckPropertyAccessibility(property, node.Parent() is AAssignmentExp, node.GetToken()); } else if (implicitStructArrayProperties.Count == 1) { APropertyDecl property = implicitStructArrayProperties[0]; type = property.GetType(); data.ArrayPropertyLinks[node] = new Util.Pair<APropertyDecl, bool>(property, true); CheckPropertyAccessibility(property, node.Parent() is AAssignmentExp, node.GetToken()); } if (replaceBaseExp == null) data.LvalueTypes[node] = type; else { node.SetBase(replaceBaseExp); //pointer.Apply(this); OutAPointerLvalue((APointerLvalue)replaceBaseExp.GetLvalue()); OutALvalueExp(replaceBaseExp); OutAArrayLvalue(node); } //if (!Assignable(data.ExpTypes[node.GetIndex()], new ANamedType(new TIdentifier("int"), null))) // errors.Add(new ErrorCollection.Error(node.GetToken(), currentSourceFile, "Indexes of arrays must be of integer type.")); }