RoseVariableSequenceImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Barth, September 5, 1985 6:37:22 pm PDT
Spreitzer, November 18, 1985 10:21:56 pm PST
DIRECTORY Basics, BitTwiddling, Convert, IO, PrincOpsUtils, Real, Rope, RoseBehavior, RoseWireClasses, RoseWireFormats, RoseWireTypes, RoseWireTypeUse, RoseWiring, UnsafeStorage, VFonts;
RoseVariableSequenceImpl:
CEDAR
PROGRAM
IMPORTS BitTwiddling, IO, Rope, RoseWireFormats, RoseWireTypes, RoseWireTypeUse, RoseWiring, UnsafeStorage
EXPORTS RoseWireClasses =
BEGIN OPEN RoseWireTypes;
SwitchVal: TYPE = RoseBehavior.SwitchVal;
Level: TYPE = RoseBehavior.Level;
VblSeqClass: TYPE = REF VblSeqClassRec;
VblSeqClassRec:
TYPE =
RECORD [
rwc: RoseWireClass,
name: ROPE,
repAux: Mesa ← [],
ewc: RoseWireClass,
eltBitSize, stepBits, eltPad: NAT
];
VblSeqType: TYPE = REF VblSeqTypeRec;
VblSeqTypeRec:
TYPE =
RECORD [
vsc: VblSeqClass,
rwt: RoseWireType,
ewt: RoseWireType,
length: NAT,
equivWords: NAT
];
uz: UNCOUNTED ZONE;
GetVariableSequence:
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;
cedarTypeName: ROPE = name.Cat[WireFlavorName[flavor]];
ewc: RoseWireClass = RoseWiring.GetWiring[prototype.elements[0], flavor];
eltBitSize: NAT = ewc.super.Bits[ewc];
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;
vsc: VblSeqClass ←
NEW [VblSeqClassRec ← [
rwc: NIL,
name: cedarTypeName,
ewc: ewc,
eltBitSize: eltBitSize,
stepBits: stepBits,
eltPad: stepBits - eltBitSize
]];
em: Mesa = ewc.super.MesaRepresentation[ewc];
bitBucket: ROPE;
IF StructureOfWire[prototype] # sequence THEN ERROR;
rwtUser.NoteMesa[em];
[bitBucket, moduleRefs] ← rwtUser.DestroyUser[];
IF bitBucket.Length[] # 0 THEN ERROR;
vsc.repAux.directory ← moduleRefs[Directory];
vsc.repAux.imports ← moduleRefs[Import];
IF moduleRefs[Export] # NIL OR moduleRefs[Open] # NIL THEN ERROR;
vsc.repAux.mesa ←
IO.PutFR[
"%g: TYPE = REF %gSeq;
%gSeq: TYPE = RECORD [elts: PACKED SEQUENCE length: NAT OF %g]",
[rope[vsc.name]],
[rope[vsc.name]],
[rope[vsc.name]],
[rope[em.mesa]]
];
vsc.rwc ← rwc ←
NEW[RoseWireClassRec ← [
structure: sequence,
dereference: TRUE,
addressContaining: ewc.dereference OR ewc.addressContaining,
classData: vsc,
super: vblSeqSuperClasses[flavor]]];
};
vblSeqSuperClasses:
ARRAY WireFlavor
OF RoseWireSuperClass ←
ALL[
NIL];
VblSeqGetType:
PROC [rwc: RoseWireClass, wire: Wire]
RETURNS [rwt: RoseWireType] = {
vsc: VblSeqClass = NARROW[rwc.classData];
ewt: RoseWireType = vsc.ewc.super.GetType[vsc.ewc, wire.elements[0]];
length: NAT = wire.elements.size;
eltsPerWord: NAT = Basics.bitsPerWord / vsc.stepBits;
equivWords: NAT = (length + eltsPerWord-1) / eltsPerWord;
vst: VblSeqType =
NEW [VblSeqTypeRec ← [
vsc: vsc,
rwt: rwt ←
NEW[RoseWireTypeRec ← [
class: rwc,
typeData: NIL,
length: length,
other: NIL]],
ewt: ewt,
length: length,
equivWords: equivWords
]];
IF StructureOfWire[wire] # sequence THEN ERROR;
rwt.typeData ← vst;
};
VblSeqListFormats:
PROC [rwt: RoseWireType]
RETURNS [lor:
LOR] = {
lor ← LIST["2", "4", "8", "16", "idiosyncratic"];
};
VblSeqGetFormat:
PROC [rwt: RoseWireType, formatName:
ROPE]
RETURNS [format: Format] = {
basic: BOOL = rwt.class.super.SubClass[rwt.class, [subscript[0]]].structure = atom;
switch: BOOL = rwt.class.super.flavor = switch;
Do:
PROC [lgBase:
NAT]
RETURNS [format: Format] = {
format ←
(
IF NOT basic THEN RoseWireFormats.constructNumericSequence
ELSE IF switch THEN RoseWireFormats.numericBasicSwitchSequence
ELSE RoseWireFormats.numericBasicSimpleSequence)
[lgBase];
};
format ←
SELECT
TRUE
FROM
formatName.Equal["idiosyncratic"] => RoseWireFormats.constructIdiosyncraticSequence,
formatName.Equal["2"] => Do[1],
formatName.Equal["2"] => Do[2],
formatName.Equal["8"] => Do[3],
formatName.Equal["16"], formatName=NIL => Do[4],
ENDCASE => ERROR;
};
VblSeqSelectorOffset:
PROC [rwt: RoseWireType, sel: Selector]
RETURNS [dBits:
NAT] = {
vst: VblSeqType = NARROW[rwt.typeData];
WITH sel
SELECT
FROM
whole => RETURN [0];
field => ERROR;
subscript => RETURN [SuboffI[vst, index]];
ENDCASE => ERROR;
};
Suboff:
PROC [vst: VblSeqType, i:
NAT]
RETURNS [dBits:
NAT] =
{dBits ← SuboffI[vst, i]};
SuboffI:
PROC [vst: VblSeqType, i:
NAT]
RETURNS [dBits:
NAT] =
INLINE {
dBits ← tagBits + vst.vsc.stepBits * i + vst.vsc.eltPad;
};
tagBits: INTEGER ← ComputeTagBits[];
ComputeTagBits:
PROC
RETURNS [delta:
INTEGER] = {
WordSR: TYPE = REF WordSeq;
x: WordSR = NEW [WordSeq[3]];
TRUSTED {delta ← (LOOPHOLE[@x[0], INT] - LOOPHOLE[x, INT]) * Basics.bitsPerWord};
};
WordSP: TYPE = LONG POINTER TO WordSeq;
WordSeq: TYPE = RECORD [elts: SEQUENCE length: NAT OF WORD];
VblSeqSubType:
PROC [rwt: RoseWireType, sel: Selector]
RETURNS [RoseWireType] = {
vst: VblSeqType = NARROW[rwt.typeData];
WITH sel
SELECT
FROM
whole => RETURN [rwt];
field => ERROR;
subscript => RETURN [vst.ewt];
ENDCASE => ERROR;
};
VblSeqSubClass:
PROC [rwc: RoseWireClass, sel: Selector]
RETURNS [RoseWireClass] = {
vsc: VblSeqClass = NARROW[rwc.classData];
WITH sel
SELECT
FROM
whole => RETURN [rwc];
field => ERROR;
subscript => RETURN [vsc.ewc];
ENDCASE => ERROR;
};
VblSeqBits:
PROC [rwc: RoseWireClass]
RETURNS [n:
INT] = {
n ← Basics.bitsPerWord * SIZE[LONG POINTER];
};
VblSeqMesaRepresentation:
PROC [rwc: RoseWireClass]
RETURNS [mesa: Mesa] = {
vsc: VblSeqClass = NARROW[rwc.classData];
mesa ← [mesa: vsc.name];
};
VblSeqMesaRepAux:
PROC [rwc: RoseWireClass]
RETURNS [mesa: Mesa] = {
vsc: VblSeqClass = NARROW[rwc.classData];
mesa ← vsc.repAux;
};
VblSeqReferentRep:
PROC [rwc: RoseWireClass, wireExpr:
ROPE]
RETURNS [mesa:
ROPE] = {
vsc: VblSeqClass = NARROW[rwc.classData];
mesa ←
IO.PutFR["%gSeq[%g.elements.size]",
[rope[vsc.name]],
[rope[wireExpr]]
];
};
VblSeqCreateReferent:
PROC [rwt: RoseWireType]
RETURNS [lp:
LONG
POINTER] =
TRUSTED {
vst: VblSeqType = NARROW[rwt.typeData];
vsc: VblSeqClass = vst.vsc;
wsp: WordSP = uz.NEW[WordSeq[vst.equivWords]];
lp ← wsp;
FOR i: NAT IN [0 .. wsp.length) DO wsp[i] ← 0 ENDLOOP;
rwt ← rwt;
};
VblSeqInitialize:
PROC [rwt: RoseWireType, p: Ptr, steady:
BOOL] = {
vst: VblSeqType = NARROW[rwt.typeData];
vsc: VblSeqClass = vst.vsc;
p ← BitTwiddling.DeReferencePtr[p];
FOR i:
NAT
IN [0 .. vst.length)
DO
vsc.ewc.super.Initialize[
vst.ewt,
BitTwiddling.OffsetPtr[p, SuboffI[vst, i]],
steady
];
ENDLOOP;
steady ← steady;
};
VblSeqTransduce:
PROC [fromS: Strength, fromT, toT: RoseWireType, fromP, toP: Ptr] = {
vst: VblSeqType = NARROW[fromT.typeData];
vsc: VblSeqClass = vst.vsc;
IF fromT.class.structure # sequence THEN ERROR;
IF toT.class.structure # sequence THEN ERROR;
IF fromT.length # toT.length THEN ERROR;
fromP ← BitTwiddling.DeReferencePtr[fromP];
IF toT.class.dereference THEN toP ← BitTwiddling.DeReferencePtr[toP];
FOR i:
NAT
IN [0 .. vst.length)
DO
subFrom: Ptr = BitTwiddling.OffsetPtr[fromP, SuboffI[vst, i]];
sel: Selector = [subscript[i]];
subTo: Ptr = BitTwiddling.OffsetPtr[toP, toT.class.super.SelectorOffset[toT, sel]];
vsc.ewc.super.Transduce[
fromS: fromS,
fromT: vst.ewt,
toT: toT.class.super.SubType[toT, sel],
fromP: subFrom,
toP: subTo];
toT ← toT;
ENDLOOP;
toT ← toT;
};
VblSeqInitQ:
PROC [rwt: RoseWireType, p: Ptr, cap: Strength] =
TRUSTED {
vst: VblSeqType = NARROW[rwt.typeData];
vsc: VblSeqClass = vst.vsc;
p ← BitTwiddling.DeReferencePtr[p];
FOR i:
NAT
IN [0 .. vst.length)
DO
subType: RoseWireType = vst.ewt;
subType.class.super.InitQ[
subType,
BitTwiddling.OffsetPtr[p, SuboffI[vst, i]],
cap];
cap ← cap;
ENDLOOP;
cap ← cap;
};
VblSeqInitUD:
PROC [rwt: RoseWireType, p: Ptr, cap: Strength]
RETURNS [isInput:
BOOL] =
TRUSTED {
vst: VblSeqType = NARROW[rwt.typeData];
vsc: VblSeqClass = vst.vsc;
isInput ← TRUE;
p ← BitTwiddling.DeReferencePtr[p];
FOR i:
NAT
IN [0 .. vst.length)
DO
subType: RoseWireType = vst.ewt;
subInput:
BOOL ← subType.class.super.InitUD[
subType,
BitTwiddling.OffsetPtr[p, SuboffI[vst, i]],
cap];
isInput ← isInput AND subInput;
ENDLOOP;
cap ← cap;
};
VblSeqComputeLevel:
PROC [rwt: RoseWireType, p: Ptr, xPhobic:
BOOL]
RETURNS [delay:
BOOL] =
TRUSTED {
vst: VblSeqType = NARROW[rwt.typeData];
vsc: VblSeqClass = vst.vsc;
delay ← FALSE;
p ← BitTwiddling.DeReferencePtr[p];
FOR i:
NAT
IN [0 .. vst.length)
DO
subType: RoseWireType = vst.ewt;
subDelay:
BOOL ← subType.class.super.ComputeLevel[
subType,
BitTwiddling.OffsetPtr[p, SuboffI[vst, i]],
xPhobic];
delay ← delay OR subDelay;
ENDLOOP;
xPhobic ← xPhobic;
};
Start:
PROC = {
FOR wf: WireFlavor
IN WireFlavor
DO
vblSeqSuperClasses[wf] ←
NEW[RoseWireSuperClassRec ← [
GetType: VblSeqGetType,
ListFormats: VblSeqListFormats,
GetFormat: VblSeqGetFormat,
SelectorOffset: VblSeqSelectorOffset,
SubType: VblSeqSubType,
SubClass: VblSeqSubClass,
Bits: VblSeqBits,
MesaRepresentation: VblSeqMesaRepresentation,
MesaRepAux: VblSeqMesaRepAux,
ReferentRep: VblSeqReferentRep,
CreateReferent: VblSeqCreateReferent,
flavor: wf,
Initialize: VblSeqInitialize,
Transduce: VblSeqTransduce,
InitQ: VblSeqInitQ,
InitUD: VblSeqInitUD,
ComputeLevel: VblSeqComputeLevel
]];
ENDLOOP;
TRUSTED {
uz ← UnsafeStorage.GetSystemUZone[];
};
};
Start[];
END.