CoreClassesImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Barth, May 6, 1986 5:05:18 pm PDT
Spreitzer, January 10, 1986 4:08:14 pm PST
Bertrand Serlet May 29, 1986 7:35:21 pm PDT
Pradeep Sindhu April 30, 1986 9:35:06 pm PDT
CoreClassesImpl:
CEDAR
PROGRAM
IMPORTS CoreOps, CoreProperties, HashTable, IO
EXPORTS CoreClasses =
BEGIN OPEN Core, CoreClasses;
Record
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 ← "<no name>";
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;
};
Transistor
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];
};
Identity
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]]];
};