RoseBitImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Barth, September 5, 1985 6:37:22 pm PDT
Spreitzer, September 30, 1985 9:23:57 pm PDT
DIRECTORY Basics, ImagerFont, IO, Real, Rope, RoseBehavior, RoseTransduce, RoseWireClasses, RoseWireTypes, VFonts;
RoseBitImpl: CEDAR PROGRAM
IMPORTS ImagerFont, IO, Real, Rope, RoseTransduce
EXPORTS RoseWireClasses, RoseTransduce =
BEGIN OPEN RoseWireTypes;
SwitchVal: TYPE = RoseBehavior.SwitchVal;
Level: TYPE = RoseBehavior.Level;
GetBit: PUBLIC PROC RETURNS [RoseWireClass] = {RETURN[bitClass]};
bitSuperClass: RoseWireSuperClass ← NEW[RoseWireSuperClassRec ← [
GetType: BitGetType,
ListFormats: BitListFormats,
GetFormat: BitGetFormat,
Bits: BitBits,
MesaRepresentation: BitMesaRepresentation,
MesaRepAux: BitMesaRepAux,
flavor: switch,
Initialize: BitInitialize,
Transduce: BitTransduce,
InitQ: BitInitQ,
InitUD: BitInitUD,
ComputeLevel: BitComputeLevel,
CopyQ: BitCopyQ,
CopyUD: BitCopyUD,
CopyLevel: BitCopyLevel,
EqualUD: BitEqualUD,
MaxinQ: BitMaxinQ,
MaxinUD: BitMaxinUD
]];
bitClass: RoseWireClass ← NEW[RoseWireClassRec ← [
structure: atom,
dereference: FALSE,
addressContaining: FALSE,
classData: NIL,
super: bitSuperClass]];
BitGetType: PROC [rwc: RoseWireClass, wire: Wire] RETURNS [rwt: RoseWireType] = {
IF wire.structure # atom THEN ERROR;
RETURN[bitType];
};
bitType: PUBLIC RoseWireType ← NEW[RoseWireTypeRec ← [
class: bitClass,
typeData: NIL,
length: 0,
other: NIL]];
BitListFormats: PROC [rwt: RoseWireType] RETURNS [lor: LOR] = {
lor ← LIST["full", "numeric"];
};
BitGetFormat: PROC [rwt: RoseWireType, formatName: ROPE] RETURNS [format: Format] = {
format ← SELECT TRUE FROM
formatName.Equal["full"], formatName=NIL => fullFormat,
formatName.Equal["numeric"], formatName=NIL => numericFormat,
ENDCASE => ERROR;
};
BitBits: PROC [rwt: RoseWireType] RETURNS [n: INT] = {RETURN[Basics.bitsPerWord]};
BitMesaRepresentation: PROC [rwc: RoseWireClass] RETURNS [mesa: Mesa] = {
mesa ← [mesa: "SwitchVal"]};
BitMesaRepAux: PROC [rwc: RoseWireClass] RETURNS [mesa: Mesa] = {
mesa ← [
mesa: "SwitchVal: TYPE = RoseBehavior.SwitchVal",
directory: LIST["RoseBehavior"]
];
};
SwitchValPtr: TYPE = LONG POINTER TO SwitchVal;
BitInitialize: PROC [rwt: RoseWireType, p: Ptr, steady: BOOL] = {
WriteSwitch[
p,
IF steady
THEN [s: [q: charge, u: none, d: charge], val: L]
ELSE [s: [q: charge, u: charge, d: charge], val: X]
];
};
BitTransduce: PROC [fromS: Strength, fromT, toT: RoseWireType, fromP, toP: Ptr] = {
IF fromT # bitType THEN ERROR;
IF toT # RoseTransduce.boolType THEN ERROR;
RoseTransduce.WriteBool[
toP,
SELECT ReadSwitch[fromP].val FROM
L => FALSE,
H => TRUE,
X => ERROR,
ENDCASE => ERROR
];
};
BitInitQ: PROC [rwt: RoseWireType, p: Ptr, cap: Strength] = TRUSTED {
svp: SwitchValPtr = SVPFromPtr[p];
svp.s[q] ← cap;
};
BitInitUD: PROC [rwt: RoseWireType, p: Ptr, cap: Strength] RETURNS [isInput: BOOL] = TRUSTED {
svp: SwitchValPtr = SVPFromPtr[p];
u, d: Strength;
[u, d] ← Parts[svp.val, cap];
svp.s[u] ← Block[u, svp.s[q]];
svp.s[d] ← Block[d, svp.s[q]];
isInput ← svp.s[q] = input;
};
Block: PROC [a, b: Strength] RETURNS [c: Strength] =
{c ← IF a < b THEN none ELSE a};
Parts: PROC [l: Level, s: Strength] RETURNS [u, d: Strength] = {
RETURN [
SELECT l FROM
L => none,
H, X => s,
ENDCASE => ERROR,
SELECT l FROM
H => none,
L, X => s,
ENDCASE => ERROR]};
BitComputeLevel: PROC [rwt: RoseWireType, p: Ptr, xPhobic: BOOL] RETURNS [delay: BOOL] = TRUSTED {
svp: SwitchValPtr = SVPFromPtr[p];
temp: Level ←
IF svp.s[u] = none AND svp.s[d] > none THEN L ELSE
IF svp.s[d] = none AND svp.s[u] > none THEN H ELSE
X;
IF NOT (delay ← xPhobic AND temp = X) THEN svp.val ← temp;
};
BitCopyQ: PROC [rwt: RoseWireType, from, to: Ptr] = TRUSTED {
fromSVP: SwitchValPtr = SVPFromPtr[from];
toSVP: SwitchValPtr = SVPFromPtr[to];
toSVP.s[q] ← fromSVP.s[q];
};
BitCopyUD: PROC [rwt: RoseWireType, from, to: Ptr] = TRUSTED {
fromSVP: SwitchValPtr = SVPFromPtr[from];
toSVP: SwitchValPtr = SVPFromPtr[to];
toSVP.s[u] ← fromSVP.s[u];
toSVP.s[d] ← fromSVP.s[d];
};
BitCopyLevel: PROC [rwt: RoseWireType, from, to: Ptr] = TRUSTED {
fromSVP: SwitchValPtr = SVPFromPtr[from];
toSVP: SwitchValPtr = SVPFromPtr[to];
toSVP.val ← fromSVP.val;
};
BitEqualUD: PROC [rwt: RoseWireType, p1, p2: Ptr] RETURNS [equal: BOOL] = TRUSTED {
svp1: SwitchValPtr = SVPFromPtr[p1];
svp2: SwitchValPtr = SVPFromPtr[p2];
equal ← svp1.s[u] = svp2.s[u] AND svp1.s[d] = svp2.s[d];
};
BitMaxinQ: PROC [rwt: RoseWireType, from, to: Ptr] RETURNS [increase: BOOL] = TRUSTED {
fromSVP: SwitchValPtr = SVPFromPtr[from];
toSVP: SwitchValPtr = SVPFromPtr[to];
increase ← FALSE;
IF toSVP.s[q]<fromSVP.s[q] THEN {toSVP.s[q]𡤏romSVP.s[q]; increase ← TRUE};
};
BitMaxinUD: PROC [rwt: RoseWireType, from, to: Ptr] RETURNS [increase: BOOL] = TRUSTED {
fromSVP: SwitchValPtr = SVPFromPtr[from];
toSVP: SwitchValPtr = SVPFromPtr[to];
u: Strength ← Block[fromSVP.s[u], toSVP.s[q]];
d: Strength ← Block[fromSVP.s[d], toSVP.s[q]];
increase ← FALSE;
IF toSVP.s[u] < u THEN {toSVP.s[u] ← u; increase ← TRUE};
IF toSVP.s[d] < d THEN {toSVP.s[d] ← d; increase ← TRUE};
};
numericFormat: Format ← NEW [FormatRep ← [
FormatValue: NumericFormatValue,
ParseValue: NumericParseValue,
MaxWidth: NumericMaxWidth,
key: "numeric"]];
NumericFormatValue: PROC [rwt: RoseWireType, f: Format, p: Ptr] RETURNS [r: ROPE] = {
r ← SELECT ReadSwitch[p].val FROM
L => "0",
H => "1",
X => "X",
ENDCASE => ERROR;
};
NumericParseValue: PROC [rwt: RoseWireType, f: Format, p: Ptr, s: STREAM] RETURNS [ok: BOOL] = {
c: CHAR = s.GetChar[];
val: SwitchVal;
SELECT c FROM
'0 => val ← [s: [q: charge, u: none, d: charge], val: L];
'X => val ← [s: [q: charge, u: charge, d: charge], val: X];
'1 => val ← [s: [q: charge, u: charge, d: none], val: H];
ENDCASE => RETURN [FALSE];
WriteSwitch[p, val];
ok ← TRUE;
};
NumericMaxWidth: PROC [rwt: RoseWireType, fmt: Format, font: VFonts.Font] RETURNS [max: INT] = {
max ← Real.Round[ImagerFont.RopeWidth[font, "X"].x];
};
DriveName: ARRAY Drive OF ROPE = [
test: "0",
see: "1",
none: "2",
chargeWeak: "3",
chargeMediumWeak: "4",
charge: "5",
chargeMediumStrong: "6",
chargeStrong: "7",
chargeVeryStrong: "8",
driveWeak: "9",
driveMediumWeak: "A",
drive: "B",
driveMediumStrong: "C",
driveStrong: "D",
driveVeryStrong: "E",
input: "F"
];
LevelName: ARRAY Level OF ROPE = [L: "L", X: "X", H: "H"];
fullFormat: Format ← NEW [FormatRep ← [
FormatValue: FullFormatValue,
ParseValue: FullParseValue,
MaxWidth: FullMaxWidth,
key: "full"]];
FullFormatValue: PROC [rwt: RoseWireType, f: Format, p: Ptr] RETURNS [r: ROPE] = {
val: SwitchVal = ReadSwitch[p];
r ← Rope.Cat[
DriveName[val.s[q]],
DriveName[val.s[u]],
DriveName[val.s[d]],
LevelName[val.val]
];
};
FullParseValue: PROC [rwt: RoseWireType, f: Format, p: Ptr, s: STREAM] RETURNS [ok: BOOL] = {
ENABLE IO.Error, IO.EndOfStream => {ok ← FALSE; CONTINUE};
val: SwitchVal;
ok ← TRUE;
val.s[q] ← ParseDrive[s];
val.s[u] ← ParseDrive[s];
val.s[d] ← ParseDrive[s];
val.val ← ParseLevel[s];
WriteSwitch[p, val];
};
ParseDrive: PROC [s: STREAM] RETURNS [d: Drive] = {
c: CHAR = s.GetChar[];
FOR drive: Drive IN Drive DO
IF c = DriveName[drive].Fetch[0] THEN RETURN [drive];
ENDLOOP;
IO.Error[SyntaxError, s];
};
ParseLevel: PROC [s: STREAM] RETURNS [l: Level] = {
c: CHAR = s.GetChar[];
FOR level: Level IN Level DO
IF c = LevelName[level].Fetch[0] THEN RETURN [level];
ENDLOOP;
IO.Error[SyntaxError, s];
};
FullMaxWidth: PROC [rwt: RoseWireType, fmt: Format, font: VFonts.Font] RETURNS [max: INT] = {
max ← Real.Round[ImagerFont.RopeWidth[font, "FFFX?"].x];
};
ReadSwitch: PUBLIC PROC [p: Ptr] RETURNS [s: SwitchVal] = TRUSTED {
svp: SwitchValPtr = SVPFromPtr[p];
s ← svp^;
};
WriteSwitch: PUBLIC PROC [p: Ptr, s: SwitchVal] = TRUSTED {
svp: SwitchValPtr = SVPFromPtr[p];
svp^ ← s;
};
SVPFromPtr: PROC [p: Ptr] RETURNS [svp: SwitchValPtr] = {
svp ← LOOPHOLE[p.word];
IF p.bit # 0 THEN ERROR;
};
END.