[Indigo]<Rosemary>2.6>Rosemary.DF=>RoseTypes.Mesa
Last Edited by: Spreitzer, November 19, 1984 1:41:46 pm 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 ANY ← NIL];
Warning: SIGNAL [msg: ROPE, data: REF ANY ← NIL];
Stop: SIGNAL [msg: ROPE, data: REF ANY ← NIL];
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: BOOLEAN ← TRUE,
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 ANY ← NIL,
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:
INTEGER ←
FIRST[
INTEGER], last:
INTEGER ←
LAST[
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 ANY ← NIL, --yes, nodes can have their own data!
initialValue: ROPE ← NIL,
cellIn: Cell,
visible: Socket ← [NIL, LAST[CARDINAL]],
unwriteability: INTEGER ← 0,
connections: SocketList ← NIL,
found, XPhobic, isInput:
BOOLEAN ←
FALSE,
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: BOOL ← FALSE] 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: BOOLEAN ← FALSE,
affectedFlags: AffectedFlags ← ALL[FALSE],
initQed, propQed, initUDed, propUDed: BOOLEAN ← FALSE,
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:
BOOL ←
FALSE] ←
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: BOOLEAN ← FALSE,
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: ROPE ← NIL, initData: REF ANY ← NIL, 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 [cell: Cell];
Initializer: TYPE = PROC [cell: Cell, --??initData: REF ANY,??-- leafily: BOOLEAN];
CellType: TYPE = REF CellTypeRep;
CellTypeRep:
TYPE =
RECORD [
name: ROPE,
expand: ExpandProc,
ioCreator: IOCreator,
initializer: Initializer,
evals: EvalProcs,
blackBox, stateToo: CellTestProc,
ports: Ports,
ioWordCount: CARDINAL,
hasASpecialPort: BOOL ← FALSE,
firstInstance: Cell,
drivePrototype: REF ANY ← NIL,
typeData: REF ANY ← NIL,
other: Assertions ← NIL];
CellTestProc:
TYPE =
PROC [handle: CellTestHandle, testeeType: CellType,
--??initData,??-- 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];
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: BOOLEAN ← FALSE,
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: BOOLEAN ← FALSE,
other: Assertions ← NIL];
END.