[Indigo]<Rosemary>2.6>Rosemary.DF=>SwitchNumConvertImpl.Mesa
Last Edited by: Spreitzer, January 23, 1985 5:34:34 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, 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 [ct: CellType]
RETURNS [ioAsAny:
REF
ANY]
--IOCreator-- =
BEGIN
cs: ConverterState ← NARROW[ct.typeData];
ioAsAny ← 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.