<> <> DIRECTORY Convert, Core, CoreClasses, CoreOps, HashTable, IO, CoreName, REFBit, Rope; CoreNameImpl: CEDAR PROGRAM IMPORTS Convert, CoreClasses, CoreOps, 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: ROPE_NIL] 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: ROPE_NIL] 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: ROPE _ NIL] 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: BOOL _ TRUE; 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: ROPE _ NIL] RETURNS [cell: CellType] = { RegPubs: CoreOps.EachWireProc = {[]_CtxRegisterWire[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}; END.