DIRECTORY Core, CoreClasses, CoreCreate, CoreOps, CoreProperties, RefTab, Rope; CoreCreateImpl: CEDAR PROGRAM IMPORTS CoreClasses, CoreOps, CoreProperties, RefTab, Rope EXPORTS CoreCreate = BEGIN OPEN CoreCreate; WireList: PUBLIC PROC [wrs: LIST OF WR _ NIL, name: ROPE _ NIL, props: Properties _ NIL] RETURNS [newWire: Wire] = { count: NAT _ 0; FOR wrl: LIST OF WR _ wrs, wrl.rest UNTIL wrl=NIL DO IF wrl.first#NIL THEN count _ count + 1; ENDLOOP; newWire _ CoreOps.CreateWires[count, name, props]; count _ 0; FOR wrl: LIST OF WR _ wrs, wrl.rest UNTIL wrl=NIL DO IF wrl.first#NIL THEN { new: Wire _ WITH wrl.first SELECT FROM wire: Wire => wire, rope: ROPE => CoreOps.CreateWire[name: rope], text: REF TEXT => CoreOps.CreateWire[name: Rope.FromRefText[text]], ENDCASE => ERROR; newWire[count] _ new; count _ count + 1; }; ENDLOOP; }; Wires: PUBLIC PROC [wr1, wr2, wr3, wr4, wr5, wr6, wr7, wr8, wr9, wr10, wr11, wr12, wr13: WR _ NIL, props: Properties _ NIL, name: ROPE _ NIL] RETURNS [Wire] = { RETURN [WireList[LIST [wr1, wr2, wr3, wr4, wr5, wr6, wr7, wr8, wr9, wr10, wr11, wr12, wr13], name, props]]; }; Seq: PUBLIC PROC [name: ROPE _ NIL, size: NAT, protoChild: Wire _ NIL] RETURNS [wire: Wire] = { wire _ CoreOps.SetShortWireName[CoreOps.CreateWires[size], name]; IF protoChild=NIL THEN FOR i: NAT IN [0..size) DO wire[i] _ CoreOps.CreateWire[]; ENDLOOP ELSE FOR i: NAT IN [0..size) DO wire[i] _ CoreOps.CopyWire[protoChild]; ENDLOOP; }; Index: PUBLIC PROC [wr: WR, index: NAT] RETURNS [WR] = { WITH wr SELECT FROM wire: Wire => RETURN [wire[index]]; rope: ROPE => RETURN [CoreOps.Index[rope, index]]; text: REF TEXT => RETURN [CoreOps.Index[Rope.FromRefText[text], index]]; ENDCASE => ERROR }; Range: PUBLIC PROC [wire: Wire, start, size: NAT, name: ROPE _ NIL, props: Properties _ NIL] RETURNS [Wire] = { RETURN [CoreOps.SubrangeWire[wire, start, size, name, props]]; }; Union: PUBLIC PROC [wr1, wr2, wr3, wr4, wr5, wr6, wr7, wr8, wr9, wr10, wr11, wr12, wr13: Wire _ NIL, name: ROPE _ NIL, props: Properties _ NIL] RETURNS [wire: Wire] = { wires: LIST OF Wire _ LIST [wr1, wr2, wr3, wr4, wr5, wr6, wr7, wr8, wr9, wr10, wr11, wr12, wr13]; count: NAT _ 0; FOR wl: LIST OF Wire _ wires, wl.rest UNTIL wl=NIL DO IF wl.first#NIL THEN count _ count + (IF wl.first.size=0 THEN 1 ELSE wl.first.size); ENDLOOP; wire _ CoreOps.CreateWires[count, name, props]; count _ 0; FOR wl: LIST OF Wire _ wires, wl.rest UNTIL wl=NIL DO IF wl.first#NIL THEN { IF wl.first.size=0 THEN { wire[count] _ wl.first; count _ count+1; } ELSE { FOR w: NAT IN [0..wl.first.size) DO wire[count+w] _ wl.first[w]; ENDLOOP; count _ count + wl.first.size; }; }; ENDLOOP; }; Instance: PUBLIC PROC [type: CellType, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9, pa10, pa11, pa12, pa13: PA _ [], name: ROPE _ NIL, props: Properties _ NIL] RETURNS [CellInstance] = { revpas: LIST OF PA _ NIL; FOR pas: LIST OF PA _ LIST [pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9, pa10, pa11, pa12, pa13], pas.rest UNTIL pas=NIL DO IF pas.first#[] THEN revpas _ CONS [pas.first, revpas]; ENDLOOP; RETURN [InstanceList[type: type, pas: revpas, name: name, props: props]]; }; instanceBindProp: ATOM _ CoreProperties.RegisterProperty[$CoreInstanceBind, CoreProperties.Props[[CoreProperties.propPrint, CoreProperties.PropDontPrint]]]; InstanceList: PUBLIC PROC [type: CellType, pas: LIST OF PA _ NIL, name: ROPE _ NIL, props: Properties _ NIL] RETURNS [instance: CellInstance] = { pasTable: RefTab.Ref _ RefTab.Create[]; instance _ CoreClasses.CreateInstance[actual: NIL, type: type, name: name, props: props]; FOR checkPas: LIST OF PA _ pas, checkPas.rest WHILE checkPas#NIL DO pa: PA = checkPas.first; pub: WR _ WITH pa.public SELECT FROM wire: Wire => wire, rope: ROPE => rope, text: REF TEXT => Rope.FromRefText[text], ENDCASE => ERROR; actual: WR _ WITH pa.actual SELECT FROM wire: Wire => wire, rope: ROPE => rope, text: REF TEXT => Rope.FromRefText[text], ENDCASE => ERROR; public: Wire _ FindWire[type.public, checkPas.first.public]; IF public=NIL THEN MakeError[ Rope.Cat[ "Could not find public '", IF ISTYPE [pub, ROPE] THEN NARROW [pub] ELSE CoreOps.GetShortWireName[NARROW[pub]], "'" ], CoreOps.GetCellTypeName[type]]; IF NOT RefTab.Store[pasTable, public, actual] THEN MakeError[ Rope.Cat[ "Binding list binds twice public '", IF ISTYPE [pub, ROPE] THEN NARROW [pub] ELSE CoreOps.GetShortWireName[NARROW[pub]], "'" ], CoreOps.GetCellTypeName[type]]; ENDLOOP; CoreProperties.PutCellInstanceProp[on: instance, prop: instanceBindProp, value: pasTable]; }; CreateError: ERROR [msg: ROPE] = CODE; MakeError: PROC [msg: ROPE, cellName: ROPE] = { ERROR CreateError[Rope.Cat[msg, " in cell type '", cellName, "'"]]; }; CheckWellFormed: PROC [root: ROPE, wire: Wire, cellName: ROPE] = { IF wire=NIL THEN MakeError[root, cellName]; FOR sub: NAT IN [0..wire.size) DO CheckWellFormed[root, wire[sub], cellName] ENDLOOP; }; Cell: PUBLIC PROC [public: WireSeq, onlyInternal, internal: WireSeq _ NIL, instances: CellInstances, name: ROPE _ NIL, props: Properties _ NIL] RETURNS [cellType: CellType] = { SELECT TRUE FROM internal=NIL AND onlyInternal=NIL => internal _ public; internal=NIL => internal _ CoreOps.UnionWire[public, onlyInternal]; onlyInternal=NIL => {}; ENDCASE => MakeError["Both internal and onlyInternal are specified", name]; CheckWellFormed["Public is malformed", public, name]; CheckWellFormed["Internal is malformed", internal, name]; FOR instList: CellInstances _ instances, instList.rest UNTIL instList=NIL DO CreateActual: PROC [public: Wire] RETURNS [actual: Wire] = { FindByName: PROC [wire: Wire] RETURNS [actual: Wire] = { actualName: ROPE _ CoreOps.GetShortWireName[wire]; actual _ FindWire[internal, wire]; IF actual#NIL THEN RETURN; IF actualName#NIL THEN actual _ FindWire[internal, actualName]; IF actual#NIL THEN RETURN; IF wire.size=0 THEN ActualError[]; actual _ wire; FOR i: NAT IN [0 .. wire.size) DO actual[i] _ FindByName[actual[i]]; ENDLOOP; }; ActualError: PROC = { MakeError[Rope.Cat["Public '", CoreOps.GetFullWireName[instance.type.public, public], "' of sub cell type '", CoreOps.GetCellTypeName[instance.type], "' has bad actual"], name]; }; act: WR; actual _ NARROW [RefTab.Fetch[visitTab, public].val]; IF actual#NIL THEN RETURN; -- already done this part of the DAG act _ RefTab.Fetch[pasTable, public].val; IF act#NIL THEN { actual _ FindWire[internal, act]; IF actual=NIL THEN WITH act SELECT FROM wire: Wire => actual _ FindByName[wire]; rope: ROPE => MakeError[Rope.Cat["Actual with name '", rope, "' not found in internal"], name]; ENDCASE => ERROR; } ELSE { FOR pNames: LIST OF ROPE _ CoreOps.GetFullWireNames[instance.type.public, public], pNames.rest UNTIL pNames=NIL DO actual _ FindWire[internal, pNames.first]; IF actual#NIL THEN EXIT; REPEAT FINISHED => { IF public.size=0 THEN ActualError[]; actual _ CoreOps.CreateWires[public.size]; FOR i: NAT IN [0 .. public.size) DO actual[i] _ CreateActual[public[i]]; ENDLOOP; }; ENDLOOP; }; IF NOT RefTab.Insert[visitTab, public, actual] THEN ERROR; }; instance: CellInstance _ instList.first; visitTab: RefTab.Ref _ RefTab.Create[]; -- Wire to Wire pasTable: RefTab.Ref _ NARROW[CoreProperties.GetCellInstanceProp[from: instance, prop: instanceBindProp]]; instance.actual _ CreateActual[instance.type.public]; FOR i: NAT IN [0..instance.actual.size) DO IF NOT CoreOps.RecursiveMember[candidate: instance.actual[i], wire: internal] THEN internal _ CoreOps.UnionWire[internal, CoreOps.CreateWire[LIST[instance.actual[i]]]]; ENDLOOP; CoreProperties.PutCellInstanceProp[on: instance, prop: instanceBindProp, value: NIL]; ENDLOOP; cellType _ CoreClasses.CreateRecordCell[public: public, internal: internal, instances: instances, name: name, props: props]; }; Transistor: PUBLIC PROC [type: TransistorType _ nE, length: NAT _ 2, width: NAT _ 4, name: ROPE _ NIL, props: Properties _ NIL] RETURNS [cellType: CellType] = { cellType _ CoreClasses.CreateTransistor[ args: [type: type, length: length, width: width], name: name, props: props ]; }; SequenceCell: PUBLIC PROC [baseCell: CellType, count: NAT, sequencePorts: WireSeq _ NIL, flatSequencePorts: WireSeq _ NIL, stitchPorts: LIST OF PA _ NIL, name: ROPE _ NIL, props: Properties _ NIL] RETURNS [cellType: CellType] = { FindTopWire: PROC [wr: WR] RETURNS [index: NAT] = { FOR index IN [0..baseCell.public.size) DO WITH wr SELECT FROM wrwire: Wire => IF wrwire=baseCell.public[index] THEN RETURN; wrrope: ROPE => IF Rope.Equal[wrrope, CoreOps.GetShortWireName[baseCell.public[index]]] THEN RETURN; text: REF TEXT => IF Rope.Equal[Rope.FromRefText[text], CoreOps.GetShortWireName[baseCell.public[index]]] THEN RETURN; ENDCASE => ERROR; REPEAT FINISHED => ERROR; -- no such wire ENDLOOP; }; FindPorts: PROC [ports: WireSeq] RETURNS [set: CoreClasses.SequenceSet] = { IF ports#NIL THEN { set _ NEW[CoreClasses.SequenceSetRec[ports.size]]; FOR i: INT IN [0..ports.size) DO sequenceName: ROPE _ CoreOps.GetShortWireName[ports[i]]; FOR w: NAT IN [0..baseCell.public.size) DO IF ports[i]=baseCell.public[w] OR (sequenceName#NIL AND Rope.Equal[sequenceName, CoreOps.GetShortWireName[ baseCell.public[w]]]) THEN { set[i] _ w; EXIT; }; REPEAT FINISHED => ERROR; ENDLOOP; ENDLOOP; }; }; stitches: CoreClasses.StitchSet _ NIL; seqCell: CoreClasses.SequenceCellType _ NIL; IF stitchPorts#NIL THEN { stitchCount: NAT _ 0; FOR sps: LIST OF PA _ stitchPorts, sps.rest UNTIL sps=NIL DO stitchCount _ stitchCount + 1; ENDLOOP; stitches _ NEW[CoreClasses.StitchSetRec[stitchCount]]; stitchCount _ 0; FOR sps: LIST OF PA _ stitchPorts, sps.rest UNTIL sps=NIL DO stitches[stitchCount].this _ FindTopWire[sps.first.public]; stitches[stitchCount].that _ FindTopWire[sps.first.actual]; stitchCount _ stitchCount + 1; ENDLOOP; }; seqCell _ NEW [CoreClasses.SequenceCellTypeRec _ [ base: baseCell, count: count, sequence: FindPorts[sequencePorts], flatSequence: FindPorts[flatSequencePorts], stitch: stitches]]; cellType _ CoreClasses.CreateSequence[args: seqCell, name: name, props: props]; }; FindWire: PUBLIC PROC [root: WireSeq, wr: WR] RETURNS [found: Wire _ NIL] = { WITH wr SELECT FROM wrwire: Wire => IF CoreOps.RecursiveMember[candidate: wrwire, wire: root] THEN found _ wrwire; wrrope: ROPE => found _ CoreOps.FindWire[root, wrrope]; text: REF TEXT => found _ CoreOps.FindWire[root, Rope.FromRefText[text]]; ENDCASE => ERROR; }; END. pCoreCreateImpl.mesa Copyright Σ 1985, 1986, 1987 by Xerox Corporation. All rights reserved. Bertrand Serlet, March 31, 1987 0:09:48 am PST Barth, February 17, 1987 6:02:57 pm PST Louis Monier May 1, 1986 4:50:13 pm PDT Mike Spreitzer February 27, 1987 2:47:20 pm PST Wires Cells This property temporarily stores a table of bindings of the form: public [Wire] -> actual [WR] We check pas is of the right type, to detect errors as soon as possible searches in internal for a wire of the same name as the one passed in argument some binding was explicitly required no explicitly required binding for this public Κ ͺ˜codešœ™KšœH™HKšœ.™.K™'K™'K™/—K™šΟk ˜ KšœE˜E—K˜šΟnœœ˜Kšœ3˜:Kšœ˜Kšœœ ˜—head™šžœœœœœœœœœœœ˜tKšœœ˜š œœœœœœ˜4Kšœ œœ˜(Kšœ˜—Kšœ2˜2Kšœ ˜ š œœœœœœ˜4šœ œœ˜šœ œ œ˜&Kšœ˜Kšœœ$˜.Kšœœœ6˜DKšœœ˜—Kšœ˜Kšœ˜K˜—Kšœ˜—K˜K™—šžœœœGœœœœœœ ˜ Kšœ œV˜kK˜K™—šžœœœœœœœœ˜_KšœA˜Aš œ œœœœœ ˜1Kšœ˜Kš˜—š œœœœ ˜Kšœ'˜'Kšœ˜—K˜K™—šžœœœœ œœœ˜8šœœ˜Kšœœ˜%Kšœœœ˜4Kšœœœœ0˜IKšœ˜—K˜K˜—šžœ œœœœœœ ˜oKšœ8˜>K˜K˜—šžœœœNœœœœœ˜¨KšœœœœG˜aKšœœ˜š œœœœœ˜5Kš œ œœœœœ˜TKšœ˜—Kšœ/˜/Kšœ ˜ š œœœœœ˜5šœ œœ˜šœœ˜K˜K˜K˜—šœ˜šœœœ˜#Kšœ˜Kšœ˜—Kšœ˜K˜—K˜—Kšœ˜—K˜K™——™šžœœœWœ œœœœ˜ΊKš œœœœœ˜šœœœœœQœœ˜{Kšœœ œ˜7Kšœ˜—KšœB˜IK˜K™—šœœ†˜œKšœ^™^K˜—šž œœœœœœœœœœœ˜‘K˜'Kšœ.œ(˜YK™Gš œ œœœœ œ˜CKšœœ˜šœœœ œ˜$K˜Kšœœ ˜Kšœœœ˜)Kšœœ˜—šœœœ œ˜'K˜Kšœœ ˜Kšœœœ˜)Kšœœ˜—Kšœ<˜<šœœœ ˜šœ ˜ Kšœ˜Kšœœœœœœœ ˜WKšœ˜—Kšœ˜—šœœ(œ ˜=šœ ˜ Kšœ%˜%Kšœœœœœœœ ˜WKšœ˜—Kšœ˜—Kšœ˜—KšœZ˜ZKšœ˜K˜—šœ œœœ˜&K˜—šž œœœ œ˜/Kšœ>˜CK˜K˜—šžœœœœ˜BKšœœœ˜+Kš œœœœ+œ˜UK˜K˜—šžœœœ5œ"œœœœ˜°K˜šœœ˜Kšœ œœœ˜8Kšœ œ7˜CKšœ œ˜KšœE˜L—Kšœ5˜5Kšœ9˜9šœ4œ œ˜LK˜šž œœœ˜