RoseFixedSequenceImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Barth, September 5, 1985 6:37:22 pm PDT
Spreitzer, October 1, 1985 6:31:31 pm PDT
DIRECTORY Basics, BitTwiddling, Convert, ImagerFont, IO, Real, Rope, RoseBehavior, RoseWireClasses, RoseWireTypes, RoseWireTypeUse, RoseWiring, VFonts;
RoseFixedSequenceImpl:
CEDAR
PROGRAM
IMPORTS BitTwiddling, ImagerFont, IO, Real, Rope, RoseWireTypes, RoseWireTypeUse, RoseWiring
EXPORTS RoseWireClasses, RoseWireTypes =
BEGIN OPEN RoseWireTypes;
SwitchVal: TYPE = RoseBehavior.SwitchVal;
Level: TYPE = RoseBehavior.Level;
FixSeqRep: TYPE = REF FixSeqRec;
FixSeqRec:
TYPE =
RECORD [
rwt: RoseWireType,
name: ROPE,
bitSize, wordSize: NAT,
repAux: Mesa ← [],
vanillaMaxWidth: INT ← 0,
vanillaMaxWidthFont: ImagerFont.Font ← NIL,
ewc: RoseWireClass,
ewt: RoseWireType,
eltBitSize, stepBits, eltPad: NAT,
eltDefaultFormat: Format,
length: NAT];
WireFlavorName:
PUBLIC
ARRAY WireFlavor
OF
ROPE ← [
simple: "Simple",
switch: "Switch",
drive: "Drive"
];
GetFixedSequence:
PUBLIC
PROC [prototype: Wire, flavor: WireFlavor]
RETURNS [rwc: RoseWireClass] = {
name: ROPE = RoseWiring.WireName[prototype];
rwtUser: RoseWireTypeUse.RoseWireTypeUser = RoseWireTypeUse.CreateUser[];
moduleRefs: ARRAY RoseWireTypeUse.ModuleRefType OF LOR;
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]];
eltBitSize: NAT = ewt.class.super.Bits[ewt];
stepBits:
NAT =
SELECT
TRUE
FROM
eltBitSize < 1 => ERROR,
eltBitSize <= 2 => eltBitSize,
eltBitSize <= 4 => 4,
eltBitSize <= 8 => 8,
eltBitSize <= Basics.bitsPerWord => Basics.bitsPerWord,
eltBitSize MOD Basics.bitsPerWord = 0 => eltBitSize,
ENDCASE => ERROR;
eltsPerWord: NAT = Basics.bitsPerWord / stepBits;
bitSize:
NAT =
IF length <= eltsPerWord
THEN length*stepBits
ELSE ((length + eltsPerWord-1) / eltsPerWord) * eltsPerWord * stepBits;
wordSize: NAT = (bitSize + Basics.bitsPerWord-1) / Basics.bitsPerWord;
fsr: FixSeqRep ←
NEW [FixSeqRec ← [
rwt: NIL,
name: cedarTypeName,
bitSize: bitSize,
wordSize: wordSize,
ewc: ewc,
ewt: ewt,
eltBitSize: eltBitSize,
stepBits: stepBits,
eltPad: stepBits - eltBitSize,
eltDefaultFormat: ewc.super.GetFormat[ewt, NIL],
length: length]];
em: Mesa = ewc.super.MesaRepresentation[ewc];
bitBucket: ROPE;
IF prototype.structure # sequence THEN ERROR;
rwtUser.NoteMesa[em];
[bitBucket, moduleRefs] ← rwtUser.DestroyUser[];
IF bitBucket.Length[] # 0 THEN ERROR;
fsr.repAux.directory ← moduleRefs[Directory];
fsr.repAux.imports ← moduleRefs[Import];
IF moduleRefs[Export] # NIL OR moduleRefs[Open] # NIL THEN ERROR;
fsr.repAux.mesa ←
IO.PutFR[
"%g: TYPE = PACKED ARRAY [0 .. %g) OF %g",
[rope[fsr.name]],
[integer[fsr.length]],
[rope[em.mesa]]
];
rwc ←
NEW[RoseWireClassRec ← [
structure: sequence,
dereference: FALSE,
addressContaining: ewc.dereference OR ewc.addressContaining,
classData: fsr,
super: fixSeqSuperClasses[flavor]]];
fsr.rwt ←
NEW[RoseWireTypeRec ← [
class: rwc,
typeData: NIL,
length: fsr.length,
other: NIL]];
};
fixSeqSuperClasses:
ARRAY WireFlavor
OF RoseWireSuperClass ←
ALL[
NIL];
FixSeqGetType:
PROC [rwc: RoseWireClass, wire: Wire]
RETURNS [rwt: RoseWireType] = {
fsr: FixSeqRep = NARROW[rwc.classData];
IF wire.structure # sequence THEN ERROR;
rwt ← fsr.rwt;
};
FixSeqListFormats:
PROC [rwt: RoseWireType]
RETURNS [lor:
LOR] = {
lor ← LIST["vanilla"];
};
FixSeqGetFormat:
PROC [rwt: RoseWireType, formatName:
ROPE]
RETURNS [format: Format] = {
format ←
SELECT
TRUE
FROM
formatName.Equal["vanilla"], formatName=NIL => vanillaFormat,
ENDCASE => ERROR;
};
FixSeqSelectorOffset:
PROC [rwt: RoseWireType, sel: Selector]
RETURNS [dBits:
NAT] = {
fsr: FixSeqRep = NARROW[rwt.class.classData];
WITH sel
SELECT
FROM
whole => RETURN [0];
field => ERROR;
subscript => RETURN [Suboff[fsr, index]];
ENDCASE => ERROR;
};
Suboff:
PROC [fsr: FixSeqRep, i:
NAT]
RETURNS [dBits:
NAT] = {
dBits ← fsr.stepBits * i + fsr.eltPad;
};
FixSeqSubType:
PROC [rwt: RoseWireType, sel: Selector]
RETURNS [RoseWireType] = {
fsr: FixSeqRep = NARROW[rwt.class.classData];
WITH sel
SELECT
FROM
whole => RETURN [rwt];
field => ERROR;
subscript => RETURN [fsr.ewt];
ENDCASE => ERROR;
};
FixSeqSubClass:
PROC [rwc: RoseWireClass, sel: Selector]
RETURNS [RoseWireClass] = {
fsr: FixSeqRep = NARROW[rwc.classData];
WITH sel
SELECT
FROM
whole => RETURN [rwc];
field => ERROR;
subscript => RETURN [fsr.ewc];
ENDCASE => ERROR;
};
FixSeqBits:
PROC [rwt: RoseWireType]
RETURNS [n:
INT] = {
fsr: FixSeqRep = NARROW[rwt.class.classData];
n ← fsr.bitSize;
};
FixSeqMesaRepresentation:
PROC [rwc: RoseWireClass]
RETURNS [mesa: Mesa] = {
fsr: FixSeqRep = NARROW[rwc.classData];
mesa ← [mesa: fsr.name];
};
FixSeqMesaRepAux:
PROC [rwc: RoseWireClass]
RETURNS [mesa: Mesa] = {
fsr: FixSeqRep = NARROW[rwc.classData];
mesa ← fsr.repAux;
};
FixSeqInitialize:
PROC [rwt: RoseWireType, p: Ptr, steady:
BOOL] = {
fsr: FixSeqRep = NARROW[rwt.class.classData];
FOR i:
NAT
IN [0 .. fsr.length)
DO
fsr.ewc.super.Initialize[
fsr.ewt,
BitTwiddling.OffsetPtr[p, Suboff[fsr, i]],
steady
];
ENDLOOP;
steady ← steady;
};
FixSeqTransduce:
PROC [fromS: Strength, fromT, toT: RoseWireType, fromP, toP: Ptr] = {
fsr: FixSeqRep = NARROW[fromT.class.classData];
IF fromT.class.structure # sequence THEN ERROR;
IF toT.class.structure # sequence THEN ERROR;
IF fromT.length # toT.length THEN ERROR;
IF toT.class.dereference THEN toP ← BitTwiddling.DeReferencePtr[toP];
FOR i:
NAT
IN [0 .. fsr.length)
DO
subFrom: Ptr = BitTwiddling.OffsetPtr[fromP, Suboff[fsr, i]];
sel: Selector = [subscript[i]];
subTo: Ptr = BitTwiddling.OffsetPtr[toP, toT.class.super.SelectorOffset[toT, sel]];
fsr.ewc.super.Transduce[
fromS: fromS,
fromT: fsr.ewt,
toT: toT.class.super.SubType[toT, sel],
fromP: subFrom,
toP: subTo];
toT ← toT;
ENDLOOP;
toT ← toT;
};
FixSeqInitQ:
PROC [rwt: RoseWireType, p: Ptr, cap: Strength] =
TRUSTED {
fsr: FixSeqRep = NARROW[rwt.class.classData];
FOR i:
NAT
IN [0 .. fsr.length)
DO
subType: RoseWireType = fsr.ewt;
subType.class.super.InitQ[
subType,
BitTwiddling.OffsetPtr[p, Suboff[fsr, i]],
cap];
cap ← cap;
ENDLOOP;
cap ← cap;
};
FixSeqInitUD:
PROC [rwt: RoseWireType, p: Ptr, cap: Strength]
RETURNS [isInput:
BOOL] =
TRUSTED {
fsr: FixSeqRep = NARROW[rwt.class.classData];
isInput ← TRUE;
FOR i:
NAT
IN [0 .. fsr.length)
DO
subType: RoseWireType = fsr.ewt;
subInput:
BOOL ← subType.class.super.InitUD[
subType,
BitTwiddling.OffsetPtr[p, Suboff[fsr, i]],
cap];
isInput ← isInput AND subInput;
ENDLOOP;
cap ← cap;
};
FixSeqComputeLevel:
PROC [rwt: RoseWireType, p: Ptr, xPhobic:
BOOL]
RETURNS [delay:
BOOL] =
TRUSTED {
fsr: FixSeqRep = NARROW[rwt.class.classData];
delay ← FALSE;
FOR i:
NAT
IN [0 .. fsr.length)
DO
subType: RoseWireType = fsr.ewt;
subDelay:
BOOL ← subType.class.super.ComputeLevel[
subType,
BitTwiddling.OffsetPtr[p, Suboff[fsr, i]],
xPhobic];
delay ← delay OR subDelay;
ENDLOOP;
xPhobic ← xPhobic;
};
vanillaFormat: Format ←
NEW [FormatRep ← [
FormatValue: RecursivelyFormatValue,
ParseValue: RecursivelyParseValue,
MaxWidth: RecursivelyMaxWidth,
key: "vanilla"]];
RecursivelyFormatValue:
PROC [rwt: RoseWireType, f: Format, p: Ptr]
RETURNS [r:
ROPE] = {
fsr: FixSeqRep = NARROW[rwt.class.classData];
to: STREAM = IO.ROS[];
to.PutRope["["];
FOR i:
NAT
IN [0 .. fsr.length)
DO
sf: Format = fsr.eltDefaultFormat;
IF i # 0 THEN to.PutRope[" "];
to.PutRope[sf.FormatValue[
fsr.ewt,
sf,
BitTwiddling.OffsetPtr[p, Suboff[fsr, i]]
]];
ENDLOOP;
to.PutRope["]"];
r ← to.RopeFromROS[];
};
RecursivelyParseValue:
PROC [rwt: RoseWireType, f: Format, p: Ptr, s:
STREAM]
RETURNS [ok:
BOOL] = {
ENABLE IO.Error, IO.EndOfStream => {ok ← FALSE; CONTINUE};
fsr: FixSeqRep = NARROW[rwt.class.classData];
Consume:
PROC [goal:
ROPE] = {
toke: ROPE = s.GetTokenRope[WireValBreak].token;
IF NOT toke.Equal[goal] THEN IO.Error[SyntaxError, s];
};
ok ← TRUE;
Consume["["];
FOR i:
NAT
IN [0 .. fsr.length)
DO
sf: Format = fsr.eltDefaultFormat;
IF i # 0 THEN [] ← s.SkipWhitespace[];
IF
NOT sf.ParseValue[
fsr.ewt,
sf,
BitTwiddling.OffsetPtr[p, Suboff[fsr, i]],
s
]
THEN RETURN [FALSE];
ENDLOOP;
Consume["]"];
};
RecursivelyMaxWidth:
PROC [rwt: RoseWireType, fmt: Format, font: VFonts.Font]
RETURNS [max:
INT] = {
fsr: FixSeqRep = NARROW[rwt.class.classData];
AddRope:
PROC [r:
ROPE, times:
NAT ← 1] = {
max ← max + Real.Round[times * ImagerFont.RopeWidth[font, r].x];
};
IF fsr.vanillaMaxWidthFont = font THEN RETURN [fsr.vanillaMaxWidth];
fsr.vanillaMaxWidthFont ← font;
max ← 0;
AddRope["[]", 1];
AddRope[" ", fsr.length-1];
max ← max + fsr.length * fsr.eltDefaultFormat.MaxWidth[
fsr.ewt,
fsr.eltDefaultFormat,
font
];
fsr.vanillaMaxWidth ← max;
};
Start:
PROC = {
FOR wf: WireFlavor
IN WireFlavor
DO
fixSeqSuperClasses[wf] ←
NEW[RoseWireSuperClassRec ← [
GetType: FixSeqGetType,
ListFormats: FixSeqListFormats,
GetFormat: FixSeqGetFormat,
SelectorOffset: FixSeqSelectorOffset,
SubType: FixSeqSubType,
SubClass: FixSeqSubClass,
Bits: FixSeqBits,
MesaRepresentation: FixSeqMesaRepresentation,
MesaRepAux: FixSeqMesaRepAux,
flavor: wf,
Initialize: FixSeqInitialize,
Transduce: FixSeqTransduce,
InitQ: FixSeqInitQ,
InitUD: FixSeqInitUD,
ComputeLevel: FixSeqComputeLevel
]];
ENDLOOP;
};
Start[];
END.