[Indigo]<Rosemary>2.6>Rosemary.DF=>SwitchNumConvertImpl.Mesa
Last Edited by: Spreitzer, August 18, 1984 9:05:06 pm PDT
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, to: ExpansionReceiver] RETURNS [t: Cell] =
BEGIN
typeName: 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;
typeName ← GetType[state, switchy, nummy];
t ← to.class.CellInstance[erInstance: to.instance, instanceName: switchy.name.Cat["-", nummy.name], typeName: typeName, interfaceNodes: switchy.name.Cat[", ", nummy.name]];
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;
TypeNote: TYPE = RECORD [
parms: ConverterStateRep,
type: CellType];
TypeNoteList: TYPE = LIST OF TypeNote;
typeNotes: TypeNoteList ← 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;
GetType: PROC [state: ConverterState, switchy, nummy: Node] RETURNS [typeName: ROPE] =
BEGIN
ports: Ports ← NEW [PortsRep[2]];
ct: CellType;
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: TypeNoteList ← typeNotes, cnl.rest WHILE cnl # NIL DO
IF cnl.first.parms = state^ THEN RETURN [cnl.first.type.name];
ENDLOOP;
typeName ← 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]];
ct ← RoseCreate.RegisterCellType[
name: typeName,
ioCreator: CreateConverterIO,
initializer: InitializeConverter,
evals: [
ValsChanged: ConverterValsChanged,
InitQ: NIL,
PropQ: ConverterPropQ,
InitUD: NIL,
PropUD: ConverterPropUD,
FinalUD: NIL,
EvalSimple: ConverterSimple,
FindVicinity: NIL],
ports: ports,
typeData: state];
typeNotes ← CONS[[state^, ct], typeNotes];
END;
CreateConverterIO: PROC [cell: Cell]--IOCreator-- =
BEGIN
cs: ConverterState ← NARROW[cell.type.typeData];
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: PROCEDURE [cell: Cell, leafily: BOOLEAN] --Initializer-- =
{IF leafily THEN cell.realCellStuff.state ← cell.type.typeData};
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 {SELECT s[i].val FROM
L => n[i+cs.no] ← FALSE;
H => n[i+cs.no] ← TRUE;
X => NULL;
ENDCASE => ERROR};
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.