DIRECTORY Core, CoreClasses, CoreConnect, CoreGlue, CoreName, CoreOps, CoreFrame, HashTable, IO, Rope; CoreConnectImpl: CEDAR PROGRAM IMPORTS CoreFrame, CoreName, CoreOps, HashTable, IO, Rope EXPORTS CoreConnect ~ BEGIN ROPE: TYPE = Core.ROPE; Path: TYPE = LIST OF INT; -- [bottom .. top] Addr: TYPE = LIST OF INT; -- [top .. bottom] CtxRec: TYPE = RECORD[addr: Addr, cnt: INT]; NodeContext: TYPE = REF NodeContextRec; NodeContextRec: TYPE = RECORD[ root: Core.CellType, table: HashTable.Table]; Signal: SIGNAL = CODE; log: IO.STREAM _ CoreFrame.GetLog[]; Connect: PUBLIC PROC [frameCT: Core.CellType] RETURNS[success: BOOL _ TRUE] = { ctx: NodeContext _ NEW[ NodeContextRec _ [ root: frameCT, table: HashTable.Create[equal: HashTable.RopeEqual, hash: HashTable.HashRope ] ] ]; ConnectNodes[ctx]; CheckPublic[ctx]; success _ CheckForSingles[ctx]; LogFrame[frameCT, frameLogger]; }; ConnectNodes: PROC [ ctx: NodeContext, frameCT: Core.CellType _ NIL, path: Path _ NIL ] = { frame: CoreFrame.Frame _ FCT[IF frameCT=NIL THEN ctx.root ELSE frameCT]; hereRef: Addr _ PathToAddr[path]; eachWire: CoreOps.EachWireProc = { name: ROPE _ CoreName.WireNm[wire].n; IF wire=NIL THEN Signal[]; IF wire.size#0 THEN RETURN; IF name.Length[]=0 THEN RETURN; -- Sinix includes ALL interest Rect items in public eachWireRp[name]}; eachWireRp: PROC[name: ROPE] = { probe: Core.CellType; start: Core.CellType _ ctx.root; oldRef: REF CtxRec _ NARROW[HashTable.Fetch[ctx.table, name].value]; old: Addr _ NIL; here: Addr _ hereRef; new: Path _ NIL; IF oldRef=NIL THEN { frame.intOnly _ AddItem[name, frame.intOnly]; []_HashTable.Store[ctx.table, name, NEW[CtxRec _ [here, 1]]]; RETURN }; old _ oldRef.addr; DO IF here=NIL OR old=NIL THEN EXIT; IF here.first # old.first THEN EXIT; new _ CONS[here.first, new]; start _ FCT[start].seq[here.first]; here _ here.rest; old _ old.rest; ENDLOOP; oldRef.addr _ PathToAddr[new]; oldRef.cnt _ oldRef.cnt+1; FCT[start].intOnly _ AddItem[name, FCT[start].intOnly]; probe _ start; IF old#NIL THEN { FOR old _ old, old.rest WHILE old#NIL DO probe _ FCT[probe].seq[old.first]; FCT[probe].public _ AddItem[name, FCT[probe].public]; ENDLOOP; FCT[probe].intOnly _ RemoveItem[name, FCT[probe].intOnly] }; probe _ start; FOR here _ here, here.rest WHILE here#NIL DO probe _ FCT[probe].seq[here.first]; FCT[probe].public _ AddItem[name, FCT[probe].public]; ENDLOOP }; IF frame.cell#NIL THEN [ ] _ CoreOps.VisitWire[frame.cell.public, eachWire] ELSE IF frame.seq.size#0 THEN FOR i: INT IN [0..frame.seq.size) DO ConnectNodes[ctx, frame.seq[i], CONS[i, path]] ENDLOOP ELSE IF frame.data=NIL OR NOT ISTYPE[frame.data, CoreGlue.Glue] THEN Signal[] ELSE FOR pubs: LIST OF ROPE _ frame.public, pubs.rest WHILE pubs#NIL DO [ ] _ eachWireRp[pubs.first] ENDLOOP}; CheckPublic: PROC [ctx: NodeContext] = { FOR public: LIST OF ROPE _ FCT[ctx.root].public, public.rest WHILE public#NIL DO oldRef: REF CtxRec _ NARROW[HashTable.Fetch[ctx.table, public.first].value]; probe: Core.CellType; old: Addr _ oldRef.addr; probe _ ctx.root; IF oldRef=NIL THEN log.PutF["\n WARNING, %g's public: %g not exported by children", IO.rope[CoreName.CellNm[ctx.root].n], IO.rope[public.first] ] ELSE { FOR old: Addr _ oldRef.addr, old.rest WHILE old#NIL DO probe _ FCT[probe].seq[old.first]; FCT[probe].public _ AddItem[public.first, FCT[probe].public]; ENDLOOP; oldRef.cnt _ oldRef.cnt+1; oldRef.addr _ NIL}; FCT[probe].intOnly _ RemoveItem[public.first, FCT[probe].intOnly]; ENDLOOP}; CheckForSingles: PROC [ctx: NodeContext] RETURNS[ok: BOOL _ TRUE] = { singleChk: HashTable.EachPairAction = { oldRef: REF CtxRec _ NARROW[value]; IF oldRef.cnt < 2 THEN { name: ROPE _ NARROW[key]; ok _ FALSE; log.PutF["\n WARNING, %g is not connected", IO.rope[name]]} }; [ ] _ HashTable.Pairs[ctx.table, singleChk]}; LogFrame: PROC[frameCT: Core.CellType, logger: FrameLogger] = { LogIt: PROC[fCT: Core.CellType, pathName: ROPE _ NIL, depth: INT _ 0] = { frame: CoreFrame.Frame _ FCT[fCT]; CoreOps.PrintIndent[depth, log]; log.PutF["Frame: %g", IO.rope[pathName]]; logger[fCT, depth]; FOR field: INT IN [0..frame.seq.size) DO name _ CoreName.CellNm[frame.seq[field]].n; IF name=NIL THEN name _ IO.PutFR["%g", IO.int[field]]; LogIt[frame.seq[field], Rope.Cat[pathName, ".", name], depth+1]; ENDLOOP}; name: ROPE _ CoreName.CellNm[frameCT].n; IF name=NIL THEN name _ "top"; LogIt[frameCT, name]}; FrameLogger: TYPE = PROC[fCT: Core.CellType, depth: INT]; wireLogger: FrameLogger = { frame: CoreFrame.Frame _ FCT[fCT]; IF frame.seq.size=0 THEN CoreOps.PrintWire[frame.cell.public, log, depth]}; frameLogger: FrameLogger = { frame: CoreFrame.Frame _ FCT[fCT]; CoreOps.PrintIndent[depth, log]; log.PutRope[" Public:"]; FOR list: LIST OF ROPE _ frame.public, list.rest WHILE list#NIL DO log.PutRope[" "]; log.PutRope[list.first]; ENDLOOP; CoreOps.PrintIndent[depth, log]; log.PutRope[" IntOnly:"]; FOR list: LIST OF ROPE _ frame.intOnly, list.rest WHILE list#NIL DO log.PutRope[" "]; log.PutRope[list.first]; ENDLOOP; }; FCT: PROC[frameCT: Core.CellType] RETURNS[frame: CoreFrame.Frame] = INLINE {RETURN[CoreFrame.FCT[frameCT]]}; PathToAddr: PROC [path: Path] RETURNS[addr: Addr _ NIL] = {FOR path _ path, path.rest WHILE path#NIL DO addr _ CONS[path.first, addr] ENDLOOP}; LogAddr: PROC [addr: Addr] = {FOR addr _ addr, addr.rest WHILE addr#NIL DO log.PutF[" %g", IO.int[addr.first]] ENDLOOP}; RemoveItem: PROC[item: ROPE, list: LIST OF ROPE] RETURNS[new: LIST OF ROPE _ NIL] = { FOR list _ list, list.rest WHILE list#NIL DO IF NOT Rope.Equal[item, list.first] THEN new _ CONS[list.first, new] ENDLOOP}; AddItem: PROC[item: ROPE, list: LIST OF ROPE] RETURNS[new: LIST OF ROPE _ NIL] = { FOR lst: LIST OF ROPE _ list, lst.rest WHILE lst#NIL DO IF Rope.Equal[item, lst.first] THEN RETURN[list] ENDLOOP; RETURN[CONS[item, list]]}; END. PCoreConnectImpl.mesa Copyright c 1986 by Xerox Corporation. All rights resersed. Last Edited by: Curry, March 8, 1986 4:49:53 pm PST success _ CheckConnects[frameCT]; LogFrame[frameCT, wireLogger]; This picks up on unnamed publics generated by Sinix CheckConnects: PROC [frameCT: Core.CellType] RETURNS[ok: BOOL _ TRUE] = { frame: CoreFrame.Frame _ FCT[frameCT]; IF frame.seq.size=0 THEN { -- expect no intOnlys and publics match count: INT _ 0; compare: INT _ 0; data: CoreClasses.RecordCellType _ NARROW[frame.cell.data]; FOR lst: LIST OF ROPE _ frame.intOnly, lst.rest WHILE lst#NIL DO ok _ FALSE; count _ count+1; log.PutF["\n WARNING, %g is NOT connected", IO.rope[lst.first]]; ENDLOOP; FOR lst: LIST OF ROPE _ frame.public, lst.rest WHILE lst#NIL DO count _ count+1 ENDLOOP; compare _ IF frame.cell.public.size=0 THEN 0 ELSE CoreOps.WireBits[frame.cell.public]; IF compare#count THEN {ok _ FALSE; Signal[]} } ELSE FOR i: INT DECREASING IN [0..frame.seq.size) DO ok _ CheckConnects[frame.seq[i]] AND ok ENDLOOP }; IF frame.seq.size=0 THEN CoreOps.PrintWire[frame.cell.public, log, depth]; Ê ±˜šœ™Jšœ<™——Jšœ-˜-—J˜šŸœœ1˜?š Ÿœœœœ œ ˜IJšœœ˜"Jšœ ˜ Jšœœ˜)Jšœ˜šœœœ˜(Jšœ+˜+Jš œœœœ œ ˜6JšœAœ˜J——Jšœœ˜(Jšœœœ˜Jšœ˜—JšŸ œœœœ˜9š  œ˜Jšœœ˜"Jšœœ3˜K—š  œ˜Jšœœ˜"Jšœ ˜ Jšœ˜š œœœœœœ˜BJšœ+œ˜3—Jšœ ˜ Jšœ˜š œœœœœœ˜CJšœ+œ˜3—Jšœœ2™JJšœ˜—J™šÐbkœœœ˜JJšœœ˜!—J˜šŸ œœœœ˜9Jš œœœœœœœ˜U—J˜šŸœœ˜Jš œœœœœœœ˜[—J˜š Ÿ œœœœœœ˜0Jš œœœœœ˜$šœœœ˜,Jš œœœœœ˜N——J˜šŸœœœœœœœœœœœ˜Rš œœœœœœ˜7Jšœœœœ˜9—Jšœœ˜—J˜Jšœ˜—…—Ð$Ñ