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. ΆRoseVariableSequenceImpl.mesa Copyright c 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 Κ Α– "cedar" style˜codešœ™Kšœ Οmœ1™Kšžœ,˜0—K˜ —K˜—šœ žœžœž˜KšœT˜TK˜K˜K˜Kšœ#žœ ˜0Kšžœžœ˜—Kšœ˜K˜—š œžœ$žœ žœ˜VKšœžœ˜'šžœžœž˜Kšœ žœ˜Kšœ žœ˜Kšœ žœ˜*Kšžœžœ˜—Kšœ˜K˜—š  œžœžœžœ žœ˜=Kšœ˜—K˜š  œžœžœžœ žœžœ˜GKšœ8˜8K˜—K˜Kšœ žœ˜$K˜š œžœžœ žœ˜1Kšœžœžœ ˜Kšœ žœ˜Kš žœ žœžœžœžœ˜QK˜K˜—Kš œžœžœžœžœ ˜'Kš œ žœžœžœ žœžœžœ˜˜>Kšœ˜KšœS˜Sšœ˜K˜ Kšœ˜Kšœ'˜'K˜Kšœ ˜ —Kšœ ˜ Kšžœ˜—Kšœ ˜ K˜K˜—šΠbn œžœ.žœ˜HKšœžœ˜'Kšœ˜Kšœ#˜#šžœžœžœž˜"Kšœ ˜ ˜K˜Kšœ+˜+K˜—Kšœ ˜ Kšžœ˜—Kšœ ˜ K˜K˜—š ‘ œžœ,žœ žœžœ˜aKšœžœ˜'Kšœ˜Kšœ žœ˜Kšœ#˜#šžœžœžœž˜"Kšœ ˜ šœ žœ˜,K˜Kšœ+˜+K˜—Kšœžœ ˜Kšžœ˜—Kšœ ˜ K˜K˜—š ‘  œžœ&žœžœ žœžœ˜eKšœžœ˜'Kšœ˜Kšœžœ˜Kšœ#˜#šžœžœžœž˜"Kšœ ˜ šœ žœ$˜2K˜Kšœ+˜+Kšœ ˜ —Kšœžœ ˜Kšžœ˜—Kšœ˜K˜K˜—š œžœ˜šžœžœ ž˜#šœžœ˜6Kšœ˜Kšœ˜Kšœ˜Kšœ%˜%Kšœ˜Kšœ˜Kšœ˜Kšœ-˜-Kšœ˜Kšœ˜Kšœ%˜%Kšœ ˜ Kšœ˜Kšœ˜K˜K˜K˜ Kšœ˜—Kšžœ˜—šžœ˜ K˜$K˜—K˜—K˜K˜K˜Kšžœ˜—…—$0