LichenImplNaming.Mesa
Last tweaked by Mike Spreitzer on April 12, 1989 1:50:13 am PDT
DIRECTORY AbSets, BiRelBasics, BiRels, Convert, FS, IntStuff, IO, LichenDataOps, LichenDataStructure, Rope, SetBasics;
LichenImplNaming: CEDAR PROGRAM
IMPORTS AbSets, BiRelBasics, BiRels, Convert, IntStuff, LichenDataOps, LichenDataStructure, Rope, SetBasics
EXPORTS LichenDataOps
=
BEGIN OPEN IS:IntStuff, Sets:AbSets, LichenDataStructure, LichenDataOps;
Break: SIGNAL ~ CODE;
PrefixifyDesign: PUBLIC PROC [design: Design] ~ {
design.cellTypes.EnumA[PrefixifyCellType];
RETURN};
CleanupDesignNames: PUBLIC PROC [d: Design] ~ {
CleanupPerType: PROC [ctv: Sets.Value] RETURNS [BOOL] ~ {
ct: CellType ~ NARROW[ctv.VA];
CleanupCT[ct, p];
IF ct.asu#NIL THEN CleanupCT[ct, w];
RETURN [FALSE]};
IF d.cellTypes.Scan[CleanupPerType].found THEN ERROR;
RETURN};
CollapseDesign: PROC [d: Design] ~ {
CollapsePerType: PROC [ctv: Sets.Value] RETURNS [BOOL] ~ {
ct: CellType ~ NARROW[ctv.VA];
CollapseCT[ct, p];
IF ct.asu#NIL THEN CollapseCT[ct, w];
RETURN [FALSE]};
IF d.cellTypes.Scan[CollapsePerType].found THEN ERROR;
RETURN};
noIntPart: INT ~ -1;
fixSet: Set--{noIntPart, 1}-- ~ Sets.CreateList[vals: LIST[IV[noIntPart], IV[1]], space: SetBasics.ints, mutability: constant, order: Sets.fwd];
noIntSet: Set ~ Sets.CreateSingleI[noIntPart, SetBasics.ints];
ref0: REF INT ~ NEW [INT ← 0];
name0: SteppyName ~ OSn[ref0];
breakICT: CellType ← NIL;
breakPortName: SteppyName ← noName;
PrefixifyCellType: PROC [cta: REF ANY] ~ {
ct: CellType ~ NARROW[cta];
PrefixifyCellTypesClass[ct, p];
IF ct.asu#NIL THEN PrefixifyCellTypesClass[ct, w];
RETURN};
PrefixifyCellTypesClass: PROC [ct: CellType, class: PWClass] ~ {
d: Design ~ ct.d;
parsed: BiRel--Steppy INT-- ~ BiRels.GenCreate[spaces: [steppyNameSpace, SetBasics.ints], mappable: [TRUE, FALSE], hints: [[fn: [$Hash], set: [$Vector]], []]];
dotted: Fn--Steppy b {$T, $F}-- ~ BiRels.CreateHashTable[[steppyNameSpace, SetBasics.refs]];
sfxposes: Fn--Steppy b INT-- ~ BiRels.CreateHashTable[[steppyNameSpace, SetBasics.ints]];
FixIt: PROC [it: PW, prefix: SteppyName] ~ {
subscripts: Set--of INT-- ~ parsed.Mapping[SnV[prefix]];
old: SteppyName ~ prefix;
new: SteppyName ~ old.SNCat[name0];
IF NOT subscripts.Equal[fixSet] THEN ERROR;
ReplaceDescendantsName[ct, it, old, new];
RETURN};
<<FixBar: PROC [pair: BiRels.Pair] RETURNS [BOOL] ~ {
sn: SteppyName ~ VSn[pair[right]];
name: ROPE ~ NARROW[sn.steps.first];
namelen: INT ~ name.Length[];
IF sn.steps.rest#NIL THEN ERROR;
IF sn.grade.gend THEN RETURN [FALSE];
{zot: INT ~ name.Index[s2: "𡤋←"];
IF zot < namelen THEN {
newName: ROPE ~ name.Replace[start: zot, len: 2, with: NIL].Concat["𡤋"];
[] ← ct.fullName[class].RemPair[pair];
[] ← ct.fullName[class].AddPair[[pair[left], OSn[newName].SnV]]};
RETURN [FALSE]}};>>
NoteNaming: PROC [pair: BiRels.Pair] RETURNS [BOOL] ~ {
sn: SteppyName ~ VSn[pair[right]];
IF sn.grade.gend THEN RETURN [FALSE];
{snx: SteppyNameSplit ~ SplitSteppy[sn];
name: ROPE ~ snx.lastRope;
namelen: INT ~ name.Length[];
sepPos: INT ~ name.SkipTo[skip: "!←"];
dotPos: INT ← name.FindBackward["."];
endPos: INT ← dotPos+1;
hasDot: BOOLFALSE;
IF dotPos>0 THEN endPos ← name.SkipOver[dotPos+1, "0123456789"];
IF endPos>dotPos+1 THEN hasDot ← TRUE ELSE {
dotPos ← SkipOverBackwardDigits[name, sepPos-1];
endPos ← sepPos};
{
sfxPos: INT ~ dotPos + (IF hasDot THEN 0 ELSE 1);
IF sfxPos < endPos THEN {
ohne: ROPE ~ name.Replace[start: sfxPos, len: endPos-sfxPos, with: NIL];
intPart: INT ~ Convert.IntFromRope[name.Substr[dotPos+1, endPos-dotPos-1]];
IF intPart<0 THEN ERROR;
IF ohne.Length[]=0 THEN ERROR;
{squzd: SteppyName ~ UnsplitSteppy[[snx.pre, ohne, snx.post]];
IF dotted.AddPair[[SnV[squzd], AV[IF hasDot THEN $T ELSE $F]]].had[leftToRight] = different THEN ERROR;
IF sfxposes.AddPair[[SnV[squzd], IV[sfxPos]]].had[leftToRight]=different THEN ERROR;
[] ← parsed.AddPair[[SnV[squzd], IV[intPart]]];
RETURN [FALSE]}}
ELSE {
[] ← parsed.AddPair[[SnV[sn], IV[noIntPart]]];
RETURN [FALSE]};
}}};
Recon: PROC [prefv: Sets.Value] RETURNS [BOOL] ~ {
sn: SteppyName ~ VSn[prefv];
snx: SteppyNameSplit ~ SplitSteppy[sn];
prefix: ROPE ~ snx.lastRope;
sufixs: Set ~ parsed.Mapping[prefv];
IF sufixs.Equal[noIntSet] THEN RETURN [FALSE];
{sfxPos: INT ~ sfxposes.Apply[prefv].MI;
hasDot: BOOL ~ SELECT dotted.Apply[prefv].MA FROM
$F => FALSE,
$T => TRUE,
ENDCASE => ERROR;
dot: ROPE ~ IF hasDot THEN "." ELSE NIL;
PerSuffix: PROC [sufv: Sets.Value] RETURNS [BOOL] ~ {
intPart: INT ~ sufv.VI;
IF intPart=noIntPart THEN {
x: PW ~ FetchPW[ct, class, sn];
IF x=NIL THEN ERROR;
FixIt[x, sn];
RETURN [FALSE]}
ELSE {
newsn: SteppyName ~ sn.SNCat[OSn[NewInt[intPart]]];
oldsn: SteppyName ← noName;
x: PW ← NIL;
FOR intRope: ROPE ← Convert.RopeFromInt[intPart], Rope.Concat["0", intRope] WHILE x=NIL AND intRope.Length[]<5 DO
oldr: ROPE ~ prefix.Replace[start: sfxPos, len: 0, with: dot.Concat[intRope]];
oldsn ← UnsplitSteppy[[snx.pre, oldr, snx.post]];
x ← FetchPW[ct, class, oldsn];
ENDLOOP;
IF x=NIL THEN ERROR;
ReplaceDescendantsName[ct, x, oldsn, newsn];
RETURN [FALSE]};
};
IF (NOT hasDot) AND sufixs.Size.EN<thresh THEN RETURN [FALSE];
IF sufixs.Scan[PerSuffix].found THEN ERROR;
RETURN [FALSE]}};
<<IF ct.fullName[class].Scan[FixBar].found THEN ERROR;>>
IF ct.fullName[class].Scan[NoteNaming].found THEN ERROR;
IF parsed.SetOn[left].Scan[Recon].found THEN ERROR;
RETURN};
thresh: NAT ← 6;
FetchPW: PROC [ct: CellType, class: PWClass, fullName: SteppyName] RETURNS [PW]
~ INLINE {RETURN [NARROW[ct.fullName[class].InvApply[SnV[fullName]].MDA]]};
SkipOverBackwardDigits: PROC [s: ROPE, pos: INT] RETURNS [INT] ~ {
FOR pos ← pos, pos-1 WHILE pos>=0 AND s.InlineFetch[pos] IN ['0..'9] DO NULL ENDLOOP;
RETURN [pos]};
SteppyNameSplit: TYPE ~ RECORD [pre: SteppyName, lastRope: ROPE, post: SteppyName];
SplitSteppy: PROC [sn: SteppyName] RETURNS [snx: SteppyNameSplit] ~ {
IF sn.grade.nonsubs<1 THEN ERROR;
snx ← [noName, NIL, sn];
DO
WITH snx.post.steps.first SELECT FROM
x: ROPE => IF snx.post.grade.nonsubs=1 THEN EXIT ELSE snx.post.grade.nonsubs ← snx.post.grade.nonsubs-1;
x: REF INT => snx.post.grade.subs ← snx.post.grade.subs-1;
ENDCASE => ERROR;
snx.post.steps ← snx.post.steps.rest;
ENDLOOP;
snx.lastRope ← NARROW[snx.post.steps.first];
snx.pre ← LSn[CopyTill[sn.steps, snx.post.steps].head];
snx.post ← snx.post.SNTail;
RETURN};
UnsplitSteppy: PROC [snx: SteppyNameSplit] RETURNS [SteppyName] ~
{RETURN snx.pre.SNCat[OSn[snx.lastRope].SNCat[snx.post]]};
refEmpty: REF ANY ~ BiRels.CreateEmptyBiRel[ALL[steppyNameSpace]].Refify[];
InheritNames: PUBLIC PROC [design: Design, cleanup, collapse: BOOL, renames: Fn--CellType b Fn(old steppy b new)--] ~ {
Subject: TYPE ~ REF ANY --actuall, UNION [Vertex, Port, CellType]--;
inherited: Set--of CellType-- ~ Sets.CreateHashSet[design.eSpace];
WorkToCT: PROC [cta: REF ANY] ~ {Ensure[NARROW[cta]]; RETURN};
Ensure: PROC [ct: CellType] ~ {
rns: Fn--old steppy b new-- ~ BiRels.DeRef[renames.ApplyA[ct].MDA[refEmpty]];
rnDom: Set ~ rns.SetOn[left];
InheritFromCI: PROC [civ: Sets.Value] ~ {
ci: CellInstance ~ NARROW[civ.VA];
ict: CellType ~ design.CiT[ci];
ciNames: Set--of SteppyName-- ~ ct.INames[ci];
dumed: Set ← ciNames.Intersection[rnDom];
InheritAlongConnection: PROC [porta, wirea: REF ANY] ~ {
port: Port ~ NARROW[porta];
wire: Wire ~ NARROW[wirea];
portNames: Set ~ ict.PNames[port];
IF ict=breakICT AND portNames.HasMember[SnV[breakPortName]] THEN Break[];
KnowVertexNames[ct, wire, ActualNames[design.labelCellTypes.HasMemA[ict], ciNames, portNames], TRUE];
RETURN};
IF ict.asTrans#NIL THEN RETURN;
Ensure[ict];
IF dumed.NonEmpty THEN {
new: Set ~ rns.Image[dumed ← dumed.CreateHashCopy[]].CreateHashCopy[];
ForgetPartNames[ct, i, ci, dumed];
KnowPartNames[ct, i, ci, new, TRUE];
ct ← ct};
ci.conns.EnumAA[InheritAlongConnection];
RETURN};
UnorganizedInheritToPort: PROC [portv: Sets.Value] ~ {
port: Port ~ NARROW[portv.VA];
wire: Wire ~ ConndWire[ct, port];
IF wire#NIL THEN KnowPortNames[ct, port, ct.WNames[wire], TRUE];
RETURN};
IF NOT inherited.AddA[ct] THEN RETURN;
IF ct.asu#NIL THEN {
wrens: LIST OF RECORD [w: Wire, old, new: SteppyName] ← NIL;
FindRen: PROC [pair: BiRels.Pair] RETURNS [BOOL] ~ {
w: Wire ~ NARROW[pair[left].VA];
old: SteppyName ~ VSn[pair[right]];
new: SteppyName ~ VSn[rns.Apply[pair[right]].Val];
wrens ← CONS[[w, old, new], wrens];
RETURN [FALSE]};
design.cct[i].EnumerateMapping[AV[ct], InheritFromCI, rightToLeft];
IF ct.fullName[w].ScanHalfRestriction[rnDom, FindRen, right].found THEN ERROR;
WHILE wrens # NIL DO
ReplaceDescendantsName[ct, wrens.first.w, wrens.first.old, wrens.first.new];
wrens ← wrens.rest;
ENDLOOP;
IF cleanup THEN CleanupCT[ct, w];
IF collapse THEN CollapseCT[ct, w];
design.cct[p].EnumerateMapping[AV[ct], UnorganizedInheritToPort, rightToLeft];
IF cleanup THEN CleanupCT[ct, p];
IF collapse THEN CollapseCT[ct, p];
RETURN}
ELSE IF ct.asArray#NIL THEN {
a: Array ~ ct.asArray;
ect: CellType ~ ct.EltType[];
ArrayInheritToPort: PROC [pair: BiRels.Pair] ~ {
ap: Port ~ NARROW[pair[left].VA];
dw: DumbWire ~ NARROW[pair[right].VA];
aloc: BiRels.MaybePair ~ dw.eps.First[[[SetBasics.alleq, SetBasics.fwd], right]];
IF NOT aloc.found THEN RETURN;
{ep: Port ~ NARROW[aloc.it[left].VA];
ai: Int2 ~ DecomposeAI[a, aloc.it[right].VI];
names: Set ~ ActualNames[FALSE, OneSteppy[AIName[a, ai]], ect.PNames[ep]];
IF design.labelCellTypes.HasMemA[ect] THEN ERROR;
KnowPortNames[ct, ap, names, TRUE];
RETURN}};
Ensure[ect];
a.dumrep.apToWire.Enumerate[ArrayInheritToPort];
IF cleanup THEN CleanupCT[ct, p];
IF collapse THEN CollapseCT[ct, p];
RETURN};
RETURN};
IF design.inheritNames THEN ERROR;
design.inheritNames ← TRUE;
design.cellTypes.EnumA[WorkToCT];
RETURN};
CleanupCT: PROC [ct: CellType, class: PWClass] ~ {
CleanupPart: PROC [part: Part] ~ {
names: Set--of SteppyName-- ~ ct.PartNames[class, part];
IF names.Empty THEN RETURN;
{best: SteppyName ~ VSn[names.First[].Val];
Remit: PROC [v: Sets.Value] RETURNS [BOOL] ~ {
sn: SteppyName ~ VSn[v];
IF GrossSteppyNameGradeCompare[best.grade, sn.grade] < equal THEN [] ← names.RemElt[v];
RETURN [FALSE]};
IF best.grade.gend THEN RETURN;
IF names.Scan[Remit].found THEN ERROR}};
ct.EnumCTParts[class, TRUE, TRUE, CleanupPart];
RETURN};
CollapseCT: PROC [ct: CellType, class: PWClass] ~ {
bogon: CellInstance ~ NEW [VertexPrivate[i]];
tails: BiRel--part tail-- ~ BiRels.GenCreate[
spaces: [ct.d.eSpace, steppyNameSpace],
hints: [
leftToRight: [[$Hash], [$Hash]],
rightToLeft: [[$BalancedTree], [$Hash]] ]];
AddTail: PROC [pair: BiRels.Pair] RETURNS [BOOL] ~ {
part: Part ~ pair[left].VA;
name: SteppyName ← VSn[pair[right]];
WHILE name.grade.nonsubs > 1 DO
name ← name.SNTail;
[] ← tails.AddPair[[AV[part], SnV[name]]];
ENDLOOP;
RETURN [FALSE]};
AdoptTail: PROC [tv: Sets.Value] RETURNS [BOOL] ~ {
nParts: LNAT ~ tails.MappingSize[tv, rightToLeft, IS.two].EN;
IF nParts>1 THEN RETURN [FALSE];
IF nParts<1 THEN ERROR;
{part: Part ~ tails.Apply[tv, rightToLeft].MA;
fpart: Part ~ NARROW[ct.fullName[class].InvApply[tv].MDA];
IF fpart#NIL AND fpart#part THEN RETURN [FALSE];
{tail: SteppyName ~ VSn[tv];
names: Set ~ ct.fullName[class].MappingA[part];
pretails: Set ~ PreTails[tail];
IF NOT names.RemFilter[pretails].hadSome THEN ERROR;
KnowPartName[ct, class, part, tail, FALSE];
RETURN [FALSE]}}};
IF ct.fullName[class].Scan[AddTail].found THEN ERROR;
IF tails.SetOn[right].Scan[AdoptTail, Sets.bwd].found THEN ERROR;
RETURN};
GlobalizeCT: PROC [ct: CellType] ~ {
GlobalizeClass[ct, p];
IF ct.fullName[w] # nilBiRel THEN GlobalizeClass[ct, w];
RETURN};
GlobalizeClass: PROC [ct: CellType, class: PWClass] ~ {
d: Design ~ ct.d;
fn: BiRel ~ ct.fullName[class];
GlobalizePair: PROC [pair: BiRels.Pair] RETURNS [BOOL] ~ {
sn: SteppyName ← VSn[pair[right]];
IF sn.grade.global THEN RETURN [FALSE];
sn.grade.global ← TRUE;
[] ← fn.RemPair[pair];
[] ← fn.AddPair[[pair[left], SnV[sn]]];
RETURN [FALSE]};
IF fn.Scan[GlobalizePair].found THEN ERROR;
RETURN};
END.