[Indigo]<Rosemary>PreRelease>Rosemary2.DF=>SwitchNumConvertImpl.Mesa
Last Edited by: Spreitzer, March 19, 1984 2:37:21 pm PST
DIRECTORY IO, NumTypes, Rope, RoseCreate, RoseRun, RoseTypes, SwitchNumConvert, SwitchTypes;
SwitchNumConvertImpl: CEDAR PROGRAM
IMPORTS IO, NumTypes, Rope, RoseCreate, RoseRun, SwitchTypes
EXPORTS SwitchNumConvert =
BEGIN OPEN RoseTypes;
ConverterState: TYPE = REF ConverterStateRep;
ConverterStateRep: TYPE = RECORD [
atomic: BOOLEAN,
first, last, length, no, switchWordCount, numWordCount: INTEGER ← 0,
writeSwitchy, writeNummy: BOOLEAN];
MakeTransducer: PUBLIC PROC [switchy, nummy: Node, within: Cell, writeSwitchy, writeNummy: BOOLEAN] RETURNS [t: Cell] =
BEGIN
className: ROPE;
state: ConverterState;
state ← NEW [ConverterStateRep ← [
atomic: switchy.type.structureType = atom,
writeSwitchy: writeSwitchy, writeNummy: writeNummy]];
IF NOT SwitchTypes.IsSwitchType[switchy.type] THEN RETURN [NIL];
IF NOT NumTypes.Numeric[nummy.type] THEN RETURN [NIL];
IF writeSwitchy = writeNummy THEN ERROR;
IF NOT SameStructure[switchy.type, nummy.type] THEN ERROR;
WITH switchy.type SELECT FROM
a: AtomNodeType => NULL;
a: ArrayNodeType => {state.first ← a.first; state.last ← a.last};
ENDCASE => ERROR;
state.length ← state.last - state.first + 1;
state.numWordCount ← (15 + state.length)/16;
state.switchWordCount ← (SwitchTypes.switchValsPerWord + state.length - 1)/SwitchTypes.switchValsPerWord;
state.no ← (16 - (state.length MOD 16)) MOD 16;
className ← GetClass[state, switchy, nummy];
t ← RoseCreate.CreateCell[within: within, instanceName: switchy.name.Cat["-", nummy.name], className: className, interfaceNodes: switchy.name.Cat[", ", nummy.name], initData: state];
END;
GetAtom: PROC [nt: NodeType] RETURNS [a: NodeType] = {
WITH nt SELECT FROM
x: AtomNodeType => a ← nt;
x: ArrayNodeType => a ← GetAtom[x.element];
ENDCASE => ERROR};
SameStructure: PROC [a, b: NodeType] RETURNS [same: BOOLEAN] =
BEGIN
first, last: INTEGER;
IF a.structureType # b.structureType THEN RETURN [FALSE];
WITH a SELECT FROM
x: ArrayNodeType => {first ← x.first; last ← x.last};
x: AtomNodeType => NULL;
ENDCASE => ERROR;
WITH b SELECT FROM
x: ArrayNodeType => {same ← first = x.first AND last = x.last};
x: AtomNodeType => same ← TRUE;
ENDCASE => ERROR;
END;
ClassNote: TYPE = RECORD [
parms: ConverterStateRep,
class: CellClass];
ClassNoteList: TYPE = LIST OF ClassNote;
classNotes: ClassNoteList ← NIL;
Words: TYPE = REF WordsRep;
WordsRep: TYPE = RECORD [words: SEQUENCE length: CARDINAL OF CARDINAL];
Switches: TYPE = LONG POINTER TO PACKED ARRAY CARDINAL OF SwitchTypes.SwitchVal;
Nums: TYPE = LONG POINTER TO PACKED ARRAY CARDINAL OF BOOLEAN;
GetClass: PROC [state: ConverterState, switchy, nummy: Node] RETURNS [className: ROPE] =
BEGIN
ports: Ports ← NEW [PortsRep[2]];
ports[0] ← [1, state.switchWordCount, "switchy", switchy.type, state.writeNummy, state.writeSwitchy, state.writeNummy];
ports[1] ← [1+state.switchWordCount, state.numWordCount, "nummy", nummy.type, state.writeSwitchy, state.writeNummy];
FOR cnl: ClassNoteList ← classNotes, cnl.rest WHILE cnl # NIL DO
IF cnl.first.parms = state^ THEN RETURN [cnl.first.class.name];
ENDLOOP;
className ← IO.PutFR[
"SN %g %g..%g %g %g",
IO.bool[state.atomic],
IO.int[state.first],
IO.int[state.last],
IO.bool[state.writeSwitchy],
IO.bool[state.writeNummy]];
[] ← RoseCreate.RegisterCellClass[
className: className,
ioCreator: CreateConverterIO,
initializer: InitializeConverter,
evals: [
ValsChanged: ConverterValsChanged,
InitQ: NIL,
PropQ: ConverterPropQ,
InitUD: NIL,
PropUD: ConverterPropUD,
FinalUD: NIL,
EvalSimple: ConverterSimple,
FindVicinity: NIL],
ports: ports];
END;
CreateConverterIO: IOCreator--PROC [cell: Cell, initData: REF ANY]-- =
BEGIN
cs: ConverterState ← NARROW[initData];
cell.realCellStuff.switchIO ← NEW [WordsRep[cs.switchWordCount+cs.numWordCount]];
cell.realCellStuff.newIO ← NEW [WordsRep[cs.switchWordCount+cs.numWordCount]];
cell.realCellStuff.oldIO ← NEW [WordsRep[cs.switchWordCount+cs.numWordCount]];
END;
InitializeConverter: Initializer--PROCEDURE [cell: Cell, initData: REF ANY, leafily: BOOLEAN]-- =
{IF leafily THEN cell.realCellStuff.state ← initData};
ConverterSimple: CellProc--PROC [cell: Cell]-- =
BEGIN
cs: ConverterState ← NARROW[cell.realCellStuff.state];
IF cs.writeSwitchy THEN RoseRun.PerturbPort[cell, 0];
END;
ConverterValsChanged: CellProc--PROC [cell: Cell]-- =
BEGIN
cs: ConverterState ← NARROW[cell.realCellStuff.state];
new: Words ← NARROW[cell.realCellStuff.newIO];
old: Words ← NARROW[cell.realCellStuff.oldIO];
FOR i: INTEGER IN [cs.switchWordCount .. cs.switchWordCount+cs.numWordCount) DO old[i] ← new[i] ENDLOOP;
IF cs.writeNummy THEN {
s: Switches;
n: Nums;
TRUSTED {
s ← LOOPHOLE[cell.realCellStuff.switchIOAsWP+1];
n ← LOOPHOLE[cell.realCellStuff.newIOAsWP+1+cs.switchWordCount]};
FOR i: INTEGER IN [0 .. cs.length) DO
TRUSTED {IF s[i].val # X THEN n[i+cs.no] ← s[i].val = H};
ENDLOOP;
};
END;
ConverterPropQ: CellProc--PROC [cell: Cell]-- =
BEGIN
cs: ConverterState ← NARROW[cell.realCellStuff.state];
IF cs.writeSwitchy THEN TRUSTED {
s: Switches ← LOOPHOLE[cell.realCellStuff.switchIOAsWP+1];
n: Nums ← LOOPHOLE[cell.realCellStuff.newIOAsWP+1+cs.switchWordCount];
FOR i: INTEGER IN [0 .. cs.length) DO s[i].s[q] ← drive ENDLOOP;
};
END;
ConverterPropUD: CellProc--PROC [cell: Cell]-- =
BEGIN
Convert: PROC [on: BOOLEAN] RETURNS [up, down: SwitchTypes.Strength] = {
IF on THEN RETURN [drive, none] ELSE RETURN [none, drive]};
cs: ConverterState ← NARROW[cell.realCellStuff.state];
IF cs.writeSwitchy THEN TRUSTED {
s: Switches ← LOOPHOLE[cell.realCellStuff.switchIOAsWP+1];
n: Nums ← LOOPHOLE[cell.realCellStuff.newIOAsWP+1+cs.switchWordCount];
FOR i: INTEGER IN [0 .. cs.length) DO
[s[i].s[u], s[i].s[d]] ← Convert[n[i+cs.no]];
ENDLOOP;
};
END;
END.