CoreNameImpl.mesa
Created by Don Curry June 25, 1986 5:49:30 pm PDT
DIRECTORY Convert, Core, CoreOps, CoreProperties, HashTable, IO, CoreName, REFBit, Rope;
CoreNameImpl: CEDAR PROGRAM
IMPORTS Convert, CoreOps, CoreProperties, HashTable, IO, Rope
EXPORTS CoreName
~ BEGIN
ROPE:  TYPE = Core.ROPE;
Wire:  TYPE = Core.Wire;
CellType: TYPE = Core.CellType;
Context: TYPE = CoreName.Context;
Ph:  TYPE = CoreName.Ph;
Polarity: TYPE = CoreName.Polarity;
SigRec: TYPE = CoreName.SigRec;
table: HashTable.Table ←
HashTable.Create[equal: HashTable.RopeEqual, hash: HashTable.HashRope];
NILRope:    ROPE = "NIL";
nilRope:     ROPE = "nil";
NILRopeRegistered: BOOL ← HashTable.Store[table, NILRope, nilRope];
nilRopeRegistered: BOOL ← HashTable.Store[table, nilRope,  nilRope];
Signal: SIGNAL = CODE;
RopeNm: PUBLIC PROC[rope: ROPE] RETURNS[registered: ROPE] = {
IF rope=NIL THEN RETURN[NIL];
registered ← NARROW[HashTable.Fetch[table, rope].value];
SELECT registered FROM
nilRope => RETURN[NIL];
NIL  => {[] ← HashTable.Store[table, rope, rope]; RETURN[rope]};
ENDCASE => RETURN[registered]};
WireNm: PUBLIC PROC[wire: Core.Wire, rope: ROPENIL]
RETURNS[w: Core.Wire, n: ROPE] = {
IF wire=NIL THEN RETURN[NIL, NIL];
IF rope=NIL THEN rope ← CoreOps.GetShortWireName[wire];
n ← RopeNm[rope];
w ← CoreOps.SetShortWireName[wire, n]};
CellNm: PUBLIC PROC[cell: Core.CellType, rope: ROPENIL]
RETURNS[c: Core.CellType, n: ROPE] = {
IF rope=NIL THEN rope ← CoreOps.GetCellTypeName[cell];
n ← RopeNm[rope];
c ← CoreOps.SetCellTypeName[cell, n]};
NextIDIndex: INT ← 0;
ID: PUBLIC PROC[rope: ROPE] RETURNS[unique: ROPE] = {
unique ← RopeNm[IO.PutFR["%g%g", IO.rope[rope], IO.int[NextIDIndex]]];
NextIDIndex ← NextIDIndex+1};
NewContext: PUBLIC PROC RETURNS[ctx: Context] =
{RETURN[HashTable.Create[equal: HashTable.RopeEqual, hash: HashTable.HashRope]]};
CtxCopyWire: PUBLIC PROC[ctx: Context, wire: Core.Wire]
RETURNS[new: Core.Wire] = {
Copy: PROC [wire: Core.Wire] RETURNS [new: Core.Wire] = {
IF (new ← NARROW[HashTable.Fetch[table: visitTab, key: wire].value])=NIL THEN {
name: ROPE ← WireNm[wire].n;
new ← CtxNameToWire[ctx, name];
IF new#NIL THEN
{[]←HashTable.Insert[table: visitTab, key: wire, value: new]; RETURN[new]};
new ← CoreOps.CreateWires
[size: wire.size, props: CoreProperties.CopyProps[propList: wire.properties]];
IF name#NIL THEN IF NOT CtxRegisterWire[ctx, new, name].ok THEN ERROR;
IF NOT HashTable.Insert[table: visitTab, key: wire, value: new] THEN ERROR;
FOR i: NAT IN [0 .. wire.size) DO new[i] ← Copy[wire[i]] ENDLOOP } };
visitTab: HashTable.Table ← HashTable.Create[]; -- Wire to Wire
IF ctx=NIL THEN RETURN[NIL];
new ← IF wire=NIL THEN NIL ELSE Copy[wire] };
CtxWire: PUBLIC PROC[ctx: Context, name: ROPE, size: INT ← -1]
RETURNS[wire: Core.Wire] = {
IF ctx=NIL THEN RETURN[NIL];
IF name=NIL OR name.Length[]=0 THEN RETURN[NIL];
wire ← CtxNameToWire[ctx, name];
IF wire=NIL
THEN {wire ← NEW[Core.WireRec[MAX[size, 0]]]; [ ] ← CtxRegisterWire[ctx, wire, name]}
ELSE {IF size#-1 AND wire.size#size THEN wire ← NIL}};
CtxRegisterWire: PUBLIC PROC[ctx: Context, wire: Core.Wire, name: ROPENIL]
RETURNS[ok: BOOL] ={
oldWire: Core.Wire;
IF ctx=NIL THEN RETURN[FALSE];
IF name=NIL OR name.Length[]=0 THEN name ← CoreOps.GetShortWireName[wire];
IF name=NIL OR name.Length[]=0 THEN RETURN[FALSE];
oldWire ← NARROW[HashTable.Fetch[ctx, name].value];
IF oldWire#NIL AND oldWire#wire THEN RETURN[FALSE];
wire ← CoreOps.SetShortWireName[wire, RopeNm[name]];
IF oldWire=wire THEN RETURN[TRUE];
[ ] ← HashTable.Store[ctx, name, wire]};
CtxNameToWire: PUBLIC PROC[ctx: Context, name: ROPE] RETURNS[wire: Core.Wire] = {
IF ctx=NIL THEN RETURN[NIL];
IF name=NIL OR name.Length[]=0 THEN RETURN[NIL];
wire ← NARROW[HashTable.Fetch[ctx, name].value]};
CtxWireToName: PUBLIC PROC[ctx: Context, wire: Core.Wire] RETURNS[name: ROPE] = {
oldWire: Core.Wire;
IF ctx=NIL THEN RETURN[NIL];
IF wire=NIL THEN RETURN[NIL];
name  ← CoreOps.GetShortWireName[wire];
oldWire ← NARROW[HashTable.Fetch[ctx, name].value];
RETURN[ IF wire=NIL OR oldWire=NIL OR wire#oldWire THEN NIL ELSE name]};
WiresFromCtx: PUBLIC PROC[ctx: Context] RETURNS[wires: Core.Wires] = {
action: HashTable.EachPairAction = {wires ← CONS[NARROW[value], wires]};
[ ] ← HashTable.Pairs[ctx, action]};
WireFromCtx: PUBLIC PROC[ctx: Context] RETURNS[wire: Core.Wire] =
{wire ← CoreOps.CreateWire[ WiresFromCtx[ctx] ]};
killing: BOOLTRUE;
KillContext: PUBLIC PROC[ctx: Context] RETURNS[Context] =
{IF killing
THEN {HashTable.Erase[ctx]; RETURN[NIL]}
ELSE {RETURN[ctx]}};
PrintWire: PUBLIC PROC[wire: Core.Wire] = {
};
PhRope: PUBLIC ARRAY Ph OF ROPE
["A", "AB", "ABB", "ABBB", "Ac", "B", "BA", "BAA", "BAAA", "Bc", ""];
PolarityRope: PUBLIC ARRAY Polarity OF ROPE ← ["", "n", "?n"];
SignalName: PUBLIC PROC [not: BOOL, pos, neg: ROPE, ph: Ph, cy: INT←-1]
RETURNS [name: ROPE] ~ {
altName, phRope, cyRope: ROPE;
end: INT;
IF not
THEN {name ← neg; altName ← pos}
ELSE {name ← pos; altName ← neg};
phRope ← PhRope[ph];
cyRope ← IF cy=-1 THEN NIL ELSE Convert.RopeFromInt[cy];
IF name = NIL THEN name ← Rope.Cat["Not", altName];
end ← name.Index[0, "."];
name ← name.Substr[0, end].Cat[cyRope, phRope, name.Substr[end]]};
ParseSignalName: PUBLIC PROC [name: ROPE]
RETURNS [not: BOOL, root: ROPE, ph: Ph, cy: INT←-1] ~ {
phasesize: ARRAY Ph OF INT ← [1,2,3,4,2,1,2,3,4,2,0];
sufix: ROPE;
end: INT;
not4: BOOL ← Rope.Equal[name.Substr[0, 4], "Not.", FALSE];
not3: BOOL ← Rope.Equal[name.Substr[0, 3], "Not", FALSE];
name ← name.Substr[start: (IF not4 THEN 4 ELSE IF not3 THEN 3 ELSE 0)];
not ← not3 OR not4;
end ← name.Index[0, "."];
root ← name.Substr[0, end];
sufix ← IF end< name.Length THEN name.Substr[end] ELSE NIL;
ph ← SELECT name.Fetch[root.Length[]-1] FROM
'A => SELECT root.Fetch[root.Length[]-2] FROM
'B   => BA,
'A   => SELECT root.Fetch[root.Length[]-3] FROM
'B   => BAA,
'A   => SELECT root.Fetch[root.Length[]-4] FROM
'B   => BAAA,
ENDCASE => unk,
ENDCASE => unk,
ENDCASE => A,
'B => SELECT root.Fetch[root.Length[]-2] FROM
'A   => AB,
'B   => SELECT root.Fetch[root.Length[]-3] FROM
'A   => ABB,
'B   => SELECT root.Fetch[root.Length[]-4] FROM
'A   => ABBB,
ENDCASE => unk,
ENDCASE => unk,
ENDCASE => B,
'c => SELECT root.Fetch[root.Length[]-2] FROM
'A   => Ac,
'B   => Bc,
ENDCASE => unk,
ENDCASE => unk;
root ← root.Substr[0, root.Length[]-phasesize[ph]];
root ← root.Cat[sufix] };
SigName: PUBLIC PROC [sigRec: SigRec] RETURNS [name: ROPE ← NIL ] ~ {
name ← sigRec.root;
IF name = NIL THEN RETURN[NIL];
IF sigRec.not   THEN name ← Rope.Cat["Not", name];
IF sigRec.cy#-1  THEN name ← name.Cat[ Convert.RopeFromInt[sigRec.cy]];
IF sigRec.ph#unk THEN name ← name.Cat[ PhRope[sigRec.ph]];
IF sigRec.idx#-1 THEN name ← name.Cat[ ".", Convert.RopeFromInt[sigRec.idx]];
name ← RopeNm[name]};
NameSig: PUBLIC PROC [name: ROPE] RETURNS [sigRec: SigRec ← [ ] ] ~ {
phasesize: ARRAY Ph OF INT ← [1,2,3,4,2,1,2,3,4,2,0];
char: CHARACTER;
end: INT;
not4: BOOL ← Rope.Equal[name.Substr[0, 4], "Not.", FALSE];
not3: BOOL ← Rope.Equal[name.Substr[0, 3], "Not", FALSE];
IF name=NIL THEN RETURN[[]];
name ← name.Substr[start: (IF not4 THEN 4 ELSE IF not3 THEN 3 ELSE 0)];
sigRec.not ← not3 OR not4;
end ← name.Index[0, "."];
sigRec.root ← name.Substr[0, end];
sigRec.idx ← IF (end+1)< name.Length
THEN Convert.IntFromRope[name.Substr[end+1]] ELSE -1;
sigRec.ph ← SELECT name.Fetch[sigRec.root.Length[]-1] FROM
'A => SELECT sigRec.root.Fetch[sigRec.root.Length[]-2] FROM
'B   => BA,
'A   => SELECT sigRec.root.Fetch[sigRec.root.Length[]-3] FROM
'B   => BAA,
'A   => SELECT sigRec.root.Fetch[sigRec.root.Length[]-4] FROM
'B   => BAAA,
ENDCASE => unk,
ENDCASE => unk,
ENDCASE => A,
'B => SELECT sigRec.root.Fetch[sigRec.root.Length[]-2] FROM
'A   => AB,
'B   => SELECT sigRec.root.Fetch[sigRec.root.Length[]-3] FROM
'A   => ABB,
'B   => SELECT sigRec.root.Fetch[sigRec.root.Length[]-4] FROM
'A   => ABBB,
ENDCASE => unk,
ENDCASE => unk,
ENDCASE => B,
'c => SELECT sigRec.root.Fetch[sigRec.root.Length[]-2] FROM
'A   => Ac,
'B   => Bc,
ENDCASE => unk,
ENDCASE => unk;
sigRec.root ← sigRec.root.Substr[0, sigRec.root.Length[]-phasesize[sigRec.ph]];
char ← sigRec.root.Fetch[sigRec.root.Length[]-1];
IF char IN ['0..'9] THEN {
sigRec.cy  ← char.ORD - '0.ORD;
sigRec.root ← sigRec.root.Substr[0, sigRec.root.Substr.Length[]-1]};
sigRec.root ← RopeNm[sigRec.root] };
SelectName: PUBLIC PROC[inv: BOOL, posNm, negNm: ROPE]
RETURNS [inverted: BOOL, name: ROPE] = {
sig, sigI: SigRec;
IF posNm=NIL THEN {inv ← ~inv; posNm ← negNm; negNm ← NIL};
sig ← NameSig[posNm];
sigI ← NameSig[negNm];
IF inv#sig.not AND negNm#NIL AND inv#sigI.not THEN {sig ← sigI; inv ← ~inv};
inverted ← inv#sig.not; sig.not ← FALSE;  name ← SigName[sig]};
NormalFormatNames: PUBLIC PROC [format: REFBit.FormatRec]
RETURNS[name, nameInv: ROPE, dual, inverted: BOOL, cy, idx: INT] = {
name  ← BitRopeToSigRope[format.name];
nameInv ← BitRopeToSigRope[format.nameInv];
IF name#NIL AND nameInv#NIL
THEN {
sig: SigRec ← NameSig[name];
sigI: SigRec ← NameSig[nameInv];
IF sig.not#sigI.not THEN Signal[];
IF sig.cy#sigI.cy THEN Signal[];
IF sig.idx#sigI.idx THEN Signal[];
IF sig.not
THEN {name  ← sigI.root; nameInv ← sig.root}
ELSE {name  ← sig.root; nameInv ← sigI.root};
cy   ← sig.cy;
idx  ← sig.idx;
inverted ← FALSE;
dual  ← TRUE }
ELSE {
sig: SigRec;
IF name#NIL
THEN {sig ← NameSig[name];  inverted ←  sig.not}
ELSE {sig ← NameSig[nameInv]; inverted ← NOT sig.not};
name  ← sig.root;
nameInv ← NIL;
dual  ← FALSE ;
cy   ← sig.cy;
idx  ← sig.idx }};
NormalFormatNames: PUBLIC PROC [format: REFBit.FormatRec]
RETURNS[name, nameInv: ROPE, dual, inverted: BOOL, cy, idx: INT] = {
sig: SigRec;
name  ← BitRopeToSigRope[format.name];
nameInv ← BitRopeToSigRope[format.nameInv];
IF name#NIL AND nameInv#NIL
THEN {
sig ← NameSig[name];  name  ← sig.root;
sig ← NameSig[nameInv]; nameInv ← sig.root;
dual ← TRUE}
ELSE IF name#NIL
THEN {sig ← NameSig[name];  inverted ←  sig.not}
ELSE {sig ← NameSig[nameInv]; inverted ← NOT sig.not; nameInv ← NIL};
name ← sig.root;
cy  ← sig.cy;
idx ← sig.idx };
BitRopeToSigRope: PUBLIC PROC [name: ROPE] RETURNS [ROPE] ~ {
Cap: PROC[rope: ROPE, idx: INT] RETURNS[ROPE] = {
char: CHAR ← rope.Fetch[idx+1];
IF char IN ['a..'z] THEN char ← char + LOOPHOLE['A - 'a];
RETURN[IO.PutFR["%g", IO.char[char]]]};
IF name = NIL THEN RETURN[NIL];
name ← Rope.Cat[Cap[name, -1], name.Substr[1]];
DO-- remove peiods and Capitalize next letters until end or next char is number
index: INT ← name.Index[0, "."];
IF index+1 >= name.Length[] OR name.Fetch[index+1] IN ['0..'9] THEN RETURN[name];
name ← Rope.Cat[name.Substr[0,index], Cap[name, index], name.Substr[index+2]];
ENDLOOP };
RootExt: PUBLIC PROC [name: ROPE] RETURNS [root, ext: ROPE] ~ {
end: INT;
end ← name.Index[0, "."];
root ← name.Substr[0, end];
ext ← IF end+1< name.Length THEN name.Substr[end] ELSE NIL};
END.