public void SolveTypes() { for (int i = 0; i < TypeDeclarationNodes.Length; i++) { if (Sets[i] == null) { continue; } var parentSet = DisjointSet.SetOf(Sets[i]); if (parentSet.IsInvalid) { Scope.RemoveType(Sets[i].Name); Report.AddError(SemanticErrors.CircularTypeDefinition(TypeDeclarationNodes[i], TypeDeclarationNodes[i].IdNode.Name)); } else { DisjointSet.FirstArrayDependency(Sets[i]); if (Sets[i].TigerType is ArrayType) { ((ArrayType)Sets[i].TigerType).ContentType = Sets[i].Parent.TigerType; } if (Sets[i].TigerType is SimpleType) { ((SimpleType)Sets[i].TigerType).ActualType = Sets[i].Parent.TigerType; } if (!(TypeDeclarationNodes[i] is RecordTypeDeclarationNode)) { Scope.CompleteType(Sets[i].Name, Sets[i].TigerType); } } } }
public void JoinSets() { foreach (var t in TypeDeclarationNodes) { var simpleDecl = t as SimpleTypeDeclarationNode; if (simpleDecl != null) { if (Dictionary.ContainsKey(simpleDecl.TypeAccessNode.IdNode.Name)) { DisjointSet.AliasOfJoin(Dictionary[simpleDecl.IdNode.Name], Dictionary[simpleDecl.TypeAccessNode.IdNode.Name]); } } var arrayDecl = t as ArrayTypeDeclarationNode; if (arrayDecl != null) { if (Dictionary.ContainsKey(arrayDecl.TypeAccessNode.IdNode.Name)) { DisjointSet.ArrayOfJoin(Dictionary[arrayDecl.IdNode.Name], Dictionary[arrayDecl.TypeAccessNode.IdNode.Name]); } } } }
public static void AliasOfJoin(DisjointSet ds1, DisjointSet alias) { var set1 = SetOf(ds1); var set2 = SetOf(alias); if (set1 == set2) { set1.IsInvalid = true; return; } ds1.Parent = alias; FirstArrayDependency(ds1); }
public static void ArrayOfJoin(DisjointSet array, DisjointSet arrayType) { var set1 = SetOf(array); var set2 = SetOf(arrayType); if (set1 == set2) { set1.IsInvalid = true; return; } array.Parent = arrayType; FirstArrayDependency(array); array.DependencyType = DependencyType.ArrayOf; }
public static void FirstArrayDependency(DisjointSet ds) { var current = ds.Parent; while (current != current.Parent) { if (current.DependencyType == DependencyType.ArrayOf) { ds.Parent = current; return; } current = current.Parent; } ds.Parent = current; }
public void CreateSets(int declarationIndex) { var decl = TypeDeclarationNodes[declarationIndex]; var simpleType = decl as SimpleTypeDeclarationNode; if (simpleType != null) { Sets[declarationIndex] = new DisjointSet(new SimpleType(decl.IdNode.Name, TigerType.Nil)); if (!Dictionary.ContainsKey(simpleType.TypeAccessNode.IdNode.Name)) { Dictionary[simpleType.TypeAccessNode.IdNode.Name] = new DisjointSet(simpleType.TypeAccessNode.TigerType); } Dictionary[decl.IdNode.Name] = Sets[declarationIndex]; } var arrayType = decl as ArrayTypeDeclarationNode; if (arrayType != null) { Sets[declarationIndex] = new DisjointSet(new ArrayType(decl.IdNode.Name, TigerType.Nil), DependencyType.ArrayOf); if (!Dictionary.ContainsKey(arrayType.TypeAccessNode.IdNode.Name)) { Dictionary[arrayType.TypeAccessNode.IdNode.Name] = new DisjointSet(arrayType.TypeAccessNode.TigerType); } Dictionary[decl.IdNode.Name] = Sets[declarationIndex]; } var recordType = decl as RecordTypeDeclarationNode; if (recordType != null) { Sets[declarationIndex] = new DisjointSet(recordType.RecordTigerType); Dictionary[decl.IdNode.Name] = Sets[declarationIndex]; } }
public static DisjointSet SetOf(DisjointSet ds) { return(ds == ds.Parent ? ds : SetOf(ds.Parent)); }
public DisjointSet(TigerType tigerType, DependencyType dependencyType = DependencyType.AliasOf) { TigerType = tigerType; Parent = this; DependencyType = dependencyType; }