Array Position
nodeNames: PUBLIC ARRAY NodeType OF Rope.ROPE ← ["OToP", "RUToP", "LDToP", "LToP", "PToI", "PToRU", "PToLD", "PToL", "ORUToI", "LDToLD", "OLDToI", "ORUToL", "Tristate", "RUToRU", "ORUToLD", "LDToI", "OLDToRU", "LToI", "RUToI", "Inverter", "FlipFlop", "ParallelInput", "InputEnabled", "RAMEven", "RAMOdd", "Master", "Input", "Interchip", "Long", "Output", "LeftDown", "RightUp"];
orientationNames:
PUBLIC
ARRAY Orientation
OF Rope.
ROPE ← ["Vertical", "Horizontal"];
positionTable: RefTab.Ref ← RefTab.Create[hash: ArrayPositionHash, equal: ArrayPositionEqual];
key: ArrayPosition ← NEW[ArrayPositionRec];
CreateArrayPosition:
PUBLIC
ENTRY
PROC [type: NodeType ← OToP, orientation: Orientation ← Vertical, grain: Position, minorArray: Position ← [0, 0], chip: Position ← [0, 0]]
RETURNS [position: ArrayPosition] = {
key.type ← type;
key.orientation ← orientation;
key.grain ← grain;
key.minorArray ← minorArray;
key.chip ← chip;
position ← InternalArrayPosition[key];
};
CopyArrayPosition:
PUBLIC
ENTRY
PROC [old: ArrayPosition]
RETURNS [new: ArrayPosition] = {
new ← InternalArrayPosition[old];
};
CopyArrayPositionRec:
PUBLIC
ENTRY
PROC [old: ArrayPositionRec]
RETURNS [new: ArrayPosition] = {
key^ ← old;
new ← InternalArrayPosition[key];
};
InternalArrayPosition:
INTERNAL
PROC [old: ArrayPosition]
RETURNS [new: ArrayPosition] = {
new ← NARROW[RefTab.Fetch[positionTable, old].val];
IF new=
NIL
THEN {
new ← NEW[ArrayPositionRec];
new^ ← old^;
IF NOT RefTab.Store[positionTable, new, new] THEN ERROR;
};
};
ArrayPositionToRope:
PUBLIC
PROC [position: ArrayPosition]
RETURNS [rope: Rope.
ROPE] = {
rope ← IO.PutFR["%g %g", IO.rope[orientationNames[position.orientation]], IO.rope[nodeNames[position.type]]];
rope ← Rope.Cat[rope, IO.PutFR[" [%g, %g]", IO.int[position.chip.x], IO.int[position.chip.y]]];
rope ← Rope.Cat[rope, (
SELECT
TRUE
FROM
position.type#Long => IO.PutFR[" [%g, %g]", IO.int[position.minorArray.x], IO.int[position.minorArray.y]],
position.orientation=Vertical => IO.PutFR[" [%g, -]", IO.int[position.minorArray.x]],
ENDCASE => IO.PutFR[" [-, %g]", IO.int[position.minorArray.y]])];
rope ← Rope.Cat[rope, (
SELECT
TRUE
FROM
position.type=InputEnabled => IO.PutFR[" [%g, %g]", IO.int[position.grain.x], IO.int[position.grain.y]],
position.orientation=Vertical => IO.PutFR[" [%g, -]", IO.int[position.grain.x]],
ENDCASE => IO.PutFR[" [-, %g]", IO.int[position.grain.y]])];
};
RopeToArrayPosition:
PUBLIC
PROC [rope: Rope.
ROPE]
RETURNS [position: ArrayPosition] = {
GetPosition:
PROC [firstDash, secondDash:
BOOL ←
FALSE]
RETURNS [pos: Position ← [0, 0]] = {
token ← IO.GetCedarTokenRope[s].token;
IF NOT Rope.Equal[token, "["] THEN ERROR;
IF firstDash
THEN {
token ← IO.GetCedarTokenRope[s].token;
IF NOT Rope.Equal[token, "-"] THEN ERROR;
}
ELSE pos.x ← IO.GetInt[s];
token ← IO.GetCedarTokenRope[s].token;
IF NOT Rope.Equal[token, ","] THEN ERROR;
IF secondDash
THEN {
token ← IO.GetCedarTokenRope[s].token;
IF NOT Rope.Equal[token, "-"] THEN ERROR;
}
ELSE pos.y ← IO.GetInt[s];
token ← IO.GetCedarTokenRope[s].token;
IF NOT Rope.Equal[token, "]"] THEN ERROR;
};
s: IO.STREAM ← IO.RIS[rope];
token: Rope.ROPE ← IO.GetID[s];
type: NodeType;
orientation: Orientation;
grain, minorArray, chip: Position;
FOR o: Orientation
IN Orientation
DO
IF Rope.Equal[token, orientationNames[o]]
THEN {
position.orientation ← o;
EXIT;
};
REPEAT FINISHED => ERROR;
ENDLOOP;
token ← IO.GetID[s];
FOR t: NodeType
IN NodeType
DO
IF Rope.Equal[token, nodeNames[t]]
THEN {
type ← t;
EXIT;
};
REPEAT FINISHED => ERROR;
ENDLOOP;
chip ← GetPosition[];
minorArray ← GetPosition[firstDash: position.type=Long AND position.orientation=Horizontal, secondDash: position.type=Long AND position.orientation=Vertical];
grain ← GetPosition[firstDash: position.type#InputEnabled AND position.orientation=Horizontal, secondDash: position.type#InputEnabled AND position.orientation=Vertical];
position ← CreateArrayPosition[type, orientation, grain, minorArray, chip];
};
ArrayPositionEqual:
PUBLIC RefTab.EqualProc = {
p1: ArrayPosition ← NARROW[key1];
p2: ArrayPosition ← NARROW[key2];
IF p1=p2 THEN RETURN[TRUE];
RETURN[p1^=p2^];
};
ArrayPositionHash:
PUBLIC RefTab.HashProc = {
p: ArrayPosition ← NARROW[key];
hash: PBasics.Word ← LOOPHOLE[p.chip.x];
hash ← PBasics.BITXOR[PBasics.BITSHIFT[hash, 2], LOOPHOLE[p.chip.y]];
hash ← PBasics.BITXOR[PBasics.BITSHIFT[hash, 2], LOOPHOLE[p.minorArray.x]];
hash ← PBasics.BITXOR[PBasics.BITSHIFT[hash, 2], LOOPHOLE[p.minorArray.y]];
hash ← PBasics.BITXOR[PBasics.BITSHIFT[hash, 2], LOOPHOLE[p.grain.x]];
hash ← PBasics.BITXOR[PBasics.BITSHIFT[hash, 2], LOOPHOLE[p.grain.y]];
hash ← PBasics.
BITXOR[PBasics.
BITSHIFT[hash, 1], (
SELECT p.orientation
FROM
Vertical => 0,
Horizontal => 1,
ENDCASE => ERROR)];
hash ← PBasics.BITXOR[PBasics.BITSHIFT[hash, 2], ORD[p.type]];
RETURN[PBasics.LowHalf[hash]];
};