DIRECTORY Asserting, Collections, LichenDataOps, LichenDataStructure, IntFunctions, LichenNavigation, PairCollections, RegularExpression, Rope; LichenNavigationImpl: CEDAR PROGRAM IMPORTS Asserting, Collections, LichenDataOps, LichenDataStructure, IntFunctions, PairCollections, RegularExpression, Rope EXPORTS LichenNavigation = BEGIN OPEN LichenDataOps, LichenDataStructure, LichenNavigation, Colls:Collections, PairColls:PairCollections, IntFns:IntFunctions; CTByName: PUBLIC PROC [d: Design, name: ROPE] RETURNS [ans: CellType _ NIL] ~ { ans _ NARROW[CTsByName[d, name, TRUE, TRUE].TheElt[]]; RETURN}; CTsByName: PUBLIC PROC [d: Design, pattern: ROPE, case: BOOL _ TRUE, literal: BOOL _ FALSE] RETURNS [Set--of CellType--] ~ { f: RegularExpression.Finder ~ RegularExpression.CreateFromRope[ literal: literal, ignoreCase: NOT case, pattern: pattern]; dat: CTsByNameData ~ NEW[CTsByNameDataPrivate _ [d, f]]; RETURN Colls.CreateEnumerator[e: [EnumCTsByName, Colls.refs, NIL, dat], mayDuplicate: FALSE]; }; CTsByNameData: TYPE ~ REF CTsByNameDataPrivate; CTsByNameDataPrivate: TYPE ~ RECORD [d: Design, f: RegularExpression.Finder]; EnumCTsByName: PROC [Consume: PROC [val: Colls.Value], data: REF ANY _ NIL] ~ { d: CTsByNameData ~ NARROW[data]; TestCT: PROC [ra: REF ANY] ~ { ct: CellType ~ NARROW[ra]; IF HasMatchingNameAssn[ct.otherPublic, d.f] THEN Consume[ct]; RETURN}; d.d.cellTypes.Enumerate[TestCT]; RETURN}; ChildByName: PUBLIC PROC [ct: CellType, name: ROPE] RETURNS [ans: Vertex _ NIL] ~ { ans _ NARROW[ChildrenByName[ct, name, TRUE, TRUE].TheElt[]]; RETURN}; ChildrenByName: PUBLIC PROC [ct: CellType, pattern: ROPE, case: BOOL _ TRUE, literal: BOOL _ FALSE] RETURNS [Set--of CellType--] ~ { f: RegularExpression.Finder ~ RegularExpression.CreateFromRope[ literal: literal, ignoreCase: NOT case, pattern: pattern]; dat: ChildrenByNameData ~ NEW[ChildrenByNameDataPrivate _ [ct, f]]; RETURN Colls.CreateEnumerator[e: [EnumChildrenByName, Colls.refs, NIL, dat], mayDuplicate: FALSE]; }; ChildrenByNameData: TYPE ~ REF ChildrenByNameDataPrivate; ChildrenByNameDataPrivate: TYPE ~ RECORD [ct: CellType, f: RegularExpression.Finder]; EnumChildrenByName: PROC [Consume: PROC [val: Colls.Value], data: REF ANY _ NIL] ~ { d: ChildrenByNameData ~ NARROW[data]; TestV: PROC [v: Vertex] ~ { IF HasMatchingSteppyName[v.names, d.f] THEN Consume[v]; RETURN}; d.ct.EnumerateParts[TestV, FALSE]; RETURN}; ChildByType: PUBLIC PROC [parent, type: CellType] RETURNS [ans: CellInstance _ NIL] ~ { ans _ NARROW[ChildrenByType[parent, type].First[].DVal]; RETURN}; ChildrenByType: PUBLIC PROC [parent, type: CellType] RETURNS [ans: Set--of CellInstance--] ~ { dat: ChildrenByTypeData ~ NEW[ChildrenByTypeDataPrivate _ [parent, type]]; RETURN Colls.CreateEnumerator[e: [EnumChildrenByType, Colls.refs, NIL, dat], mayDuplicate: FALSE]; }; ChildrenByTypeData: TYPE ~ REF ChildrenByTypeDataPrivate; ChildrenByTypeDataPrivate: TYPE ~ RECORD [parent, type: CellType]; EnumChildrenByType: PROC [Consume: PROC [val: Colls.Value], data: REF ANY _ NIL] ~ { d: ChildrenByTypeData ~ NARROW[data]; TestV: PROC [ra: REF ANY] ~ { ci: CellInstance ~ NARROW[ra]; IF ci.type=d.type THEN Consume[ci]; RETURN}; d.parent.asUnorganized.containedInstances.Enumerate[TestV]; RETURN}; PortByName: PUBLIC PROC [root: Port, name: ROPE] RETURNS [ans: Port] ~ { ans _ NARROW[PortsByName[root, name, TRUE, TRUE].First[].DVal]; RETURN}; PortsByName: PUBLIC PROC [root: Port, pattern: ROPE, case: BOOL _ TRUE, literal: BOOL _ FALSE] RETURNS [ans: Set--of Port--] ~ { f: RegularExpression.Finder ~ RegularExpression.CreateFromRope[ literal: literal, ignoreCase: NOT case, pattern: pattern]; dat: PortsByNameData ~ NEW[PortsByNameDataPrivate _ [root, f]]; RETURN Colls.CreateEnumerator[e: [EnumPortsByName, Colls.refs, NIL, dat], mayDuplicate: FALSE]; }; PortsByNameData: TYPE ~ REF PortsByNameDataPrivate; PortsByNameDataPrivate: TYPE ~ RECORD [root: Port, f: RegularExpression.Finder]; EnumPortsByName: PROC [Consume: PROC [val: Colls.Value], data: REF ANY _ NIL] ~ { d: PortsByNameData ~ NARROW[data]; stack: PortList _ LIST[d.root]; WHILE stack#NIL DO p: Port ~ stack.first; IF HasMatchingSteppyName[p.names, d.f] THEN Consume[p]; stack _ stack.rest; IF p.firstChild#NIL THEN stack _ CONS[p.firstChild, stack]; IF p.next#NIL THEN stack _ CONS[p.next, stack]; ENDLOOP; RETURN}; Quit: ERROR ~ CODE; HasMatchingNameAssn: PROC [assns: Assertions, f: RegularExpression.Finder] RETURNS [BOOL] ~ { TestName: PROC [assertion: Assertion] ~ { thisN: ROPE ~ NARROW[Asserting.TermOf[assertion]]; before, after: INT; found: BOOL; [found: found, before: before, after: after] _ f.SearchRope[thisN]; IF found AND before=0 AND after=thisN.Length THEN Quit; }; Asserting.EnumerateAssertionsAbout[nameReln, assns, TestName !Quit => GOTO Has]; RETURN [FALSE]; EXITS Has => RETURN [TRUE]; }; HasMatchingSteppyName: PROC [listData: ListData, f: RegularExpression.Finder] RETURNS [has: BOOL] ~ { names: Set ~ [listClass, listData]; TestName: PROC [val: REF ANY] RETURNS [pass: BOOL _ FALSE] ~ { steppy: SteppyName ~ NARROW[val]; ropy: ROPE ~ UnparseSteppyName[steppy]; before, after: INT; found: BOOL; [found: found, before: before, after: after] _ f.SearchRope[ropy]; IF found AND before=0 AND after=ropy.Length THEN pass _ TRUE; RETURN}; has _ names.Scan[TestName].found; RETURN}; FilterSet: PUBLIC PROC [big: Set, Test: PROC [ra: REF ANY] RETURNS [passes: BOOL]] RETURNS [filtered: Set] ~ { MaybePass: PROC [ra: REF ANY] ~ { IF Test[ra] AND NOT filtered.AddElt[ra] THEN ERROR; }; filtered _ Colls.CreateHashSet[]; big.Enumerate[MaybePass]; big _ big; }; instanceType: PUBLIC Function ~ PairColls.FnFromProc[Apply: InstanceToType, ScanInverse: ScanInstancesOfType]; InstanceToType: PROC [data: REF ANY, v: REF ANY] RETURNS [Colls.MaybeValue] ~ { WITH v SELECT FROM ci: CellInstance => RETURN [[TRUE, ci.type]]; ENDCASE => RETURN [Colls.noMaybe]; }; ScanInstancesOfType: PROC [data: REF ANY, v: Colls.Value, Test: PairColls.Tester] RETURNS [PairColls.MaybePair] ~ { WITH v SELECT FROM ct: CellType => { FOR ci: CellInstance _ ct.firstInstance, ci.nextInstance WHILE ci # NIL DO IF Test[[ci, ct]] THEN RETURN [[TRUE, [ci, ct]]]; ENDLOOP; }; ENDCASE => NULL; RETURN [PairColls.noMaybePair]}; wireToChildren: PUBLIC OneToOne ~ PairColls.FnFromProc[Apply: WireToChildren, ScanInverse: ScanParentOfChildWires, spaces: [Colls.refs, PairColls.refPairColls], oneToOne: TRUE]; WireToChildren: PROC [data: REF ANY, v: Colls.Value] RETURNS [mv: Colls.MaybeValue] ~ { WITH v SELECT FROM x: Wire => RETURN [[TRUE, IntFns.CreateFromCollection[Colls.CreateEnumerator[e: [EnumerateChildrenOfWire, Colls.refs, NIL, x], mayDuplicate: FALSE, orderStyle: client]].Refify]]; ENDCASE => RETURN [Colls.noMaybe]; }; ScanParentOfChildWires: PROC [data: REF ANY, v: Colls.Value, Test: PairColls.Tester] RETURNS [PairColls.MaybePair] ~ { children: Seq ~ IntFns.DeRef[v]; child: Wire ~ NARROW[children.Apply[0].val]; IF child.containingWire=NIL THEN RETURN [PairColls.noMaybePair]; IF NOT children.Equal[IntFns.DeRef[WireToChildren[data: NIL, v: child.containingWire].val]] THEN RETURN [PairColls.noMaybePair]; IF Test[[child.containingWire, v]] THEN RETURN [[TRUE, [child.containingWire, v]]]; RETURN [PairColls.noMaybePair]; }; EnumerateChildrenOfWire: PROC [Consume: PROC [val: Colls.Value], data: REF ANY _ NIL] ~ { w: Wire ~ NARROW[data]; FOR child: Wire _ w.FirstChildWire[], child.NextChildWire[] UNTIL child=NIL DO Consume[child] ENDLOOP; RETURN}; portToChildren: PUBLIC OneToOne ~ PairColls.FnFromProc[Apply: PortToChildren, ScanInverse: ScanParentOfChildPorts, spaces: [Colls.refs, PairColls.refPairColls], oneToOne: TRUE]; PortToChildren: PROC [data: REF ANY, v: Colls.Value] RETURNS [mv: Colls.MaybeValue] ~ { WITH v SELECT FROM x: Port => RETURN [[TRUE, IntFns.CreateFromCollection[Colls.CreateEnumerator[e: [EnumerateChildrenOfPort, Colls.refs, NIL, x], mayDuplicate: FALSE, orderStyle: client]].Refify]]; ENDCASE => RETURN [Colls.noMaybe]; }; ScanParentOfChildPorts: PROC [data: REF ANY, v: Colls.Value, Test: PairColls.Tester] RETURNS [PairColls.MaybePair] ~ { children: Seq ~ IntFns.DeRef[v]; child: Port ~ NARROW[children.Apply[0].val]; parent: Port ~ WITH child.parent SELECT FROM x: Port => x, ct: CellType => NIL, ENDCASE => ERROR; IF parent=NIL THEN RETURN [PairColls.noMaybePair]; IF NOT children.Equal[IntFns.DeRef[PortToChildren[data: NIL, v: parent].val]] THEN RETURN [PairColls.noMaybePair]; IF Test[[parent, v]] THEN RETURN [[TRUE, [parent, v]]]; RETURN [PairColls.noMaybePair]; }; EnumerateChildrenOfPort: PROC [Consume: PROC [val: Colls.Value], data: REF ANY _ NIL] ~ { w: Port ~ NARROW[data]; FOR child: Port _ w.FirstChildPort[], child.NextChildPort[] UNTIL child=NIL DO Consume[child] ENDLOOP; RETURN}; bestVertexShortName: PUBLIC Function ~ PairColls.FnFromProc[Apply: VertexToBestShortName, spaces: [Colls.refs, Colls.ropes[TRUE]]]; VertexToBestShortName: PROC [data: REF ANY, v: Colls.Value] RETURNS [mv: Colls.MaybeValue] ~ { x: Vertex ~ NARROW[v]; mv _ x.VertexNames.First[]; RETURN}; bestPortShortName: PUBLIC Function ~ PairColls.FnFromProc[Apply: PortToBestShortName, spaces: [Colls.refs, Colls.ropes[TRUE]]]; PortToBestShortName: PROC [data: REF ANY, v: Colls.Value] RETURNS [mv: Colls.MaybeValue] ~ { x: Port ~ NARROW[v]; mv _ x.PortNames.First[]; RETURN}; vertexNames: PUBLIC Function ~ PairColls.FnFromProc[Apply: VertexToNames, spaces: [Colls.refs, Colls.refColls]]; VertexToNames: PROC [data: REF ANY, v: Colls.Value] RETURNS [mv: Colls.MaybeValue] ~ { x: Vertex ~ NARROW[v]; mv _ [TRUE, x.VertexNames.Refify]; RETURN}; portNames: PUBLIC Function ~ PairColls.FnFromProc[Apply: PortToNames, spaces: [Colls.refs, Colls.refColls]]; PortToNames: PROC [data: REF ANY, v: Colls.Value] RETURNS [mv: Colls.MaybeValue] ~ { x: Port ~ NARROW[v]; mv _ [TRUE, x.PortNames.Refify]; RETURN}; END. ˜LichenNavigationImpl.mesa Last tweaked by Mike Spreitzer on September 21, 1987 1:07:34 pm PDT addBounds: TRUE, addBounds: TRUE, addBounds: TRUE, Κ '– "cedar" style˜code™KšœC™C—K˜KšΟk œ†˜K˜šΟnœœ˜#Kšœs˜zKšœ˜K˜—K˜Kš œœ7žœž œžœ˜ƒK˜š žœœœœœœ˜OKšœœœœ ˜6Kšœ˜—K˜šž œœœœœœ œœœΟcœ˜|šœ?˜?Kšœ œ™K˜Kšœ œ˜Kšœ˜—Kšœœ ˜8Kšœ7œœ˜]K˜—K˜Kšœœœ˜/Kšœœœ*˜MK˜šž œœžœœœœœ˜OKšœœ˜ šžœœœœ˜Kšœœ˜Kšœ*œ ˜=Kšœ˜—Kšœ ˜ Kšœ˜—K˜š ž œœœœœœ˜SKšœœœœ ˜Kšœœ˜!Kšœœ˜'Kšœœ˜Kšœœ˜ KšœB˜BKš œœ œœœ˜=Kšœ˜—Kšœ!˜!Kšœ˜—K˜šž œœœ žœœœœœ œœ˜nšž œœœœ˜!Kš œ œœœœ˜3K˜—Kšœ!˜!K˜K˜ K˜—K˜Kšœœ!žœž œ˜nK˜šžœœœœœœœ˜Ošœœ˜Kšœœœ ˜-Kšœœ˜"—K˜—K˜š žœœœœžœœ˜sšœœ˜˜šœ6œœ˜JKšœœœœ ˜1Kšœ˜—K˜—Kšœœ˜—Kšœ˜ —K˜Kš œœ!žœž œRœ˜±K˜š žœœœœœ˜Wšœœ˜Kš œ œœ^œœ ˜²Kšœœ˜"—K˜—K˜š žœœœœžœœ˜vK˜ Kšœœ˜,Kšœœœœ˜@Kš œœ2œ!œœ˜€Kšœ!œœœ˜SKšœ˜K˜—K˜šžœœžœœœœœ˜YKšœ œ˜Kš œ9œœœœ˜fKšœ˜—K˜Kš œœ!žœž œRœ˜±K˜š žœœœœœ˜Wšœœ˜Kš œ œœ^œœ ˜²Kšœœ˜"—K˜—K˜š žœœœœžœœ˜vK˜ Kšœœ˜,šœœœ˜,K˜ Kšœœ˜Kšœœ˜—Kšœœœœ˜2Kš œœ2œœœ˜rKšœœœœ˜7Kšœ˜K˜—K˜šžœœžœœœœœ˜YKšœ œ˜Kš œ9œœœœ˜fKšœ˜—K˜Kšœœ!žœ:œ˜ƒK˜š žœœœœœ˜^Kšœ œ˜K˜Kšœ˜—K˜Kšœœ!žœ8œ˜K˜š žœœœœœ˜\Kšœ œ˜K˜Kšœ˜—K˜Kšœ œ!žœ7˜pK˜š ž œœœœœ˜VKšœ œ˜Kšœœ˜"Kšœ˜—K˜Kšœ œ!žœ5˜lK˜š ž œœœœœ˜TKšœ œ˜Kšœœ˜ Kšœ˜—K˜Kšœ˜—…—&ž3]