LichenNamingImpl1.Mesa
Last tweaked by Mike Spreitzer on February 2, 1988 4:30:00 pm PST
DIRECTORY AbSets, Asserting, BiRels, Convert, LichenArrayStuff, LichenDataOps, LichenDataStructure, LichenTransforms, Rope, SetBasics;
LichenNamingImpl1: CEDAR PROGRAM
IMPORTS AbSets, Asserting, BiRels, Convert, LichenArrayStuff, LichenDataOps, LichenDataStructure, Rope, SetBasics
EXPORTS LichenTransforms
=
BEGIN OPEN Sets:AbSets, LichenDataStructure, LichenDataOps;
PrefixifyDesign: PUBLIC PROC [design: Design] ~ {
design.cellTypes.EnumA[PrefixifyCellType];
RETURN};
noIntPart: INT ~ -1;
fixSet: Set--{noIntPart, 1}-- ~ Sets.CreateList[vals: LIST[IV[noIntPart], IV[1]], space: SetBasics.ints, mutability: constant, order: fwd];
PrefixifyCellType: PROC [cta: REF ANY] ~ {
ct: CellType ~ NARROW[cta];
IF ct.asUnorganized#NIL THEN {
root: Wire ~ ct.asUnorganized.internalWire;
parsed: BiRel--ROPE INT-- ~ BiRels.GenCreate[spaces: [SetBasics.ropes[TRUE], SetBasics.ints], mappable: [TRUE, FALSE], hints: [[fn: [$Hash], set: [$Vector]], []]];
FixWire: PROC [w: Wire, prefix: ROPE, dotPos: INT] ~ {
subscripts: Set--of INT-- ~ parsed.MappingA[prefix];
newName: ROPE ~ prefix.Replace[start: dotPos, len: 0, with: ".0"];
IF NOT subscripts.Equal[fixSet] THEN ERROR;
ForgetVertexName[w, LSn[LIST[prefix]]];
KnowVertexName[w, LSn[LIST[newName]]];
RETURN};
FOR w: Wire ← ct.asUnorganized.internalWire.FirstChildWire, w.NextChildWire WHILE w#NIL DO
PrefixifyName: PROC [snv: Sets.Value] ~ {
sn: SteppyName ~ VSn[snv];
name: ROPE ~ NARROW[sn.steps.first];
namelen: INT ~ name.Length[];
dotPos: INT ← -1;
sepPos: INT ← namelen;
IF sn.steps.rest#NIL THEN ERROR;
FOR idx: INT DECREASING IN [0 .. namelen) DO
SELECT name.InlineFetch[idx] FROM
'← => sepPos ← idx;
'. => {dotPos ← idx; EXIT};
ENDCASE => NULL;
ENDLOOP;
IF dotPos>=0 THEN {
prefix: ROPE ~ name.Replace[start: dotPos, len: sepPos-dotPos, with: NIL];
intPart: INT ~ Convert.IntFromRope[name.Substr[dotPos+1, sepPos-dotPos-1]];
IF intPart<0 THEN ERROR;
IF prefix.Length[]=0 THEN ERROR;
[] ← parsed.AddPair[[AV[prefix], IV[intPart]]];
IF parsed.HasPair[[AV[prefix], IV[noIntPart]]] THEN FixWire[NARROW[FetchVertex[ct, LSn[LIST[prefix]]]], prefix, dotPos];
RETURN}
ELSE {
fix: BOOL ~ parsed.HasMapA[name];
[] ← parsed.AddPair[[AV[name], IV[noIntPart]]];
IF fix THEN FixWire[w, name, sepPos];
RETURN};
};
w.VertexNames.Enumerate[PrefixifyName];
ENDLOOP;
RETURN};
RETURN};
InheritNames: PUBLIC PROC [design: Design] ~ {
Subject: TYPE ~ REF ANY --actuall, UNION [Vertex, Port, CellType]--;
inherited: Set--of CellType-- ~ Sets.CreateHashSet[];
WorkToCT: PROC [cta: REF ANY] ~ {Ensure[NARROW[cta]]; RETURN};
Ensure: PROC [ct: CellType] ~ {
InheritFromCI: PROC [cia: REF ANY] ~ {
ci: CellInstance ~ NARROW[cia];
WorkFrom: PROC [cellward: Vertex, fullnames, portnames: ListData] ~ {
TakeStep: PROC [port: Port, wireward: Vertex] ~ {
subfullnames: ListData ~ CrossNames[Setify[fullnames], port.PortNames];
subportnames: ListData ~ IF portnames=noListData THEN port.names ELSE CrossNames[Setify[portnames], port.PortNames];
WITH wireward SELECT FROM
w: Wire => AddVertexNames[w, subfullnames];
im: Intermediary => {AddVertexNames[im, subportnames]; WorkFrom[im, subfullnames, subportnames]};
ci: CellInstance => ERROR;
ENDCASE => ERROR;
RETURN};
cellward.EnumerateImmediateConnections[Consume: TakeStep, filter: [cellward: FALSE, wireward: TRUE]];
RETURN};
IF Asserting.FnVals[$MOSFETFlavor, ci.type.otherPublic]#NIL THEN RETURN;
Ensure[ci.type];
WorkFrom[ci, ci.names, noListData];
RETURN};
UnorganizedInheritToPort: PROC [port: Port] RETURNS [doKids, moreSibs: BOOLTRUE] ~ {
IF port.wire#NIL THEN {
rel: Wire ~ WITH port.parent SELECT FROM
p: Port => p.wire,
ct: CellType => NIL,
ENDCASE => ERROR;
GetNames: PROC [w: Wire, names: ListData] RETURNS [ListData] ~ {
IF w.containingWire=rel OR w.containingWire=ct.asUnorganized.internalWire THEN RETURN [names];
RETURN GetNames[w.containingWire, CrossNames[Setify[names], w.containingWire.VertexNames]]};
names: ListData ~ GetNames[port.wire, port.wire.names];
AddPortNames[port, names];
RETURN};
RETURN};
IF NOT inherited.AddA[ct] THEN RETURN;
IF ct.inheritNames THEN ERROR;
ct.inheritNames ← TRUE;
IF ct.asUnorganized#NIL THEN {
ct.asUnorganized.containedInstances.EnumA[InheritFromCI];
[] ← ct.port.EnumeratePort[UnorganizedInheritToPort];
RETURN}
ELSE IF ct.asArray#NIL THEN {
a: Array ~ ct.asArray;
ArrayInheritToPort: PROC [apa, paia: REF ANY] ~ {
ap: Port ~ NARROW[apa];
pai: PortAtIndex ~ NARROW[paia];
idx: SteppyName ~ LichenArrayStuff.NameIndex[a, pai.ai];
names: ListData ~ CrossNames[Setify[CreateSteppyNames[LIST[idx]]], pai.port.PortNames];
AddPortNames[ap, names];
RETURN};
Ensure[a.eltType];
a.statrep.apToPAI.EnumAA[ArrayInheritToPort];
RETURN};
RETURN};
design.cellTypes.EnumA[WorkToCT];
RETURN};
AddVertexNames: PROC [v: Vertex, names: ListData] ~ {
news: Set--of SteppyName-- ~ Setify[names];
bestOld: SteppyName ~ VSn[v.VertexNames.First.DVal[noNameVal]];
bestNew: SteppyName ~ VSn[news.First.DVal[noNameVal]];
InheritVertexName: PROC [namev: Sets.Value] ~ {
name: SteppyName ~ VSn[namev];
[] ← KnowVertexName[v, name];
RETURN};
IF bestNew#noName AND (bestOld=noName OR SteppyNameGradeCompare[bestNew.grade, bestOld.grade]<=equal) THEN news.Enumerate[InheritVertexName];
RETURN};
AddPortNames: PROC [port: Port, names: ListData] ~ {
news: Set--of SteppyName-- ~ Setify[names];
bestOld: SteppyName ~ VSn[port.PortNames.First.DVal[noNameVal]];
bestNew: SteppyName ~ VSn[news.First.DVal[noNameVal]];
InheritPortName: PROC [namev: Sets.Value] ~ {
name: SteppyName ~ VSn[namev];
[] ← KnowPortName[port, name];
RETURN};
IF bestNew#noName AND (bestOld=noName OR SteppyNameGradeCompare[bestNew.grade, bestOld.grade]<=equal) THEN news.Enumerate[InheritPortName];
RETURN};
END.