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: BOOL ← FALSE;
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.