DIRECTORY AmpersandContext USING[MakeNodeFromNode], CCTypes USING[CCError, CCErrorCase, CreateFrameNodeForSelf], CedarCode USING[ExtractFieldFromNode, GetTypeOfNode, LoadThroughIndirectNode, SelectFieldFromNode, StoreThroughIndirectNode], CirioNubAccess USING[FileEntry, GetConcreteTypecode, GetFileEntry, GetTypestring, Handle, LookupFileEntryByStemName, LookupMatchingSymEntryByName, LookupMatchingSymEntryByValue, LookupSymEntryByName, ReadBytes, Read32BitsAsCard, SymEntry, WriteCardAs32Bits], CirioTypes USING[CirioAddress, CirioAddressBody, CompilerContext, Node, Type], Convert USING[RopeFromCard], IO USING[card, Error, PutChar, PutF, PutFR, PutRope, rope, STREAM], NewAmpersandProcs USING[Handle], PBasics USING[BITAND, BITLSHIFT, BITNOT, BITOR, BITRSHIFT], PFS USING [RopeFromPath], Rope, SystemInterface USING[ShowReport]; NewAmpersandProcsImpl: CEDAR PROGRAM IMPORTS AmpersandContext, CCTypes, CedarCode, CirioNubAccess, Convert, IO, PBasics, PFS, Rope, SystemInterface EXPORTS NewAmpersandProcs = BEGIN CC: TYPE = CirioTypes.CompilerContext; CCE: ERROR[case: CCTypes.CCErrorCase, msg: Rope.ROPE _ NIL] _ CCTypes.CCError; Handle: TYPE = NewAmpersandProcs.Handle; FriendlyFileEntry: TYPE ~ RECORD[ seqNum: CARD, commitPoint: BOOL, fileName: Rope.ROPE, fOffset: CARD, fmagic: CARD, size: CARD, mtime: CARD, smagic: CARD, stamp: Rope.ROPE, readerData: CARD, readerDataSize: CARD, patchReloc: CARD, patchSize: CARD, textReloc: CARD, textSize: CARD, dataReloc: CARD, dataSize: CARD, bssReloc: CARD, bssSize: CARD, commonReloc: CARD, commonSize: CARD]; InstallItems: PUBLIC PROC[ampersandContext: CirioTypes.Node, handle: Handle, cc: CC] = BEGIN indirectFrameForSelf: CirioTypes.Node _ CCTypes.CreateFrameNodeForSelf[cc]; indirectTypeForSelf: CirioTypes.Type _ CedarCode.GetTypeOfNode[indirectFrameForSelf]; indirectArgs: CirioTypes.Node _ CedarCode.SelectFieldFromNode["&args", indirectTypeForSelf, indirectFrameForSelf, cc]; indirectTypeForArgs: CirioTypes.Type _ CedarCode.GetTypeOfNode[indirectArgs]; indirectGlobalFrame: CirioTypes.Node _ CedarCode.ExtractFieldFromNode["&enclosingContext", indirectTypeForSelf, indirectFrameForSelf, cc]; indirectTypeForGlobalFrame: CirioTypes.Type _ CedarCode.GetTypeOfNode[indirectGlobalFrame]; indirectGlobalVars: CirioTypes.Node _ CedarCode.SelectFieldFromNode["&globalVars", indirectTypeForGlobalFrame, indirectGlobalFrame, cc]; indirectTypeForGlobalVars: CirioTypes.Type _ CedarCode.GetTypeOfNode[indirectGlobalVars]; globalVars: CirioTypes.Node _ CedarCode.LoadThroughIndirectNode[indirectTypeForGlobalVars, indirectGlobalVars, cc]; typeForGlobalvars: CirioTypes.Type _ CedarCode.GetTypeOfNode[globalVars]; ampersandContextType: CirioTypes.Type _ CedarCode.GetTypeOfNode[ampersandContext]; InstallAnArg: PROC[name: Rope.ROPE, argItemName: Rope.ROPE] = BEGIN indirect: CirioTypes.Node _ CedarCode.SelectFieldFromNode[argItemName, indirectTypeForArgs, indirectArgs, cc]; indirectType: CirioTypes.Type _ CedarCode.GetTypeOfNode[indirect]; item: CirioTypes.Node _ CedarCode.LoadThroughIndirectNode[indirectType, indirect, cc]; FinishInstall[name, item]; END; InstallAGlobal: PROC[name: Rope.ROPE, globalItemName: Rope.ROPE] = BEGIN <> item: CirioTypes.Node _ CedarCode.ExtractFieldFromNode[globalItemName, typeForGlobalvars, globalVars, cc]; FinishInstall[name, item]; END; FinishInstall: PROC[name: Rope.ROPE, item: CirioTypes.Node] = BEGIN indirectAmpersandNode: CirioTypes.Node _ CedarCode.SelectFieldFromNode[name, ampersandContextType, ampersandContext, cc]; indirectAmpersandType: CirioTypes.Type _ CedarCode.GetTypeOfNode[indirectAmpersandNode]; encapsulatedItem: CirioTypes.Node _ AmpersandContext.MakeNodeFromNode[item, cc]; encapsulatedType: CirioTypes.Type _ CedarCode.GetTypeOfNode[encapsulatedItem]; CedarCode.StoreThroughIndirectNode[encapsulatedType, encapsulatedItem, indirectAmpersandType, indirectAmpersandNode, cc]; END; InstallAnArg["&&H", "handle"]; InstallAGlobal["&TestProc", "TestProc"]; InstallAGlobal["&MemDump", "MemDump"]; InstallAGlobal["&IndirectMemDump", "IndirectMemDump"]; InstallAGlobal["&RdMem", "RdMem"]; InstallAGlobal["&IndirectRdMem", "IndirectRdMem"]; InstallAGlobal["&PokeCard", "PokeCard"]; InstallAGlobal["&dr", "DecimalRead"]; InstallAGlobal["&LookupFileEntryByStemName", "LookupFileEntryByStemName"]; InstallAGlobal["&LookupSymEntryByName", "LookupSymEntryByName"]; InstallAGlobal["&LookupMatchingSymEntryByName", "NubLookupMatchingSymEntryByName"]; InstallAGlobal["&LookupMatchingSymEntryByValue", "NubLookupMatchingSymEntryByValue"]; InstallAGlobal["&GetFileEntry", "GetFileEntry"]; InstallAGlobal["&RdPath", "RdPath"]; InstallAGlobal["&RdRope", "RdRope"]; InstallAGlobal["&RdXString", "RdXString"]; InstallAGlobal["&RdXStringBody", "RdXStringBody"]; InstallAGlobal["&RdRopeDB", "RdRopeDB"]; InstallAGlobal["&MakeLocalRope5", "MakeLocalRope5"]; InstallAGlobal["&MakeLocalRope10", "MakeLocalRope10"]; InstallAGlobal["&LocalRopeConcat", "LocalRopeConcat"]; InstallAGlobal["&LocalRopeCat", "LocalRopeCat"]; InstallAGlobal["&LocalRopeSubstr", "LocalRopeSubstr"]; InstallAGlobal["&GetTypestring", "GetTypestring"]; InstallAGlobal["&GetConcreteTypecode", "GetConcreteTypecode"]; END; TestProc: PROC = BEGIN handle: Handle _ GetHandle[]; IO.PutF[handle.out, "hi, ampersand procs here\N"]; END; Double: PROC [a: Rope.ROPE] RETURNS [Rope.ROPE] ~ {RETURN a.Concat[a]}; AnaRope: PROC [a: Rope.ROPE] RETURNS [len: INT, c0: CHAR] ~ { len _ a.Length[]; c0 _ IF len>0 THEN a.Fetch[0] ELSE '?; RETURN}; rgv1: Rope.ROPE _ "rgv1"; rgv2: Rope.ROPE _ "rgv2!"; BytesPerWord: CARD = 4; DecimalRead: PROC[addr: CARD, count: CARD _ 4] = BEGIN handle: Handle _ GetHandle[]; byteAddr: CARD _ (addr/BytesPerWord)*BytesPerWord; IO.PutF[handle.out, "%g:", IO.card[addr]]; FOR I: CARD IN [0..count) DO word: CARD _ CirioNubAccess.Read32BitsAsCard[[handle.nub, byteAddr, 0, FALSE, TRUE]]; IO.PutF[handle.out, " %g", IO.card[word]]; byteAddr _ byteAddr + BytesPerWord; ENDLOOP; END; hexChars: ARRAY [0 .. 15] OF CHAR = ['0, '1, '2, '3, '4, '5, '6, '7, '8, '9, 'A, 'B, 'C, 'D, 'E, 'F]; RdMem: PROC [addr: CARD, bytes: INTEGER _ 16, base: CARD _ 16] ~ {FullMemDump[addr, bytes, FALSE, base]}; IndirectRdMem: PROC [addr: CARD, bytes: INTEGER _ 16, base: CARD _ 16] ~ {FullMemDump[addr, bytes, TRUE, base]}; MemDump: PROC [addr: CARD, bytes: INTEGER _ 16] ~ {FullMemDump[addr, bytes, FALSE, 16]}; IndirectMemDump: PROC [addr: CARD, bytes: INTEGER _ 16] ~ {FullMemDump[addr, bytes, TRUE, 16]}; FullMemDump: PROC [addr: CARD, bytes: INTEGER, indirect: BOOL, base: CARD] ~ { addr _ (addr/BytesPerWord)*BytesPerWord; {len: CARD ~ CARD[bytes]; afterLast: CARD ~ addr + len; handle: Handle _ GetHandle[]; IF (addr <= CARD[INT.LAST]) # (afterLast <= CARD[INT.LAST]) THEN { IO.PutF[handle.out, "Can't dump across address sign change (%08x + %08x).\n", [cardinal[addr]], [cardinal[len]] ]; RETURN}; IF indirect THEN {ur: CARD ~ addr; addr _ CirioNubAccess.Read32BitsAsCard[[handle.nub, addr, 0, FALSE, TRUE]]; IF (addr MOD BytesPerWord) # 0 THEN { IO.PutF[handle.out, "%08x contains a non-word-aligned pointer (%08x).\n", [cardinal[ur]], [cardinal[addr]] ]; RETURN}; }; IO.PutF[handle.out, "%l", [rope["f"]]]; {ENABLE UNWIND => IO.PutF[handle.out, "%l(dump aborted)\n", [rope["F"]] !IO.Error => CONTINUE]; WHILE bytes>0 DO bytes _ bytes + 3; bytes _ bytes - (bytes MOD 4); SELECT base FROM 8 => IO.PutF[handle.out, "%08x:", [cardinal[addr]]]; 10 =>IO.PutF[handle.out, "%08x:", [cardinal[addr]]]; 16 =>IO.PutF[handle.out, "%08x:", [cardinal[addr]]]; ENDCASE => { IO.PutF[handle.out, "%g is not a valid base. Try 8, 10, or 16.\n", [cardinal[base]]]; RETURN}; {nAsk: NAT ~ MIN[16, bytes]; lb: REF TEXT ~ CirioNubAccess.ReadBytes[[handle.nub, LOOPHOLE[addr], 0, FALSE, TRUE], nAsk]; IF lb.length # nAsk THEN { IO.PutF[handle.out, "%lReadBytes[%08x, %g] returned %g bytes.\n", [rope["F"]], [cardinal[addr]], [integer[nAsk]], [integer[lb.length]] ]; RETURN}; { didVal: BOOLEAN _ FALSE; tmpVal: CARD _ 0; FOR i: NAT IN [0 .. 16] DO IF (i MOD 4)=0 THEN { IF didVal THEN SELECT base FROM 8 => handle.out.PutF["%011bB", [cardinal[tmpVal]]]; 10 => handle.out.PutF["%010dD", [cardinal[tmpVal]]]; 16 => handle.out.PutF["%08xH", [cardinal[tmpVal]]]; ENDCASE => ERROR ELSE IF i # 0 THEN SELECT base FROM 8 => handle.out.PutF[" "]; 10 => handle.out.PutF[" "]; 16 => handle.out.PutF[" "]; ENDCASE => ERROR; tmpVal _ 0; didVal _ FALSE; handle.out.PutChar[' ]; }; IF i=bytes THEN handle.out.PutRope[" "] ELSE SELECT lb[i] FROM <' , >'~ => handle.out.PutChar['.]; ENDCASE => handle.out.PutChar[lb[i]]; ENDLOOP; handle.out.PutRope["\n"]; addr _ addr + 16; bytes _ bytes - 16; }ENDLOOP; }; IO.PutF[handle.out, "%l", [rope["F"]]]}}; PokeCard: PROC [addr, val: CARD, mask: CARD _ 0FFFFFFFFH] ~ { handle: Handle _ GetHandle[]; addr _ (addr/BytesPerWord)*BytesPerWord; {old: CARD ~ CirioNubAccess.Read32BitsAsCard[[handle.nub, addr, 0, FALSE, TRUE]]; maskBar: CARD ~ PBasics.BITNOT[mask]; rem: CARD ~ PBasics.BITAND[old, maskBar]; delt: CARD ~ PBasics.BITAND[val, mask]; new: CARD ~ PBasics.BITOR[rem, delt]; CirioNubAccess.WriteCardAs32Bits[[handle.nub, addr, 0, FALSE, TRUE], new]; RETURN}}; GetTypestring: PROC [code: CARD] RETURNS [string, whyNot: Rope.ROPE] ~ { handle: Handle _ GetHandle[]; [string, whyNot] _ CirioNubAccess.GetTypestring[handle.nub, [code]]; RETURN}; GetConcreteTypecode: PROC [opaque: CARD] RETURNS [concrete: CARD, whyNot: Rope.ROPE] ~ { handle: Handle _ GetHandle[]; [[concrete], whyNot] _ CirioNubAccess.GetConcreteTypecode[handle.nub, [opaque]]; RETURN}; LookupFileEntryByStemName: PROC [stemName: Rope.ROPE, numToSkip: INT] RETURNS [name: Rope.ROPE, type, value, size, fileSeqNum: CARD] ~ { handle: Handle _ GetHandle[]; se: CirioNubAccess.SymEntry _ CirioNubAccess.LookupFileEntryByStemName[handle.nub, stemName, numToSkip]; IF se=NIL THEN RETURN [NIL, 0, 0, 0, 0]; RETURN [se.name, se.type, se.value, se.size, se.fileSeqNum]}; LookupSymEntryByName: PROC [sym: Rope.ROPE, caseSensitive: BOOLEAN, externOnly: BOOLEAN, numToSkip: INT] RETURNS [name: Rope.ROPE, type, value, size, fileSeqNum: CARD] ~ { handle: Handle _ GetHandle[]; se: CirioNubAccess.SymEntry _ CirioNubAccess.LookupSymEntryByName[handle.nub, sym, caseSensitive, externOnly, numToSkip]; IF se=NIL THEN RETURN [NIL, 0, 0, 0, 0]; RETURN [se.name, se.type, se.value, se.size, se.fileSeqNum]}; NubLookupMatchingSymEntryByName: PROC[symID: CARD, pattern: Rope.ROPE, caseSensitive: BOOLEAN, wantedTypes: CARD, ignoreClasses: CARD, numToSkip: INT] RETURNS[CirioNubAccess.SymEntry] = BEGIN handle: Handle _ GetHandle[]; RETURN[CirioNubAccess.LookupMatchingSymEntryByName[handle.nub, symID, pattern, caseSensitive, wantedTypes, ignoreClasses, numToSkip]]; END; NubLookupMatchingSymEntryByValue: PROC[symID: CARD, val: CARD, wantedTypes: CARD, ignoreClasses: CARD, numToSkip: INT] RETURNS[CirioNubAccess.SymEntry] = BEGIN handle: Handle _ GetHandle[]; RETURN[CirioNubAccess.LookupMatchingSymEntryByValue[handle.nub, symID, val, wantedTypes, ignoreClasses, numToSkip]]; END; GetFileEntry: PROC [seqNum: CARD] RETURNS [ffe: REF FriendlyFileEntry _ NIL] ~ { handle: Handle _ GetHandle[]; fe: CirioNubAccess.FileEntry ~ CirioNubAccess.GetFileEntry[handle.nub, seqNum]; IF fe#NIL THEN ffe _ NEW [FriendlyFileEntry _ [ seqNum: fe.seqNum, commitPoint: fe.commitPoint, fileName: PFS.RopeFromPath[fe.fileName], fOffset: fe.fOffset, fmagic: fe.fmagic, size: fe.size, mtime: fe.mtime, smagic: fe.smagic, stamp: fe.stamp, readerData: fe.readerData, readerDataSize: fe.readerDataSize, patchReloc: fe.patchReloc, patchSize: fe.patchSize, textReloc: fe.textReloc, textSize: fe.textSize, dataReloc: fe.dataReloc, dataSize: fe.dataSize, bssReloc: fe.bssReloc, bssSize: fe.bssSize, commonReloc: fe.commonReloc, commonSize: fe.commonSize]]; RETURN}; RdXString: PROC[a: CARD, nChars: CARD _ 100] = BEGIN handle: Handle _ GetHandle[]; xStringVarAddr: CirioTypes.CirioAddress _ CreateLCAFromCard[a, handle.nub]; xStringBodyVarAddr: CirioTypes.CirioAddress _ xStringVarAddr.followPointer[0, xStringVarAddr]; IF xStringBodyVarAddr.asCard[xStringBodyVarAddr] = 0 THEN SystemInterface.ShowReport["XString is NIL, maybe this is an XStringBody.", $urgent]; RdXStringBody[xStringBodyVarAddr.asCard[xStringBodyVarAddr], nChars]; END; RdXStringBody: PROC[a: CARD, nChars: CARD _ 100] = BEGIN handle: Handle _ GetHandle[]; xStringBodyVarAddr: CirioTypes.CirioAddress _ CreateLCAFromCard[a, handle.nub]; rope: Rope.ROPE _ " "; SeeOneChar: PROC[c: CHAR] = {rope _ Rope.Cat[rope, Rope.FromChar[c]]}; GenCharsForXString[xStringBodyVarAddr, 0, nChars, FALSE, SeeOneChar]; SystemInterface.ShowReport[rope, $urgent]; END; GenCharsForXString: PROC[a: CirioTypes.CirioAddress, first: CARD, nChars: CARD, debug: BOOLEAN, for: PROC[CHAR]] = BEGIN suffixSizeF: Field = [0, 16]; homogeneousF: Field = [16, 8]; prefixF: Field = [24, 8]; limitF: Field = [32, 32]; offsetF: Field = [64, 32]; charsF: Field = [96, 32]; siffixSize: CARD _ a.readBits[0, suffixSizeF.offset, suffixSizeF.size, a]; homogeneous: CARD _ a.readBits[0, homogeneousF.offset, homogeneousF.size, a]; prefix: CARD _ a.readBits[0, prefixF.offset, prefixF.size, a]; limit: CARD _ a.readBits[0, limitF.offset, limitF.size, a]; offset: CARD _ a.readBits[0, offsetF.offset, offsetF.size, a]; chars: CARD _ a.readBits[0, charsF.offset, charsF.size, a]; length: CARD _ limit - offset; handle: Handle _ GetHandle[]; b: CirioTypes.CirioAddress _ CreateLCAFromCard[chars + offset, handle.nub]; n: CARD _ IF first >= length THEN 0 ELSE MIN[length-first, nChars]; ShowClient: PROC[c: CHAR] RETURNS[quit: BOOL] = {for[c]; RETURN[FALSE]}; FOR I: CARD IN [0..n) DO byte: CARD _ b.readBits[first + I, 0, 8, b]; for[VAL[BYTE[byte]]]; ENDLOOP; END; RdPath: PROC[a: CARD] = BEGIN handle: Handle _ GetHandle[]; pathVarAddr: CirioTypes.CirioAddress _ CreateLCAFromCard[a, handle.nub]; pathObjAddr: CirioTypes.CirioAddress _ pathVarAddr.followPointer[0, pathVarAddr]; privPathObjAddr: CirioTypes.CirioAddress _ pathObjAddr.followPointer[0, pathObjAddr]; RdRopeMain[privPathObjAddr.asCard[privPathObjAddr] + 4, 500, FALSE]; END; RdRopeMain: PROC[a: CARD, nChars: CARD _ 100, debug: BOOLEAN _ FALSE] = BEGIN handle: Handle _ GetHandle[]; ropeVarAddr: CirioTypes.CirioAddress _ CreateLCAFromCard[a, handle.nub]; rope: Rope.ROPE _ " "; SeeOneChar: PROC[c: CHAR] = {rope _ Rope.Cat[rope, Rope.FromChar[c]]}; GenCharsForRope[ropeVarAddr.followPointer[0, ropeVarAddr], 0, nChars, debug, SeeOneChar]; SystemInterface.ShowReport[rope, $urgent]; END; RdRope: PROC[a: CARD, nChars: CARD _ 100] = { RdRopeMain[a, nChars]; }; RdRopeDB: PROC[a: CARD, nChars: CARD _ 100] = { RdRopeMain[a, nChars, TRUE]; }; MakeLocalRope5: PROC [c1, c2, c3, c4, c5: CHAR _ ' ] RETURNS [Rope.ROPE] ~ { a: ARRAY [1..5] OF CHAR ~ [c1, c2, c3, c4, c5]; i: INT _ 0; GetChar: PROC RETURNS [CHAR] ~ {RETURN [a[i _ i.SUCC]]}; r: Rope.ROPE _ Rope.FromProc[5, GetChar]; RETURN r.Substr[len: r.Index[s2: " "]]}; MakeLocalRope10: PROC [c1, c2, c3, c4, c5, c6, c7, c8, c9, c10: CHAR _ ' ] RETURNS [Rope.ROPE] ~ { a: ARRAY [1..10] OF CHAR ~ [c1, c2, c3, c4, c5, c6, c7, c8, c9, c10]; i: INT _ 0; GetChar: PROC RETURNS [CHAR] ~ {RETURN [a[i _ i.SUCC]]}; r: Rope.ROPE _ Rope.FromProc[10, GetChar]; RETURN r.Substr[len: r.Index[s2: " "]]}; LocalRopeConcat: PROC [base, rest: Rope.ROPE] RETURNS [Rope.ROPE] ~ {RETURN Rope.Concat[base, rest]}; LocalRopeCat: PROC [r1, r2, r3, r4, r5: Rope.ROPE _ NIL] RETURNS [Rope.ROPE] ~ {RETURN Rope.Cat[r1, r2, r3, r4, r5]}; LocalRopeSubstr: PROC [base: Rope.ROPE, start: INT _ 0, len: INT _ INT.LAST] RETURNS [Rope.ROPE] ~ {RETURN Rope.Substr[base, start, len]}; GetHandle: PUBLIC SIGNAL RETURNS[Handle] = CODE; Field: TYPE = RECORD[offset: INT, size: CARD]; GenCharsForRope: PROC[a: CirioTypes.CirioAddress, first: CARD, nChars: CARD, debug: BOOLEAN, for: PROC[CHAR]] = BEGIN tagF: Field = [0, 1]; tag: CARD _ a.readBits[tagF.offset, 0, tagF.size, a]; ShowClient: PROC[c: CHAR] RETURNS[quit: BOOL] = {for[c]; RETURN[FALSE]}; IF debug THEN SystemInterface.ShowReport[IO.PutFR["tag = %g", IO.rope[Convert.RopeFromCard[tag, 16]]], $debug]; SELECT tag FROM 0 => -- we are looking at a text BEGIN lengthF: Field = [1, 15]; maxF: Field = [16, 16]; length: CARD _ a.readBits[0, lengthF.offset, lengthF.size, a]; max: CARD _ a.readBits[0, maxF.offset, maxF.size, a]; n: CARD _ IF first >= length THEN 0 ELSE MIN[length-first, nChars]; FOR I: CARD IN [0..n) DO byte: CARD _ a.readBits[4+first+I, 0, 8, a]; for[VAL[BYTE[byte]]]; ENDLOOP; END; 1 => -- we are looking at a node BEGIN sizeF: Field = [1, 31]; depthF: Field = [32, 30]; casesF: Field = [62, 2]; size: CARD _ a.readBits[0, sizeF.offset, sizeF.size, a]; depth: CARD _ a.readBits[0, depthF.offset, depthF.size, a]; cases: CARD _ a.readBits[0, casesF.offset, casesF.size, a]; n: CARD _ IF first >= size THEN 0 ELSE MIN[size-first, nChars]; IF n > 0 THEN SELECT cases FROM 0 => -- substr BEGIN baseF: Field = [64, 32]; startF: Field = [96, 32]; base: CirioTypes.CirioAddress _ a.followPointer[baseF.offset/8, a]; start: CARD _ a.readBits[0, startF.offset, startF.size, a]; IF debug THEN [] _ Rope.Map[base: "??substr??", action: ShowClient]; GenCharsForRope[base, start, n, debug, for]; END; 1 => -- concat BEGIN baseF: Field = [64, 32]; restF: Field = [96, 32]; posF: Field = [128, 32]; base: CirioTypes.CirioAddress _ a.followPointer[baseF.offset/8, a]; rest: CirioTypes.CirioAddress _ a.followPointer[restF.offset/8, a]; pos: CARD _ a.readBits[0, posF.offset, posF.size, a]; IF debug THEN [] _ Rope.Map[base: "??concat??", action: ShowClient]; IF first < pos THEN BEGIN GenCharsForRope[base, first, MIN[pos-first, n], debug, for]; IF n > pos-first THEN GenCharsForRope[rest, 0, n-pos+first, debug, for]; END ELSE GenCharsForRope[rest, first-pos, n, debug, for]; END; 2 => BEGIN baseF: Field = [64, 32]; replaceF: Field = [96, 32]; startF: Field = [128, 32]; oldPosF: Field = [160, 32]; newPosF: Field = [192, 32]; base: CirioTypes.CirioAddress _ a.followPointer[baseF.offset/8, a]; replace: CirioTypes.CirioAddress _ a.followPointer[replaceF.offset/8, a]; start: CARD _ a.readBits[0, startF.offset, startF.size, a]; oldPos: CARD _ a.readBits[0, oldPosF.offset, oldPosF.size, a]; newPos: CARD _ a.readBits[0, newPosF.offset, newPosF.size, a]; IF debug THEN [] _ Rope.Map[base: "??replace??", action: ShowClient]; IF n > 0 AND first < start THEN BEGIN GenCharsForRope[base, first, MIN[n, start-first], debug, for]; first _ start; n _ n-MIN[n, start-first]; END; IF n > 0 AND first < newPos THEN BEGIN GenCharsForRope[replace, first-start, MIN[n, newPos-first], debug, for]; first _ newPos; n _ n - MIN[n, newPos-first]; END; IF n > 0 AND first < size THEN GenCharsForRope[base, first-newPos+oldPos, n, debug, for]; END; 3 => [] _ Rope.Map[base: "??ObjectRope??", action: ShowClient]; ENDCASE => CCE[cirioError]; END; ENDCASE => CCE[cirioError]; END; CreateLCAFromCard: PROC[addr: CARD, nub: CirioNubAccess.Handle] RETURNS[CirioTypes.CirioAddress] = BEGIN RETURN[NEW[CirioTypes.CirioAddressBody_[ readBits: LCAReadBits, writeBits: LCAWriteBits, followPointer: LCAFollowPointer, asCard: LCAAsCard, data: NEW[LCADataBody _ [nub, addr]]]]]; END; LCAData: TYPE = REF LCADataBody; LCADataBody: TYPE = RECORD[ nub: CirioNubAccess.Handle, byteAddr: CARD]; LCAReadBits: PROC[byteOffset: INT _ 0, bitOffset: INT _ 0, bitSize: CARD, data: CirioTypes.CirioAddress] RETURNS[CARD] = BEGIN lcaData: LCAData _ NARROW[data.data]; fullByteOffset: INT _ byteOffset + bitOffset/8; fullByteAddr: INT _ lcaData.byteAddr+fullByteOffset; cardByteAddr: CARD _ (fullByteAddr/4)*4; remainingBitOffset: INT _ (fullByteAddr MOD 4)*8 + (bitOffset MOD 8); cardVal: CARD _ CirioNubAccess.Read32BitsAsCard[[lcaData.nub, cardByteAddr, 0, FALSE, TRUE]]; RETURN[PBasics.BITRSHIFT[PBasics.BITLSHIFT[cardVal, remainingBitOffset], 32-bitSize]]; END; LCAWriteBits: PROC[byteOffset: INT _ 0, bitOffset: INT _ 0, bitSize: CARD, data: CirioTypes.CirioAddress, bits: CARD] = BEGIN ERROR END; LCAFollowPointer: PROC[byteOffset: INT _ 0, data: CirioTypes.CirioAddress] RETURNS[CirioTypes.CirioAddress] = BEGIN lcaData: LCAData _ NARROW[data.data]; pointer: CARD _ data.readBits[byteOffset, 0, 32, data]; RETURN[CreateLCAFromCard[pointer, lcaData.nub]]; END; LCAAsCard: PROC[data: CirioTypes.CirioAddress] RETURNS[CARD] = BEGIN lcaData: LCAData _ NARROW[data.data]; RETURN[lcaData.byteAddr]; END; END.. ” NewAmpersandProcsImpl.mesa Copyright Σ 1990, 1991, 1992 by Xerox Corporation. All rights reserved. Sturgis, April 3, 1990 11:17 am PDT Spreitze, May 31, 1990 8:55 am PDT Last tweaked by Mike Spreitzer on December 23, 1991 10:19 am PST Laurie Horton, January 28, 1992 2:51 pm PST Philip James, March 6, 1992 11:21 am PST FOR i: NAT IN [0 .. 15] DO IF (i MOD 4)=0 THEN handle.out.PutChar[' ]; IF i>=bytes THEN handle.out.PutRope[" "] ELSE { b: BYTE ~ lb[i].ORD; h: CARDINAL ~ b/16; l: CARDINAL ~ b MOD 16; handle.out.PutChar[hexChars[h]]; handle.out.PutChar[hexChars[l]]}; ENDLOOP; The original version of this procedure took "a: CirioTypes.CirioAddress", which works in the Dorado world, but fails with an internal Cirio error in the Sun world. I should investigate. "a" is intended to be the numerical byte address of a variable of type Rope.ROPE. ropeBodyAddr: CirioTypes.CirioAddress _ a.followPointer[0, a]; ropeBodyContents: CARD _ ropeBodyAddr.readBits[0, 0, 32, ropeBodyAddr]; support The field declarations in the following procedures must agree with Rope.RopeRep in the PCedar world (see [PCedar2.0]Rope.mesa) This procedure assumes that a is the address of a rope body. Local CirioAddress impl (for RdRope, since we can't at the moment define RdRope to take a CirioAddress as an argument, for unknown reasons) only works for fields that do not cross word boundaries adapted from RMTWFrames.UBFReadBits Κu•NewlineDelimiter ™codešœ™K™HKšœ#™#K™"K™@K™+K™(—K˜šΟk ˜ Kšœœ˜)Kšœœ/˜˜NKšœœ˜Kšœœ3œ˜CKšœœ ˜ Kš œœœ œœœ œ˜;Kšœœ˜Kšœ˜Kšœœ ˜"K˜—KšΟnœœœœ@œ œœ˜―˜Kš˜Kšœœ˜&Kšœœ&œœ˜NK˜Kšœœ˜(K˜šœœœ˜!Kšœœ˜ Kšœ œ˜Kšœœ˜Kšœ œ˜Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœ œ˜Kšœ œ˜Kšœœ˜Kšœ œ˜Kšœ œ˜Kšœ œ˜Kšœ œ˜Kšœ œ˜Kšœ œ˜Kšœ œ˜Kšœ œ˜Kšœ œ˜Kšœ œ˜—K˜šž œœœ8œ˜VKš˜KšœK˜KKšœU˜UKšœv˜vKšœN˜NKšœŠ˜ŠKšœ[˜[Kšœˆ˜ˆKšœY˜YKšœs˜sKšœI˜IKšœR˜RK˜šž œœ œœ˜=Kš˜Kšœn˜nKšœB˜BKšœV˜VK˜Kšœ˜Kšœ˜—K˜šžœœ œœ˜BKš˜Kšœ˜KšœD˜DKšœj˜jK˜Kšœ˜Kšœ˜—K˜K˜šž œœ œ˜=Kš˜Kšœy˜yKšœX˜XK˜PK˜NKšœy˜yKšœ˜—K˜K˜Kšœ(˜(Kšœ&˜&Kšœ6˜6Kšœ"˜"Kšœ2˜2Kšœ(˜(Kšœ%˜%KšœJ˜JKšœ@˜@KšœS˜SKšœU˜UKšœ0˜0Kšœ$˜$Kšœ$˜$Kšœ*˜*Kšœ2˜2Kšœ(˜(Kšœ4˜4Kšœ6˜6Kšœ6˜6Kšœ0˜0Kšœ6˜6Kšœ2˜2Kšœ>˜>Kšœ˜—K˜šžœœ˜Kš˜Kšœ˜Kšœ0˜2Kšœ˜—K˜š žœœ œœœ˜/Kšœœ˜—K˜š žœœ œœœœ˜=K˜Kšœœœ œ˜&Kšœ˜—K˜Kšœ œ ˜Kšœ œ ˜K˜Kšž œœ˜šž œœœ œ˜0Kš˜Kšœ˜Kšœ œ$˜2Kšœœ ˜*š œžœœœ ˜Kšœœ=œœ˜UKšœœ ˜*Kšœ#˜#Kšœ˜—Kšœ˜—K˜Kšœ œ œœD˜eK˜š žœœœ œ œ˜>Kšœœ ˜*K˜—š ž œœœ œ œ˜FKšœœ ˜)K˜—šžœœœ œ˜/Kšœœ˜(—K˜šžœœœ œ˜7Kšœœ˜'—K˜š ž œœœ œ œœ˜NKšœ(˜(Kšœœœ˜Kšœ œ˜Kšœ˜šœ œœœœœœœ˜BKšœp˜rKšœ˜—šœ œœ˜"Kšœ=œœ˜Kšœœœ˜%Kšœk˜mKšœ˜—K˜—Kšœ%˜'Kš œœœœ5œ œ˜_šœ ˜K˜K˜šœ˜Kšœœ-˜4Kšœœ-˜4Kšœœ-˜4šœ ˜ KšœT˜VKšœ˜——Kšœœœ ˜Kš œœœ)œ œœ ˜\šœœ˜Kšœ‡˜‰Kšœ˜—Kšœ˜Kšœœœ˜Kšœœ˜šœœœ ˜šœœœ˜šœ˜šœ˜K˜3K˜4K˜3Kšœ˜——šœœ˜šœ˜K˜%K˜%K˜#Kšœœ˜——K˜ Kšœ œ˜Kšœ˜K˜—šœ œœ˜Kšœœ œ˜Kšœœ˜#Kšœ œ˜K˜—šœœ œ˜Kšœ˜—Kšœ˜K˜—šœœœ ™Kšœœœ™+šœ œœ™0Kšœœ œ™Kšœœ™Kšœœœ™K™ K™!—Kšœ™—K˜šœœœ ˜Kšœœœ˜+Kšœ œ˜(šœœ˜K˜#Kšœ˜%—Kšœ˜—K˜K˜K˜Kšœœ˜ —Kšœ˜Kšœ'˜)—K˜šžœœ œœ˜=Kšœ˜Kšœ(˜(Kšœœ9œœ˜QKšœ œ œ˜%Kšœœ œ˜)Kšœœ œ ˜'Kšœœ œ ˜%Kšœ7œœ˜JKšœ˜ —K˜š ž œœœœœ˜HKšœ˜KšœD˜DKšœ˜K˜—š žœœ œœ œœ˜XKšœ˜KšœP˜PKšœ˜K˜—šžœœœ œœ œ!œ˜ˆKšœ˜Kšœh˜hKš œœœœœ˜(Kšœ7˜=—K˜šžœœ œœœ œœ œ!œ˜«Kšœ˜Kšœy˜yKš œœœœœ˜(Kšœ7˜=—K˜šžœœœœœœœ œœ˜ΉKš˜Kšœ˜Kšœ€˜†Kšœ˜—K˜šž œœœœœœ œœ˜™Kš˜Kšœ˜Kšœn˜tKšœ˜—K˜š ž œœ œœœœ˜PKšœ˜KšœO˜Ošœœœœ˜/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™Q—K˜šž œœœ œ ˜.Kš˜Kšœ˜KšœK˜KKšœ^˜^šœ3˜9K˜U—KšœE˜EKšœ˜K˜—šž œœœ œ ˜2Kš˜Kšœ˜KšœO˜OKšœ œœ˜šž œœœ˜K˜*—Kšœ2œ˜EK˜*Kšœ˜K˜—šžœœ$œ œ œœœ˜rKš˜K˜K˜K˜K˜K˜K˜Kšœ œ:˜JKšœ œ<˜MKšœœ2˜>Kšœœ0˜;Kšœœ2˜>Kšœœ0˜;Kšœœ˜K˜K˜K˜KKš œœœœœœ˜Cš ž œœœœœ˜/Kšœ œœ˜—K˜š œžœœœ˜Kšœœ"˜,Kšœœœ ˜Kšœ˜—Kšœ˜K˜—šžœœœ˜Kš˜Kšœ˜KšœH˜HKšœQ˜QKšœU˜UKšœ=œ˜DKšœ˜K˜—š ž œœœ œœœ˜GKš˜Kšœ>™>Kšœœ1™GKšœ˜KšœH˜HKšœ œœ˜šž œœœ˜K˜*—KšœY˜YK˜*Kšœ˜K˜—šžœœœ œ%˜GK˜—š žœœœ œ"œ˜OK˜—š žœœœœœ˜LKšœœœœ˜/Kšœœ˜ Kš žœœœœœ œ˜8Kšœœ˜)Kšœ"˜(—K˜š žœœ+œœœ˜bKšœœ œœ-˜EKšœœ˜ Kš žœœœœœ œ˜8Kšœœ˜*Kšœ"˜(—K˜š žœœœœœ˜AKšœœ˜#—K˜š ž œœœœœœ˜LKšœœ˜(—K˜šžœœ œ œ œœœœœ˜`Kšœœ ˜)—K˜Kšœ™K˜Kš ž œœœœ œ˜0K˜K˜Kš œœœ œœ˜.˜Kšœ„™„—˜Kšœ<™<—šžœœ$œ œ œœœ˜oKš˜K˜Kšœœ,˜5š ž œœœœœ˜/Kšœ œœ˜K˜—Kšœœœœ/˜pšœ˜šœΟc˜ Kš˜K˜K˜Kšœœ2˜>Kšœœ,˜5Kš œœœœœœ˜CK˜š œžœœœ˜Kšœœ"˜,Kšœœœ ˜Kšœ˜—Kšœ˜—šœŸ˜ Kš˜K˜K˜K˜Kšœœ.˜8Kšœœ0˜;Kšœœ0˜;Kš œœœœœœ˜?šœ˜ šœ˜šœŸ ˜Kš˜Kšœ˜Kšœ˜KšœC˜CKšœœ0˜;Kšœœ7˜DK˜,Kšœ˜—šœŸ ˜Kš˜Kšœ˜Kšœ˜Kšœ˜KšœC˜CKšœC˜CKšœœ,˜5Kšœœ7˜Dšœ ˜Kš˜Kšœœ˜K˜Kšœœ˜šœ˜K˜——šœœ˜ Kš˜Kšœ&œ˜HK˜Kšœœ˜Kšœ˜—K˜šœœ˜Kšœ:˜:K˜—Kšœ˜—Kšœ?˜?Kšœœ ˜——Kšœ˜—Kšœœ ˜—Kšœ˜—K˜K˜K˜™‹K˜šžœœœœ˜bKš˜šœœ˜(Kšœ˜Kšœ˜Kšœ ˜ Kšœ˜Kšœœ˜(—Kšœ˜—K˜K˜Kšœ œœ ˜ šœ œœ˜K˜Kšœ œ˜—˜K™7Kšœ#™#—šž œœ œœœ!œœ˜xKš˜Kšœœ ˜%Kšœœ˜/Kšœœ#˜4Kšœœ˜(Kšœœœœ˜EKšœ œBœœ˜]šœ  œ  œ˜HKšœ ˜ —Kšœ˜—K˜š ž œœ œœœ'œ˜wKš˜Kš˜Kšœ˜—K˜šžœœ œ%œ˜mKš˜Kšœœ ˜%Kšœ œ*˜7Kšœ*˜0Kšœ˜—K˜šž œœ œœ˜>Kš˜Kšœœ ˜%Kšœ˜Kšœ˜—K˜—Kšœ˜——…—Q’n›