LichenImplNaming.Mesa
Last tweaked by Mike Spreitzer on April 6, 1989 4:43:31 pm 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];
IF ct.asu#
NIL
THEN {
d: Design ~ ct.d;
parsed: BiRel--ROPE INT-- ~ BiRels.GenCreate[spaces: [SetBasics.ropes[TRUE], SetBasics.ints], mappable: [TRUE, FALSE], hints: [[fn: [$Hash], set: [$Vector]], []]];
dotted: Fn--ROPE b {$T, $F}-- ~ BiRels.CreateHashTable[[SetBasics.ropes[TRUE], SetBasics.refs]];
FixWire:
PROC [w: Wire, prefix:
ROPE] ~ {
subscripts: Set--of INT-- ~ parsed.MappingA[prefix];
old: SteppyName ~ OSn[prefix];
new: SteppyName ~ old.SNCat[name0];
IF NOT subscripts.Equal[fixSet] THEN ERROR;
ReplaceDescendantsName[ct, w, old, new];
RETURN};
<<FixBar:
PROC [pair: BiRels.Pair]
RETURNS [
BOOL] ~ {
w: Wire ~ NARROW[pair[left].VA];
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[w].RemPair[pair];
[] ← ct.fullName[w].AddPair[[pair[left], OSn[newName].SnV]]};
RETURN [FALSE]}};>>
NoteNaming:
PROC [pair: BiRels.Pair]
RETURNS [
BOOL] ~ {
w: Wire ~ NARROW[pair[left].VA];
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];
{sepPos: INT ~ name.Index[s2: "←"];
dotPos: INT ← -1;
hasDot: BOOL ← FALSE;
IF sepPos=0 THEN ERROR;
FOR idx:
INT
DECREASING
IN [0 .. sepPos)
DO
SELECT name.InlineFetch[idx]
FROM
IN ['0 .. '9] => NULL;
'. => {hasDot ← TRUE; dotPos ← idx; EXIT};
IN ['a..'z], IN ['A..'Z] => {hasDot ← FALSE; dotPos ← idx; EXIT};
ENDCASE => ERROR;
ENDLOOP;
IF dotPos<0 THEN ERROR;
{dd: INTEGER ~ IF hasDot THEN 0 ELSE 1;
sfxPos: INT ~ dotPos+dd;
IF dotPos+1 < sepPos
THEN {
prefix: ROPE ~ name.Replace[start: sfxPos, len: sepPos-sfxPos, with: NIL];
intPart: INT ~ Convert.IntFromRope[name.Substr[dotPos+1, sepPos-dotPos-1]];
IF dotted.AddAA[prefix, IF hasDot THEN $T ELSE $F].had[leftToRight] = different THEN ERROR;
IF intPart<0 THEN ERROR;
IF prefix.Length[]=0 THEN ERROR;
[] ← parsed.AddPair[[AV[prefix], IV[intPart]]];
RETURN [FALSE]}
ELSE {
[] ← parsed.AddPair[[AV[name], IV[noIntPart]]];
RETURN [FALSE]};
}}};
Recon:
PROC [prefv: Sets.Value]
RETURNS [
BOOL] ~ {
prefix: ROPE ~ NARROW[prefv.VA];
sufixs: Set ~ parsed.Mapping[prefv];
IF sufixs.Equal[noIntSet] THEN RETURN [FALSE];
{seppos: INT ~ prefix.Index[s2: "←"];
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 {
w: Wire ~ ct.FetchWire[OSn[prefix]];
FixWire[w, prefix];
RETURN [FALSE]}
ELSE {
oldsn: SteppyName ~ OSn[prefix.Replace[start: seppos, len: 0, with: dot.Concat[Convert.RopeFromInt[intPart]]]];
newsn: SteppyName ~ LSn[LIST[prefix, NewInt[intPart]]];
w: Wire ~ ct.FetchWire[oldsn];
ReplaceDescendantsName[ct, w, 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[w].Scan[FixBar].found THEN ERROR;>>
IF ct.fullName[w].Scan[NoteNaming].found THEN ERROR;
IF parsed.SetOn[left].Scan[Recon].found THEN ERROR;
RETURN};
RETURN};
thresh: NAT ← 6;
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.