CoreNameImpl.mesa
Created by Don Curry February 23, 1987 3:17:13 pm PST
DIRECTORY Convert, Core, CoreClasses, CoreOps, HashTable, IO, CoreName, REFBit, Rope;
CoreNameImpl: CEDAR PROGRAM
IMPORTS Convert, CoreClasses, CoreOps, HashTable, IO, REFBit, 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] -- only name prop is copied
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];
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;
[]←WireNm[new, name];
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] = {
TwoWires: TYPE = RECORD[w0, w1: Wire];
action: HashTable.EachPairAction = {wires ← CONS[NARROW[value], wires]};
ordered: BOOL;
[ ] ← HashTable.Pairs[ctx, action];
ordered ← wires=NIL OR wires.rest=NIL;
WHILE NOT ordered DO
ordered ← TRUE;
FOR ws: Core.Wires ← wires, ws.rest WHILE ws.rest # NIL DO
IF Rope.Compare[WireNm[ws.first].n, WireNm[ws.rest.first].n] = greater THEN
{[ws.first, ws.rest.first] ← TwoWires[ws.rest.first, ws.first]; ordered ← FALSE};
ENDLOOP;
ENDLOOP};
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]}};
BindModules: PUBLIC PROC[public: Wire, modules: LIST OF CellType, name: ROPENIL]
RETURNS [cell: CellType] = {
RegPubs: CoreOps.EachWireProc = {[]𡤌txRegisterWire[ctx, wire]};
ctx:   Context ← NewContext[];
rec:    CoreClasses.RecordCellType;
cnt:   NAT ← 0;
[] ← CoreOps.VisitWire[public, RegPubs];
FOR m: LIST OF CellType ← modules, m.rest WHILE m#NIL DO cnt ← cnt + 1 ENDLOOP;
rec ← NEW [CoreClasses.RecordCellTypeRec[cnt]];
cnt ← 0;
FOR m: LIST OF CellType ← modules, m.rest WHILE m#NIL DO
rec[cnt] ← NEW[ CoreClasses.CellInstanceRec ←
[actual: CtxCopyWire[ctx, m.first.public], type: m.first]];
cnt ← cnt+1 ENDLOOP;
rec.internal ← WireFromCtx[ctx];
cell   ← NEW [Core.CellTypeRec ← [
class:  CoreClasses.recordCellClass,
public: public,
data:  rec ]];
[ ] ← CellNm[cell, name];
ctx ← KillContext[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"];
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 }};
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};
EDTypeWire: PUBLIC PROC[root, ext, ref: ROPE] RETURNS[wire: Wire] = {
bitName, bitNameInv: ROPE;
refREF: REF ← REFBit.NEWFromName[ref];
format: REFBit.Format ← REFBit.Desc[refREF].bitForm;
wire ← CoreOps.CreateWires[MAX[2, format.size], root.Cat[ext]];
FOR i: INT IN[0..format.size) DO
bitName  ← BitRopeToSigRope[format[i].name];
bitNameInv ← BitRopeToSigRope[format[i].nameInv];
IF ((format.size#1) = (i+1=format.size)) = (bitName#NIL) THEN ERROR;
IF ((format.size#1) = (bitNameInv#NIL)) = (bitName#NIL) THEN ERROR;
IF bitName=NIL THEN bitName ← bitNameInv;
wire[i] ← CoreOps.CreateWires[0, root.Cat[bitName, ext]];
IF format.size=1 THEN
wire[1] ← CoreOps.CreateWires[0, root.Cat[bitNameInv, ext]];
ENDLOOP};
END.