<> <> DIRECTORY AMTypes, Graphs, Rope; TypeGraphs: CEDAR PROGRAM IMPORTS AMTypes, Rope = BEGIN ROPE: TYPE = Rope.ROPE; TypeRef: TYPE = REF Type; Type: TYPE = AMTypes.Type; NewTypeVertex: PROC [type: AMTypes.Type] RETURNS [vertex: Graphs.Vertex] = BEGIN vertex _ NEW [Graphs.VertexRep _ [ type: typeVertexType, rep: NEW [Type _ type]]] END; ExpandType: Graphs.ExpandProc --PROC [vertex: Vertex, consume: EdgeConsumer, data: REF ANY _ NIL]-- = BEGIN tr: TypeRef _ NARROW[vertex.rep]; tc: AMTypes.Class _ AMTypes.TypeClass[tr^]; SELECT tc FROM record, structure => BEGIN FOR i: INT IN [1 .. AMTypes.NComponents[tr^]] DO consume.proc[ [ AMTypes.IndexToName[type: tr^, index: i], NewTypeVertex[AMTypes.IndexToType[type: tr^, index: i]]], consume.data]; ENDLOOP; END; ref, pointer, longPointer => consume.proc[["referent", NewTypeVertex[AMTypes.Range[tr^]]], consume.data]; definition => consume.proc[["definition", NewTypeVertex[AMTypes.UnderType[tr^]]], consume.data]; array, sequence, procedure => BEGIN consume.proc[["arg", NewTypeVertex[AMTypes.Domain[tr^]]], consume.data]; consume.proc[["result", NewTypeVertex[AMTypes.Range[tr^]]], consume.data]; END; ENDCASE; END; LabelTypeEdges: PROC [vertex: Graphs.Vertex, consume: Graphs.LabelConsumer] --Graphs.LabelEdgesProc-- = BEGIN tr: TypeRef _ NARROW[vertex.rep]; tc: AMTypes.Class _ AMTypes.TypeClass[tr^]; SELECT tc FROM record, structure => BEGIN FOR i: INT IN [1 .. AMTypes.NComponents[tr^]] DO consume.proc[AMTypes.IndexToName[type: tr^, index: i], consume.data]; ENDLOOP; END; ref, pointer, longPointer => consume.proc["referent", consume.data]; definition => consume.proc["definition", consume.data]; array, sequence, procedure => BEGIN consume.proc["arg", consume.data]; consume.proc["result", consume.data]; END; ENDCASE; END; CrossLabeledTypeEdge: PROC [vertex: Graphs.Vertex, edgeLabel: ROPE] RETURNS [neighbor: Graphs.Vertex] --Graphs.CrossLabeledEdgeProc-- = BEGIN tr: TypeRef _ NARROW[vertex.rep]; tc: AMTypes.Class _ AMTypes.TypeClass[tr^]; SELECT tc FROM record, structure => BEGIN i: CARDINAL _ AMTypes.NameToIndex[type: tr^, name: edgeLabel]; ctr: TypeRef _ NEW [Type _ AMTypes.IndexToType[type: tr^, index: i]]; neighbor _ NEW [Graphs.VertexRep _ [type: typeVertexType, rep: ctr]]; END; ref, pointer, longPointer => RETURN [NewTypeVertex[AMTypes.Range[tr^]]]; definition => RETURN [NewTypeVertex[AMTypes.UnderType[tr^]]]; array, sequence, procedure => BEGIN IF edgeLabel.Equal["arg"] THEN RETURN [NewTypeVertex[AMTypes.Domain[tr^]]]; IF edgeLabel.Equal["result"] THEN RETURN [NewTypeVertex[AMTypes.Range[tr^]]]; ERROR; END; ENDCASE => ERROR; END; CountTypeNeighbors: Graphs.NeighborCountProc --PROC [vertex: Vertex] RETURNS [neighborCount: INT]-- = BEGIN tr: TypeRef _ NARROW[vertex.rep]; tc: AMTypes.Class _ AMTypes.TypeClass[tr^]; SELECT tc FROM record, structure => BEGIN neighborCount _ AMTypes.NComponents[tr^]; END; ref, pointer, longPointer, definition => neighborCount _ 1; array, sequence, procedure => neighborCount _ 2; ENDCASE => neighborCount _ 0; END; typeVertexType: Graphs.VertexType _ NEW [Graphs.VertexTypeRep _ [ Expand: ExpandType, LabelEdges: LabelTypeEdges, CrossLabeledEdge: CrossLabeledTypeEdge, GetNeighborCount: CountTypeNeighbors ]]; END.