<> <> <> <> <> <> <<>> DIRECTORY Core, CoreClasses, CoreOps, CoreProperties, HashTable, IO, Rope; CoreClassesImpl: CEDAR PROGRAM IMPORTS CoreOps, CoreProperties, HashTable, IO EXPORTS CoreClasses = BEGIN OPEN Core, CoreClasses; <> recordCellClass: PUBLIC CellClass _ CoreOps.SetClassPrintProc[NEW [CellClassRec _ [name: "Record", recast: NIL]], PropPrint]; PropPrint: CoreOps.PrintClassProc = { RecordPrint[NARROW [data], out, indent, level]; }; RecordPrint: PROC [recordCellType: RecordCellType, out: STREAM, indent: NAT _ 0, level: NAT _ 2] = { CoreOps.PrintIndent[indent, out]; IO.PutRope[out, "Internal wire:"]; CoreOps.PrintWire[recordCellType.internal, out, indent, level]; CoreOps.PrintIndent[indent, out]; IO.PutF[out, "%g instances", IO.int[recordCellType.size]]; FOR i: NAT IN [0 .. recordCellType.size) DO firstActual: BOOL _ TRUE; instanceName: ROPE _ GetCellInstanceName[recordCellType.instances[i]]; EachWirePair: CoreOps.EachWirePairProc = { internalNames: LIST OF ROPE _ CoreOps.GetFullWireNames[recordCellType.internal, actualWire]; publicNames: LIST OF ROPE _ CoreOps.GetFullWireNames[recordCellType.instances[i].type.public, publicWire]; subWires _ internalNames=NIL OR publicNames=NIL; IF NOT subWires THEN { IF NOT firstActual THEN out.PutChar[',]; firstActual _ FALSE; out.PutF[" %g: %g", IO.rope[publicNames.first], IO.rope[internalNames.first]]; }; }; IF instanceName = NIL THEN instanceName _ ""; CoreOps.PrintIndent[indent, out]; IO.PutF[out, "CellInstance %g: %g", [rope[instanceName]], [rope[CoreOps.GetCellTypeName[recordCellType.instances[i].type]]] ]; CoreOps.PrintIndent[indent, out]; IO.PutRope[out, " Actual wire: "]; IF CoreOps.VisitBinding[recordCellType.instances[i].actual, recordCellType.instances[i].type.public, EachWirePair] THEN out.PutF["\n*** Actual and Public do not conform\n"]; CoreProperties.PrintProperties[props: recordCellType.instances[i].properties, out: out, indent: 1, level: level]; ENDLOOP; }; CreateRecordCell: PUBLIC PROC [public: Wire, internal: Wire, instances: LIST OF CellInstance, name: ROPE _ NIL, props: Properties _ NIL] RETURNS [recordCell: CellType] = { internals: HashTable.Table _ HashTable.Create[internal.size]; AddInInternals: CoreOps.EachWireProc = {[] _ HashTable.Store[internals, wire, wire]}; data: RecordCellType; size: NAT _ 0; FOR list: LIST OF CellInstance _ instances, list.rest WHILE list#NIL DO size _ size+1; ENDLOOP; data _ NEW [RecordCellTypeRec[size]]; size _ 0; FOR i: NAT IN [0 .. internal.size) DO [] _ CoreOps.VisitWire[internal[i], AddInInternals]; ENDLOOP; FOR i: NAT IN [0 .. public.size) DO IF ~HashTable.Fetch[internals, public[i]].found THEN ERROR; -- public public[i] is not part of internal ENDLOOP; FOR list: LIST OF CellInstance _ instances, list.rest WHILE list#NIL DO data[size] _ list.first; size _ size+1; IF NOT CoreOps.Conform[list.first.actual, list.first.type.public] THEN ERROR; FOR i: NAT IN [0 .. list.first.actual.size) DO IF ~HashTable.Fetch[internals, list.first.actual[i]].found THEN ERROR; -- actual list.first.actual[i] is not part of internal ENDLOOP; ENDLOOP; data.internal _ internal; CoreOps.FlushNameCaches[internal]; recordCell _ CoreOps.CreateCellType[recordCellClass, public, data, name, props]; }; CreateInstance: PUBLIC PROC [actual: Wire, type: CellType, name: ROPE _ NIL, props: Properties _ NIL] RETURNS [instance: CellInstance] = { instance _ NEW[CellInstanceRec _ [ actual: actual, type: type, properties: props]]; IF name#NIL THEN instance _ SetCellInstanceName[instance, name]; }; GetCellInstanceName: PUBLIC PROC [instance: CellInstance] RETURNS [name: ROPE] = { name _ NARROW [CoreProperties.GetCellInstanceProp[instance, CoreOps.nameProp]]; }; SetCellInstanceName: PUBLIC PROC [instance: CellInstance, name: ROPE] RETURNS [sameInstance: CellInstance] = { CoreProperties.PutCellInstanceProp[on: instance, prop: CoreOps.nameProp, value: name]; sameInstance _ instance; }; CorrespondingActual: PUBLIC PROC [instance: CellInstance, public: Wire] RETURNS [actual: Wire _ NIL] = { EachWirePair: CoreOps.EachWirePairProc = { IF publicWire=public THEN {actual _ actualWire; quit _ TRUE}; }; [] _ CoreOps.VisitBinding[instance.actual, instance.type.public, EachWirePair]; }; ReverseCellInstances: PUBLIC PROC [instances: CellInstances] RETURNS [rev: CellInstances _ NIL] = { WHILE instances#NIL DO rev _ CONS [instances.first, rev]; instances _ instances.rest; ENDLOOP; }; <> transistorCellClass: PUBLIC CellClass _ NEW [CellClassRec _ [name: "Transistor", recast: NIL]]; transistorTypeNames: PUBLIC ARRAY TransistorType OF ROPE _ ["nE", "pE", "nD"]; transistorPortNames: PUBLIC ARRAY TransistorPort OF ROPE _ ["gate", "ch1", "ch2"]; CreateTransistor: PUBLIC PROC [args: TransistorRec, name: ROPE _ NIL, props: Properties _ NIL] RETURNS [cellType: CellType] = { tranNames: ARRAY TransistorType OF ROPE _ ["nE", "pE", "nD"]; tranPublic: Wire _ CoreOps.CreateWire[LIST[ CoreOps.CreateWire[name: "gate"], CoreOps.CreateWire[name: "ch1"], CoreOps.CreateWire[name: "ch2"] ]]; cellType _ CoreOps.CreateCellType[ class: transistorCellClass, public: tranPublic, data: NEW [TransistorRec _ args], name: name, props: props]; }; <> identityCellClass: PUBLIC CellClass _ CoreOps.SetClassPrintProc[NEW[CellClassRec _ [name: "Identity", recast: IdentityRecast]], IdentityPrint]; CreateIdentity: PUBLIC PROC [cellType: CellType, name: ROPE _ NIL, props: Properties _ NIL] RETURNS [identity: CellType] = { identity _ CoreOps.CreateCellType[ class: identityCellClass, public: CoreOps.CopyWire[cellType.public], data: cellType, name: name, props: props]; }; IdentityRecast: RecastProc = {new _ NARROW [me.data]}; IdentityPrint: CoreOps.PrintClassProc = { ct: CellType _ NARROW [data]; CoreOps.PrintIndent[indent, out]; out.PutF["Identity of %g", IO.rope[CoreOps.GetCellTypeName[ct]]]; }; <> unspecifiedCellClass: PUBLIC CellClass _ NEW [CellClassRec _ [name: "Unspecified"]]; CreateUnspecified: PUBLIC PROC [public: Wire _ NIL, name: ROPE _ NIL, props: Properties _ NIL] RETURNS [cellType: CellType] = { cellType _ CoreOps.CreateCellType[ class: unspecifiedCellClass, public: public, data: NIL, name: name, props: props]; }; END.