[Indigo]<Rosemary>2.6>Rosemary.DF=>RoseTypes.Mesa
Last Edited by: Spreitzer, January 25, 1985 10:50:11 am PST
Last Edited by: Gasbarro, July 17, 1984 4:06:47 pm PDT
DIRECTORY Asserting, IO, OrderedSymbolTableRef, Rope, RoseEvents, VFonts;
RoseTypes: CEDAR DEFINITIONS =
BEGIN
Error: ERROR [msg: ROPE, data: REF ANYNIL];
Warning: SIGNAL [msg: ROPE, data: REF ANYNIL];
Stop: SIGNAL [msg: ROPE, data: REF ANYNIL];
LORA: TYPE = LIST OF REF ANY;
ROPE: TYPE = Rope.ROPE;
RopeList: TYPE = LIST OF ROPE;
STREAM: TYPE = IO.STREAM;
Assertion: TYPE = Asserting.Assertion;
Assertions: TYPE = Asserting.Assertions;
SymbolTable: TYPE = OrderedSymbolTableRef.Table;
WatcherList: TYPE = LIST OF Watcher;
Watcher: TYPE = RoseEvents.Watcher;
WordPtr: TYPE = LONG POINTER TO CARDINAL;
TwoToThe: ARRAY [0..16] OF LONG CARDINAL = [
1, 2, 4, 8,
16, 32, 64, 128,
256, 512, 1024, 2048,
4096, 8192, 16384, 32768,
65536];
NodeType: TYPE = REF NodeTypeRep;
NodeTypeRep: TYPE = RECORD [
procs: NodeProcs,
typeData: REF ANY,
simple: BOOLEANTRUE,
other: Assertions ← NIL,
structure: SELECT structureType: StructureType FROM
atom => [],
array => [first, last: INTEGER, element: NodeType],
ENDCASE
];
StructureType: TYPE = {atom, array};
ArrayNodeType: TYPE = REF NodeTypeRep[array];
AtomNodeType: TYPE = REF NodeTypeRep[atom];
NodeProcs: TYPE = REF NodeProcsRep;
NodeProcsRep: TYPE = RECORD [
Bits: PROC [NodeType] RETURNS [INTEGER],
--how many bits does it take to represent--
MesaUse: PROC [NodeType] RETURNS [Mesa],
--the Mesa type of the representation--
MesaDefinition: PROC [NodeType] RETURNS [Mesa] ← NIL,
--Mesa code (e.g. declaration) to establish mesa type;--
--returning NIL means nothing necessary--
UserDescription: PROC [NodeType] RETURNS [ROPE],
MesaDescription: PROC [NodeType] RETURNS [Mesa],
--a Mesa expression that evaluates to this NodeType--
ListFormats: PROC [NodeType] RETURNS [RopeList],
GetFormat: PROC [NodeType, ROPE] RETURNS [Format],
MakeSubarrayType: PROC [nt: NodeType, first, last: INTEGER] RETURNS [NodeType] ← NIL,
MakeSplitJoin: PROC [within: Cell, a, b: StretchList, writeA, writeB: BOOLEAN, for: ExpansionReceiver] RETURNS [Cell] ← NIL,
MakeTransducer: PROC [myKind, otherKind: Node, within: Cell, writeMine, writeOther: BOOLEAN, for: ExpansionReceiver] RETURNS [Cell] ← NIL,
InitNode: PROC [node: Node, initData: REF ANY, steady: BOOL] ← NIL,
If steady, initialize for steady-state work; otherwise, for initialization work.
InitPort: PROC [Node, WordPtr] ← NIL,
InitQ, InitUD, NewVal: PROC [Node] ← NIL,
ComputeQ: PROC [Node, WordPtr] ← NIL,
CompareUD: PROC [nt: NodeType, wp1, wp2: WordPtr] RETURNS [diff: BOOL] ← NIL,
CopyUD, CopyVal: PROC [nt: NodeType, from, to: WordPtr] ← NIL,
ClearUD: PROC [nt: NodeType, at: WordPtr] ← NIL,
NewQ, NewUD: PROC [Node, WordPtr] RETURNS [BOOLEAN] ← NIL,
QFromNode, UDFromNode, ValFromNode, SetNode: PROC [Node, WordPtr] ← NIL
];
Mesa: TYPE = RECORD [mesa: ROPE, directory, imports: RopeList ← NIL];
NodeList: TYPE = LIST OF Node;
Format: TYPE = REF FormatRep;
FormatRep: TYPE = RECORD [
FormatValue: PROC [Node, Format, WordPtr] RETURNS [ROPE],
If node's type is simple, user data pointed to by WordPtr; otherwise use data kept at node.
ParseValue: PROC [Node, Format, WordPtr, STREAM] RETURNS [BOOLEAN],
If node's type is simple, user data pointed to by WordPtr; otherwise use data kept at node.
FormatTest: PROC [NodeType, Format, NodeTestProc, NodeTestData] RETURNS [ROPE],
ParseTest: PROC [NodeType, Format, STREAM] RETURNS [BOOLEAN, NodeTestProc, NodeTestData],
MaxWidth: PROC [NodeType, Format, VFonts.Font] RETURNS [INT],
formatData: REF ANYNIL,
key: ROPE
];
ValWP: PROC [node: Node] RETURNS [wp: WordPtr] = INLINE
{wp ← IF node.type.simple THEN node.visible.SocketToWP[] ELSE NIL};
NodeTestProc: TYPE = PROC [where: WordPtr, testData: NodeTestData, nodeType: NodeType] RETURNS [passes: BOOLEAN];
NodeTestData: TYPE = REF ANY;
StretchList: TYPE = LIST OF Stretch;
Stretch: TYPE = RECORD [
node: Node,
variant: SELECT type: StretchType FROM
single => [],
sub => [first, last: INTEGER],
ENDCASE];
StretchType: TYPE = {single, sub};
SingleStretch: TYPE = Stretch[single];
SubStretch: TYPE = Stretch[sub];
Single: PROC [n: Node] RETURNS [Stretch] = INLINE {RETURN[[n, single[]]]};
Sub: PROC [n: Node, first: INTEGERFIRST[INTEGER], last: INTEGERLAST[INTEGER]] RETURNS [Stretch] = INLINE {
WITH n.type SELECT FROM
ant: ArrayNodeType => BEGIN
IF first = FIRST[INTEGER] THEN first ← ant.first ELSE IF first < ant.first THEN ERROR;
IF last = LAST[INTEGER] THEN last ← ant.last ELSE IF last > ant.last THEN ERROR;
IF first > last THEN ERROR;
RETURN [[n, sub[first, last]]];
END;
ant: AtomNodeType => ERROR;
ENDCASE => ERROR};
Node: TYPE = REF NodeRep;
NodeRep: TYPE = RECORD [
name: ROPE,
type: NodeType,
data: REF ANYNIL, --yes, nodes can have their own data!
initialValue: ROPENIL,
initialValueFormat: Format ← NIL,
cellIn: Cell,
visible: Socket ← [NIL, LAST[CARDINAL]],
unwriteability: INTEGER ← 0,
connections: SocketList ← NIL,
found, XPhobic, isInput: BOOLEANFALSE,
The NodeType is responsible for maintaining "isInput".
nextPerturbed, nextAffected, nextX, prevX: Node ← NIL--compiler can't handle: notInNodeList--,
watchers: ARRAY Priority OF WatcherList ← ALL[NIL],
next: Node ← NIL,
other: Assertions ← NIL];
notInNodeList: Node;
SocketList: TYPE = LIST OF Socket;
Socket: TYPE = RECORD [cell: Cell, index: CARDINAL];
SocketToWP: PROC [s: Socket, useBryant: BOOLFALSE] RETURNS [wp: WordPtr];
Priority: TYPE = {ordinary, high};
"ordinary" is for ordinary mortals, like breakpoints
"high" is for things like the display, which should be updated first
Cell: TYPE = REF CellRep;
CellRep: TYPE = RECORD [
name: ROPE,
type: CellType,
nextInstance: Cell,
sim: Simulation,
parent, leftChild, rightSibling: Cell,
firstInternalNode: Node,
internalNodes, components: SymbolTable,
interfaceNodes: NodeS,
other: Assertions,
substantiality: CellSubstantiality,
expansion: ExpandDecision,
realCellStuff: RealCellStuff -- non-NIL only for Real Cells
];
notInCellList: Cell;
ExpandDecision: TYPE = {Leaf, Inline, Nested};
CellSubstantiality: TYPE = {Real, Shadow};
RealCellStuff: TYPE = REF RealCellStuffRep;
RealCellStuffRep: TYPE = RECORD [
schedNext, nextNeeded, nextNoted: Cell ← NIL--notInCellList--,
newIO, oldIO, switchIO: REF ANY,
newIOAsWP, oldIOAsWP, switchIOAsWP: WordPtr,
locked: BOOLEANFALSE,
affectedFlags: AffectedFlags ← ALL[FALSE],
initQed, propQed, initUDed, propUDed: BOOLEANFALSE,
state: REF ANY,
evals: EvalProcs,
schedWatchers, evalWatchers: WatcherList ← NIL];
AffectedFlags: TYPE = ARRAY Speciality OF BOOLEAN;
Speciality: TYPE = {special, general};
EvalProcs: TYPE = RECORD [
ValsChanged, InitQ, PropQ, InitUD, PropUD, FinalUD, EvalSimple: CellProc ← NIL,
FindVicinity: PROC [cell: Cell, portIndex: CARDINAL, evenIfInput: BOOLFALSE] ← NIL];
noPort: CARDINAL = LAST[CARDINAL];
CellProc: TYPE = PROC [cell: Cell];
Structure: TYPE = REF StructureRep;
StructureRep: TYPE = RECORD [
container, mirror: Cell,
schedFirst, schedLast, firstNeeded: Cell,
locked, running: BOOLEANFALSE,
insideNodes: NodeS,
nextPerturbed, nextWasPerturbed: Structure ← NIL--notInStrList--,
firstPerturbed, firstAffected: Node ← NIL];
notInStrList: Structure;
CellToStr: PROC [cell: Cell] RETURNS [str: Structure];
ContainingStr: PROC [cell: Cell] RETURNS [str: Structure] = INLINE
{str ← CellToStr[cell.parent]};
NodeS: TYPE = REF NodeSR;
NodeSR: TYPE = RECORD [nodes: SEQUENCE length: CARDINAL OF Node];
ExpandProc: TYPE = PROC [thisCell: Cell, to: ExpansionReceiver];
ExpansionReceiver: TYPE = RECORD [instance: REF ANY, class: ERClass];
ERClass: TYPE = REF ERClassRep;
ERClassRep: TYPE = RECORD [
CellInstance: PROC [erInstance: REF ANY, instanceName, typeName, interfaceNodes: ROPE, other: Assertions ← NIL] RETURNS [cell: Cell],
NodeInstance: PROC [erInstance: REF ANY, name: ROPE, type: NodeType, initialValue, initialValueFormat: ROPENIL, initData: REF ANYNIL, other: Assertions ← NIL] RETURNS [node: Node],
SplitJoin: PROC [erInstance: REF ANY, a, b: StretchList, writeA, writeB: BOOLEAN],
This proc declares the alignment of two lists of subarrays or elements.
ChangeReps: PROC [erInstance: REF ANY, a, b: Node, writeA, writeB: BOOLEAN]
This proc declares that the two nodes are electrically identical, but use different representations during simulation.
];
IOCreator: TYPE = PROC [ct: CellType] RETURNS [ioAsAny: REF ANY];
DriveCreator: TYPE = PROC [ct: CellType] RETURNS [driveAsAny: REF ANY];
Initializer: TYPE = PROC [cell: Cell, leafily: BOOLEAN];
CellType: TYPE = REF CellTypeRep;
CellTypeRep: TYPE = RECORD [
name: ROPE,
expand: ExpandProc,
ioCreator: IOCreator,
driveCreator: DriveCreator,
initializer: Initializer,
evals: EvalProcs,
testers: SymbolTable,
ports: Ports,
ioWordCount: CARDINAL,
hasASwitchPort, hasASpecialPort: BOOLFALSE,
firstInstance: Cell,
typeData: REF ANYNIL,
other: Assertions ← NIL];
CellTest: TYPE = REF CellTestRep;
CellTestRep: TYPE = RECORD [
name: ROPE,
proc: CellTestProc,
stateToo: BOOL
];
CellTestProc: TYPE = PROC [handle: CellTestHandle, testeeType: CellType, testData, io, driveAsAny, stateAsAny: REF ANY];
CellTestHandle: TYPE = REF CellTestHandleRep;
CellTestHandleRep: TYPE;
NarrowToCellTestHandle: PROC [any: REF ANY] RETURNS [cth: CellTestHandle];
GetSimulationFromCellTestHandle: PROC [CellTestHandle] RETURNS [Simulation];
DriveLevel: TYPE = {Drive, Ignore, Test};
DriveTagType: TYPE = CARDINAL;
Ports: TYPE = REF PortsRep;
PortsRep: TYPE = RECORD [
ports: SEQUENCE length: CARDINAL OF Port];
Port: TYPE = RECORD [
firstWord, wordCount: CARDINAL,
name: ROPE,
type: NodeType,
input, output, XPhobic, special: BOOLEANFALSE,
other: Assertions ← NIL];
SocketIsSpecial: PROC [s: Socket] RETURNS [special: BOOL] = INLINE
{port: Port ← s.cell.type.ports[s.index];
special ← (NOT port.type.simple) AND port.special AND (s.cell.expansion = Leaf) AND (ContainingStr[s.cell].mirror = s.cell)};
GetIndex: PROC [ports: Ports, key: ROPE] RETURNS [index: CARDINAL];
notFound: CARDINAL = LAST[CARDINAL];
Simulation: TYPE = REF SimulationRep;
SimulationRep: TYPE = RECORD [
steady: BOOL,
root: Cell,
firstPerturbedStr, firstWasPerturbedStr: Structure ← NIL,
firstX, lastX: Node ← NIL,
switched, wasSettled: BOOLEANFALSE,
other: Assertions ← NIL];
END.