RoseBasicSequenceImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Barth, September 5, 1985 6:37:22 pm PDT
Spreitzer, October 1, 1985 6:32:08 pm PDT
DIRECTORY Basics, BigCardinals, BitTwiddling, Convert, ImagerFont, IO, PrincOpsUtils, Real, Rope, RoseBehavior, RoseWireClasses, RoseTransduce, RoseWireTypes, RoseWireTypeUse, RoseWiring, VFonts;
RoseBasicSequenceImpl:
CEDAR
PROGRAM
IMPORTS BigCardinals, BitTwiddling, ImagerFont, IO, PrincOpsUtils, Real, Rope, RoseTransduce, RoseWireTypes, RoseWiring
EXPORTS RoseWireClasses =
BEGIN OPEN RoseWireTypes;
SwitchVal: TYPE = RoseBehavior.SwitchVal;
Level: TYPE = RoseBehavior.Level;
BigCARD: TYPE = BigCardinals.BigCARD;
BasicSeqType: TYPE = REF BasicSeqTypeRec;
BasicSeqTypeRec:
TYPE =
RECORD [
rwc: RoseWireClass,
name: ROPE,
repAux: Mesa ← [],
ewc: RoseWireClass,
ewt: RoseWireType,
eltDefaultFormat: Format,
rwt: RoseWireType,
length: NAT,
leftPad, wordLength: NAT,
maxes: ARRAY Base OF MaxNote ← ALL[[]]
];
MaxNote:
TYPE =
RECORD [
maxWidth: INT ← 0,
maxWidthFont: ImagerFont.Font ← NIL
];
Base: TYPE = {R2, R8, R16};
BaseBase: ARRAY Base OF NAT = [R2: 2, R8: 8, R16: 16];
LgBase: ARRAY Base OF NAT = [R2: 1, R8: 3, R16: 4];
BaseSuffix: ARRAY Base OF ROPE = [R2: "B", R8: "O", R16: "H"];
Digits:
ARRAY [0 .. 16)
OF
ROPE = [
"0", "1", "2", "3",
"4", "5", "6", "7",
"8", "9", "A", "B",
"C", "D", "E", "F"];
GetBasicSequence:
PUBLIC
PROC [prototype: Wire]
RETURNS [rwc: RoseWireClass] = {
name: ROPE = RoseWiring.WireName[prototype];
flavor: WireFlavor = simple;
length: NAT = prototype.elements.size;
cedarTypeName: ROPE = name.Cat[WireFlavorName[flavor]];
ewc: RoseWireClass = RoseWiring.GetWiring[prototype.elements[0], flavor];
ewt: RoseWireType = ewc.super.GetType[ewc, prototype.elements[0]];
eltsPerWord: NAT = Basics.bitsPerWord;
wordLength: NAT = (length + eltsPerWord-1)/eltsPerWord;
bst: BasicSeqType ←
NEW [BasicSeqTypeRec ← [
rwc: NIL,
name: cedarTypeName,
ewc: ewc,
ewt: ewt,
eltDefaultFormat: ewc.super.GetFormat[ewt, NIL],
rwt: NIL,
length: length,
leftPad: wordLength*Basics.bitsPerWord - length,
wordLength: wordLength
]];
IF prototype.structure # sequence THEN ERROR;
IF ewt # RoseTransduce.boolType THEN ERROR;
bst.repAux ← [mesa: NIL];
bst.rwc ← rwc ←
NEW [RoseWireClassRec ← [
structure: sequence,
dereference: TRUE,
addressContaining: ewc.dereference OR ewc.addressContaining,
classData: bst,
super: basicSeqSuperClass]];
bst.rwt ←
NEW [RoseWireTypeRec ← [
class: rwc,
typeData: bst,
length: length
]];
};
basicSeqSuperClass: RoseWireSuperClass ←
NEW[RoseWireSuperClassRec ← [
GetType: BasicSeqGetType,
ListFormats: BasicSeqListFormats,
GetFormat: BasicSeqGetFormat,
SelectorOffset: BasicSeqSelectorOffset,
SubType: BasicSeqSubType,
SubClass: BasicSeqSubClass,
Bits: BasicSeqBits,
MesaRepresentation: BasicSeqMesaRepresentation,
MesaRepAux: BasicSeqMesaRepAux,
flavor: simple,
Initialize: BasicSeqInitialize,
Transduce: BasicSeqTransduce
]];
BasicSeqGetType:
PROC [rwc: RoseWireClass, wire: Wire]
RETURNS [rwt: RoseWireType] = {
bst: BasicSeqType = NARROW[rwc.classData];
rwt ← bst.rwt;
};
BasicSeqListFormats:
PROC [rwt: RoseWireType]
RETURNS [lor:
LOR] = {
lor ← LIST["2", "8", "16"];
};
BasicSeqGetFormat:
PROC [rwt: RoseWireType, formatName:
ROPE]
RETURNS [format: Format] = {
format ←
SELECT
TRUE
FROM
formatName.Equal["2"] => base2,
formatName.Equal["8"] => base8,
formatName.Equal["16"] => base16,
formatName=NIL => base16,
ENDCASE => ERROR;
};
BasicSeqSelectorOffset:
PROC [rwt: RoseWireType, sel: Selector]
RETURNS [dBits:
NAT] = {
bst: BasicSeqType = NARROW[rwt.typeData];
WITH sel
SELECT
FROM
whole => RETURN [0];
field => ERROR;
subscript => RETURN [SuboffI[bst, index]];
ENDCASE => ERROR;
};
Suboff:
PROC [bst: BasicSeqType, i:
NAT]
RETURNS [dBits:
NAT] =
{dBits ← SuboffI[bst, i]};
SuboffI:
PROC [bst: BasicSeqType, i:
NAT]
RETURNS [dBits:
NAT] =
INLINE {
dBits ← bst.leftPad + i;
};
WordSP: TYPE = LONG POINTER TO WordSeq;
WordSeq: TYPE = RECORD [elts: SEQUENCE length: NAT OF WORD];
BasicSeqSubType:
PROC [rwt: RoseWireType, sel: Selector]
RETURNS [RoseWireType] = {
bst: BasicSeqType = NARROW[rwt.typeData];
WITH sel
SELECT
FROM
whole => RETURN [rwt];
field => ERROR;
subscript => RETURN [bst.ewt];
ENDCASE => ERROR;
};
BasicSeqSubClass:
PROC [rwc: RoseWireClass, sel: Selector]
RETURNS [RoseWireClass] = {
bst: BasicSeqType = NARROW[rwc.classData];
WITH sel
SELECT
FROM
whole => RETURN [rwc];
field => ERROR;
subscript => RETURN [bst.ewc];
ENDCASE => ERROR;
};
BasicSeqBits:
PROC [rwt: RoseWireType]
RETURNS [n:
INT] = {
bst: BasicSeqType = NARROW[rwt.typeData];
n ← Basics.bitsPerWord * bst.wordLength;
};
BasicSeqMesaRepresentation:
PROC [rwc: RoseWireClass]
RETURNS [mesa: Mesa] = {
bst: BasicSeqType = NARROW[rwc.classData];
mesa ←
SELECT bst.wordLength
FROM
=1 => [mesa: "BitOps.BitWord", directory: LIST["BitOps"]],
=2 => [mesa: "BitOps.BitDWord", directory: LIST["BitOps"]],
>2 => [
mesa:
IO.PutFR[
"ARRAY [0 .. %g) OF CARDINAL",
[integer[bst.wordLength]]
]
],
ENDCASE => ERROR;
};
BasicSeqMesaRepAux:
PROC [rwc: RoseWireClass]
RETURNS [mesa: Mesa] = {
bst: BasicSeqType = NARROW[rwc.classData];
mesa ← bst.repAux;
};
BasicSeqInitialize:
PROC [rwt: RoseWireType, p: Ptr, steady:
BOOL] =
TRUSTED {
bst: BasicSeqType = NARROW[rwt.typeData];
ap: ArrPtr = ToArrPtr[p];
PrincOpsUtils.LongZero[LOOPHOLE[ap], bst.wordLength];
steady ← steady;
};
ArrPtr: TYPE = LONG POINTER TO ARRAY NAT OF CARDINAL;
ToArrPtr:
PROC [p: Ptr]
RETURNS [ap: ArrPtr] =
TRUSTED {
ap ← p.word;
IF p.bit # 0 THEN ERROR;
};
BasicSeqTransduce:
PROC [fromS: Strength, fromT, toT: RoseWireType, fromP, toP: Ptr] = {
bst: BasicSeqType = NARROW[fromT.typeData];
IF fromT.class.structure # sequence THEN ERROR;
IF toT.class.structure # sequence THEN ERROR;
IF fromT.length # toT.length THEN ERROR;
IF toT.class.super.flavor # switch THEN ERROR;
IF toT.class.dereference THEN toP ← BitTwiddling.DeReferencePtr[toP];
FOR i:
NAT
IN [0 .. bst.length)
DO
subFrom: Ptr = BitTwiddling.OffsetPtr[fromP, SuboffI[bst, i]];
sel: Selector = [subscript[i]];
subTo: Ptr = BitTwiddling.OffsetPtr[toP, toT.class.super.SelectorOffset[toT, sel]];
RoseTransduce.WriteSwitch[
subTo,
SELECT RoseTransduce.ReadBool[subFrom]
FROM
FALSE => [s: [q: fromS, u: none, d: fromS], val: L],
TRUE => [s: [q: fromS, u: fromS, d: none], val: H],
ENDCASE => ERROR
];
ENDLOOP;
toT ← toT;
};
base2: Format ←
NEW [FormatRep ← [
FormatValue: NumericFormatValue,
ParseValue: NumericParseValue,
MaxWidth: NumericMaxWidth,
formatData: NEW [Base ← R2],
key: "2"]];
base8: Format ←
NEW [FormatRep ← [
FormatValue: NumericFormatValue,
ParseValue: NumericParseValue,
MaxWidth: NumericMaxWidth,
formatData: NEW [Base ← R8],
key: "8"]];
base16: Format ←
NEW [FormatRep ← [
FormatValue: NumericFormatValue,
ParseValue: NumericParseValue,
MaxWidth: NumericMaxWidth,
formatData: NEW [Base ← R16],
key: "16"]];
NumericFormatValue:
PROC [rwt: RoseWireType, f: Format, p: Ptr]
RETURNS [r:
ROPE] = {
bst: BasicSeqType = NARROW[rwt.typeData];
base: REF Base = NARROW[f.formatData];
lgBase: NAT = LgBase[base^];
acc: NAT ← 0;
state: NAT ← 0;
Emit:
PROC = {
r ← Digits[acc].Concat[r];
state ← 0;
};
r ← BaseSuffix[base^];
FOR i:
NAT
DECREASING
IN [0 .. bst.length)
DO
sp: Ptr = BitTwiddling.OffsetPtr[p, SuboffI[bst, i]];
b: [0 .. 1] = IF RoseTransduce.ReadBool[sp] THEN 1 ELSE 0;
acc ← acc*2 + b;
state ← state + 1;
IF state = lgBase OR i = 0 THEN Emit[];
ENDLOOP;
r ← r;
};
NumericParseValue:
PROC [rwt: RoseWireType, f: Format, p: Ptr, s:
STREAM]
RETURNS [ok:
BOOL] =
TRUSTED {
ENABLE IO.Error, IO.EndOfStream => {ok ← FALSE; CONTINUE};
bst: BasicSeqType = NARROW[rwt.typeData];
toke: ROPE ← s.GetTokenRope[WireValBreak].token;
lm1: NAT = toke.Length[]-1;
base: Base =
SELECT toke.Fetch[lm1]
FROM
'B => R2,
'O => R8,
'H => R16,
ENDCASE => ERROR;
bb: NAT = BaseBase[base];
mult: BigCARD = BigCardinals.BigFromSmall[bb];
acc: BigCARD ← BigCardinals.Zero;
ap: ArrPtr = ToArrPtr[p];
FOR i:
NAT
IN [0 .. lm1)
DO
c: CHAR = toke.Fetch[i];
d:
NAT =
SELECT c
FROM
IN ['0 .. '9] => c - '0,
IN ['A .. 'F] => c - 'A + 10,
ENDCASE => ERROR;
IF d >= bb THEN RETURN [FALSE];
acc ← acc.BigMultiply[mult];
acc ← acc.BigAdd[BigCardinals.BigFromSmall[d]];
ENDLOOP;
IF acc.size > bst.wordLength THEN RETURN [FALSE];
FOR i:
NAT
IN [0 .. acc.size)
DO
IF INT[i+1] = acc.size AND acc.contents[i] >= BitTwiddling.TwoToThe[bst.length MOD Basics.bitsPerWord] THEN RETURN [FALSE];
ap[bst.wordLength - 1 - i] ← acc.contents[i];
ENDLOOP;
f ← f;
FOR i:
NAT
IN [acc.size .. bst.wordLength)
DO
ap[bst.wordLength - 1 - i] ← 0;
ENDLOOP;
f ← f;
};
NumericMaxWidth:
PROC [rwt: RoseWireType, fmt: Format, font: VFonts.Font]
RETURNS [max:
INT] = {
bst: BasicSeqType = NARROW[rwt.typeData];
base: REF Base = NARROW[fmt.formatData];
bitsPerDigit: NAT = LgBase[base^];
AddRope:
PROC [r:
ROPE, times:
NAT ← 1] = {
max ← max + Real.Round[times * ImagerFont.RopeWidth[font, r].x];
};
IF bst.maxes[base^].maxWidthFont = font THEN RETURN [bst.maxes[base^].maxWidth];
bst.maxes[base^].maxWidthFont ← font;
max ← 0;
AddRope[BaseSuffix[base^], 1];
AddRope["X", (bst.length + bitsPerDigit-1)/bitsPerDigit];
bst.maxes[base^].maxWidth ← max;
};
END.