<<>> <> <> <> <> DIRECTORY Basics, Basics16, OSMiscOps USING [Copy], Rope USING [Fetch, Length, ROPE, Text, TextRep], SafeStorage USING [GetSystemZone], TargetConversions, TargetConversionsPrivate; TargetConversionsImpl: CEDAR PROGRAM IMPORTS Basics, Basics16, OSMiscOps, Rope, SafeStorage EXPORTS TargetConversions SHARES Rope = BEGIN OPEN TargetConversions, TargetConversionsPrivate; <> <<>> <> <<>> <> <> ByteSequence: TYPE = Rope.ROPE; <> Reader: TYPE = REF ReaderRep; ReaderRep: PUBLIC TYPE = TargetConversionsPrivate.ReaderRep; Writer: TYPE = REF WriterRep; WriterRep: PUBLIC TYPE = TargetConversionsPrivate.WriterRep; Word: TYPE = Bits32; nullWord: Word = LOOPHOLE[LONG[0]]; bytesPerWord: NAT = LAST[ByteLength]; <> z: ZONE ¬ SafeStorage.GetSystemZone[]; <> <> InsufficientBits: PUBLIC ERROR = CODE; <> <<>> InvalidArgument: PUBLIC ERROR = CODE; <> <<>> NotImplemented: PUBLIC ERROR = CODE; <> <<>> NotAligned: PUBLIC ERROR = CODE; <> <<>> <> Card32ToBits32: PROC [c: Card32] RETURNS [Bits32] = INLINE { RETURN [LOOPHOLE[Basics.FFromCard32[c]]]; }; CharToBits32: PROC [c: CHAR] RETURNS [Bits32] = INLINE { RETURN [LOOPHOLE[Bytes[0, 0, 0, c.ORD]]]; }; Int32ToBits32: PROC [i: Int32] RETURNS [Bits32] = INLINE { RETURN [LOOPHOLE[Basics.FFromInt32[i]]]; }; Real32ToBits32: PROC [r: Real32] RETURNS [Bits32] = INLINE { RETURN [LOOPHOLE[Basics.FFromInt32[LOOPHOLE[r]]]]; }; BytesToBits32: PROC [bytes: Bytes] RETURNS [Bits32] = INLINE { RETURN [LOOPHOLE[bytes]]; }; Bits32ToCard32: PROC [b: Bits32] RETURNS [Card32] = INLINE { RETURN [Basics.Card32FromF[LOOPHOLE[b]]]; }; Bits32ToChar: PROC [b: Bits32] RETURNS [CHAR] = INLINE { bytes: Bytes = LOOPHOLE[b]; RETURN [VAL[bytes[0]]]; }; Bits32ToInt32: PROC [b: Bits32] RETURNS [Int32] = INLINE { RETURN [Basics.Int32FromF[LOOPHOLE[b]]]; }; Bits32ToReal32: PROC [b: Bits32] RETURNS [Real32] = INLINE { RETURN [LOOPHOLE[Basics.Int32FromF[LOOPHOLE[b]]]]; }; Bits32ToBytes: PROC [b: Bits32] RETURNS [Bytes] = INLINE { RETURN [LOOPHOLE[b]]; }; CharToByte: PROC [c: CHAR] RETURNS [BYTE] = INLINE { RETURN [ORD[c]]; }; ByteToChar: PROC [b: BYTE] RETURNS [CHAR] = INLINE { RETURN [VAL[b]]; }; <> bank: CARD = 65536; bigEndianOrder: Bytes = LOOPHOLE[(1*bank)+(2*256+3)]; littleEndianOrder: Bytes = LOOPHOLE[(3*256*bank+2*bank)+(1*256)]; princOpsOrder: Bytes = LOOPHOLE[(2*256*bank+3*bank)+(1)]; byteOrder: Bytes = [0, 1, 2, 3]; <> Half: TYPE = PACKED ARRAY [0..bitsPerHalf) OF [0..1]; bitsPerHalf: NAT = bitsPerWord/2; nullHalf: Half = LOOPHOLE[0]; onesHalf: Half = LOOPHOLE[177777B]; Halves: TYPE = PACKED ARRAY [0..1] OF Half; HalfShift: PROC [x: Half, len: INTEGER] RETURNS [Half] = INLINE { RETURN [LOOPHOLE[Basics16.BITSHIFT[LOOPHOLE[x], len]]]; }; HalfAnd: PROC [x,y: Half] RETURNS [Half] = INLINE { RETURN [LOOPHOLE[Basics16.BITAND[LOOPHOLE[x], LOOPHOLE[y]]]]; }; HalfOr: PROC [x,y: Half] RETURNS [Half] = INLINE { RETURN [LOOPHOLE[Basics16.BITOR[LOOPHOLE[x], LOOPHOLE[y]]]]; }; WordAnd: PROC [x,y: Word] RETURNS [Word] = INLINE { RETURN [LOOPHOLE[Basics.BITAND[LOOPHOLE[x], LOOPHOLE[y]]]]; }; WordOr: PROC [x,y: Word] RETURNS [Word] = INLINE { RETURN [LOOPHOLE[Basics.BITOR[LOOPHOLE[x], LOOPHOLE[y]]]]; }; BitOffsetInByte: PROC [bits: INT] RETURNS [[0..7]] = INLINE { RETURN [Basics16.BITAND[7, Basics.LowHalf[LOOPHOLE[bits]]]]; }; BitOffsetInWord: PROC [bits: INT] RETURNS [BitIndex] = INLINE { RETURN [Basics16.BITAND[LAST[BitIndex], Basics.LowHalf[LOOPHOLE[bits]]]]; }; ShiftBitsLeft: PROC [word: Word, shift: BitLength] RETURNS [Word] = --INLINE-- { halves: Halves ¬ LOOPHOLE[word, Halves]; halves[0] ¬ HalfOr[HalfShift[halves[0], shift], HalfShift[halves[1], shift-bitsPerHalf]]; halves[1] ¬ HalfShift[halves[1], shift]; RETURN [LOOPHOLE[halves]]; }; ShiftBitsRight: PROC [word: Word, shift: BitLength] RETURNS [Word] = --INLINE-- { halves: Halves ¬ LOOPHOLE[word, Halves]; halves[1] ¬ HalfOr[HalfShift[halves[1], -shift], HalfShift[halves[0], bitsPerHalf-shift]]; halves[0] ¬ HalfShift[halves[0], -shift]; RETURN [LOOPHOLE[halves]]; }; MaskBitsLeft: PROC [bits32: Word, leftBits: BitLength] RETURNS [Word] = --INLINE-- { halves: Halves ¬ LOOPHOLE[bits32, Halves]; SELECT leftBits FROM <= bitsPerHalf => { halves[0] ¬ HalfAnd[halves[0], HalfShift[onesHalf, bitsPerHalf-leftBits]]; halves[1] ¬ nullHalf; }; < bitsPerWord => halves[1] ¬ HalfAnd[halves[1], HalfShift[onesHalf, bitsPerWord-leftBits]]; ENDCASE; RETURN [LOOPHOLE[halves]]; }; BitsToBytes: PROC [bits: CARD] RETURNS [CARD] = INLINE { RETURN [Basics.BITRSHIFT[bits, 3]]; }; SignCheck: PROC [int: Int32, rightBits: BitLength] = { SELECT rightBits FROM 0 => ERROR InvalidArgument; < bitsPerWord => { limit: Int32 = Bits32ToInt32[ShiftBitsLeft[Int32ToBits32[1], rightBits-1]]; IF int NOT IN [-limit..limit) THEN ERROR InvalidArgument; }; ENDCASE; }; SignExtend: PROC [int: Int32, rightBits: BitLength] RETURNS [Int32] = { <> bits32: Bits32 ¬ Int32ToBits32[int]; SELECT rightBits FROM 0 => ERROR InvalidArgument; < bitsPerWord => { signBitOn: Bits32 ¬ nullBits32; signIndex: BitIndex ¬ bitsPerWord-rightBits; signBitOn[signIndex] ¬ 1; bits32[signIndex] ¬ ORD[NOT VAL[bits32[signIndex]]]; int ¬ Bits32ToInt32[Card32ToBits32[Bits32ToCard32[bits32]-Bits32ToCard32[signBitOn]]]; }; ENDCASE; RETURN [int]; }; EnsureBytes: PROC [writer: Writer, bytes: NAT] RETURNS [REF TEXT] = { buffer: REF TEXT ¬ writer.buffer; bufLen: NAT ¬ bytes; IF bytes > buffer.maxLength THEN TRUSTED { oldLen: NAT ¬ buffer.length; newLen: NAT ¬ IF bytes > LAST[NAT]/2 THEN bytes+256 ELSE bytes*2; new: REF TEXT ¬ z.NEW[TEXT[newLen]]; new.length ¬ bytes; OSMiscOps.Copy[ from: LOOPHOLE[buffer, LONG POINTER] + SIZE[TEXT[0]], nwords: WORDS[TEXT[oldLen]] - WORDS[TEXT[0]], to: LOOPHOLE[new, LONG POINTER] + SIZE[TEXT[0]]]; writer.buffer ¬ buffer ¬ new; }; RETURN [buffer]; }; FlushWriterWord: PROC [writer: Writer] = { IF writer.dirty THEN { word: Bits32 = writer.partialWord; buffer: REF TEXT; bytes: Bytes ¬ Bits32ToBytes[word]; bits: INT ¬ writer.bitPos; offset: BitIndex = BitOffsetInWord[bits]; bPos: CARDINAL; IF offset # 0 THEN bits ¬ bits - offset; bPos ¬ BitsToBytes[bits]; buffer ¬ EnsureBytes[writer, bPos+bytesPerWord]; TRUSTED { OSMiscOps.Copy[ from: @bytes, nwords: WORDS[Bytes], to: LOOPHOLE[buffer, LONG POINTER] + SIZE[TEXT[bPos]]]; }; writer.dirty ¬ FALSE; }; }; AdvanceWriterPos: PROC [writer: Writer, new: INT] = { newOffset: BitIndex ¬ BitOffsetInWord[new]; old: INT ¬ writer.bitPos; oldOffset: BitIndex ¬ BitOffsetInWord[old]; buffer: REF TEXT ¬ writer.buffer; IF new > writer.bitsWritten THEN writer.bitsWritten ¬ new; IF (new-newOffset) # (old-oldOffset) THEN { <> IF writer.dirty THEN FlushWriterWord[writer]; IF new >= writer.bitsWritten THEN { <> bPos: INT ¬ BitsToBytes[new+(bitsPerWord-1)]; buffer ¬ EnsureBytes[writer, bPos]; writer.partialWord ¬ nullWord; buffer.length ¬ bPos; } ELSE { <> bPos: NAT ¬ BitsToBytes[new-newOffset]; bytes: Bytes ¬ nullBytes; TRUSTED { OSMiscOps.Copy[ from: LOOPHOLE[buffer, LONG POINTER] + SIZE[TEXT[bPos]], nwords: WORDS[Bytes], to: @bytes]; }; writer.partialWord ¬ BytesToBits32[bytes]; }; }; writer.bitPos ¬ new; }; PutBits32: PROC [writer: Writer, bits32: Bits32, start: BitIndex, bits: BitLength, mask: BOOL ¬ FALSE] = { <> IF bits # 0 THEN { pos: INT ¬ writer.bitPos; offset: BitIndex ¬ BitOffsetInWord[pos]; rem: NAT ¬ (bitsPerWord-offset); IF start+bits > bitsPerWord THEN ERROR InvalidArgument; IF start # 0 THEN bits32 ¬ ShiftBitsLeft[bits32, start]; IF mask THEN bits32 ¬ MaskBitsLeft[bits32, bits]; IF offset # 0 THEN { <> writer.partialWord ¬ WordOr[writer.partialWord, ShiftBitsRight[bits32, offset]]; writer.dirty ¬ TRUE; bits32 ¬ ShiftBitsLeft[bits32, rem]; IF bits < rem THEN { <> new: INT ¬ writer.bitPos ¬ pos + bits; IF new > writer.bitsWritten THEN writer.bitsWritten ¬ new; RETURN; }; AdvanceWriterPos[writer, pos ¬ pos + rem]; bits ¬ bits - rem; }; IF bits # 0 THEN { <> writer.partialWord ¬ bits32; writer.dirty ¬ TRUE; AdvanceWriterPos[writer, pos ¬ pos + bits]; }; }; }; GetBits32: PROC [reader: Reader, start: BitIndex, len: BitLength] RETURNS [bits32: Bits32 ¬ nullBits32] = { IF len # 0 THEN { offset: BitIndex ¬ BitOffsetInWord[reader.bitsRead]; rem: NAT = bitsPerWord - offset; bitsAvail: INT = reader.bitsLength-reader.bitsRead; index: INT ¬ reader.bytesRead; lastByteIndex: INT ¬ reader.lastByteIndex; IF bitsAvail < len THEN ERROR InsufficientBits; IF start+len > bitsPerWord THEN ERROR InvalidArgument; bits32 ¬ MaskBitsLeft[ShiftBitsLeft[reader.partialWord, offset], len]; <> IF len > rem THEN { <> ReadAhead[reader]; bits32 ¬ WordOr[bits32, ShiftBitsRight[reader.partialWord, len-rem]]; IF start+len # bitsPerWord THEN bits32 ¬ MaskBitsLeft[bits32, len]; }; <> IF start # 0 THEN bits32 ¬ ShiftBitsRight[bits32, start]; reader.bitsRead ¬ reader.bitsRead + len; IF BitOffsetInWord[reader.bitsRead] = 0 THEN ReadAhead[reader]; <> }; }; ReadAhead: PROC [reader: Reader] = { index: INT ¬ reader.bytesRead; lastByteIndex: INT ¬ reader.lastByteIndex; bytes: Bytes ¬ nullBytes; FOR i: ByteIndex IN ByteIndex DO x: INT ¬ index+i; IF x > lastByteIndex THEN EXIT; bytes[i] ¬ CharToByte[Rope.Fetch[reader.buffer, x]]; reader.bytesRead ¬ x+1; ENDLOOP; reader.partialWord ¬ BytesToBits32[bytes]; }; Bits32ToByteSequence: PROC [bits32: Bits32, start: BitIndex, len: BitLength, mask: BOOL ¬ FALSE] RETURNS [ByteSequence ¬ NIL] = { IF start # 0 THEN bits32 ¬ ShiftBitsLeft[bits32, start]; IF mask THEN bits32 ¬ MaskBitsLeft[bits32, len]; IF len # 0 THEN { bytes: Bytes = Bits32ToBytes[bits32]; byteLen: ByteLength = (len+7)/8; new: Rope.Text ¬ z.NEW[Rope.TextRep[byteLen]]; new.length ¬ byteLen; FOR i: NAT IN [0..byteLen) DO new[i] ¬ ByteToChar[bytes[i]]; ENDLOOP; RETURN [new]; }; }; ByteSequenceToBits32: PROC [seq: ByteSequence, start: BitIndex, len: BitLength] RETURNS [bits32: Bits32 ¬ nullBits32] = { bytes: Bytes ¬ nullBytes; byteLen: ByteLength = (len+7)/8; IF byteLen > Rope.Length[seq] THEN ERROR InvalidArgument; FOR i: NAT IN [0..byteLen) DO bytes[i] ¬ CharToByte[Rope.Fetch[seq, i]]; ENDLOOP; bits32 ¬ BytesToBits32[bytes]; SELECT start+len FROM > bitsPerWord => ERROR InvalidArgument; < bitsPerWord => IF len MOD 8 # 0 THEN bits32 ¬ MaskBitsLeft[bits32, len]; ENDCASE; IF start # 0 THEN bits32 ¬ ShiftBitsRight[bits32, start]; }; <> NewWriter: PUBLIC PROC RETURNS [Writer] = { <> RETURN [NEW[WriterRep ¬ [bitsWritten: 0, partialWord: nullWord, dirty: FALSE, buffer: z.NEW[TEXT[16]]]]]; }; ResetWriter: PUBLIC PROC [writer: Writer] = { <> writer.bitsWritten ¬ writer.bitPos ¬ 0; writer.partialWord ¬ nullWord; writer.buffer.length ¬ 0; writer.dirty ¬ FALSE; }; WriterContents: PUBLIC PROC [writer: Writer] RETURNS [ByteSequence ¬ NIL] = { <> nB: NAT = BitsToBytes[writer.bitsWritten+7]; IF writer.dirty THEN FlushWriterWord[writer]; -- force out the partial word IF nB # 0 THEN TRUSTED { overhead: NAT = SIZE[TEXT[0]]; contents: Rope.Text ¬ z.NEW[Rope.TextRep[nB]]; contents.length ¬ nB; OSMiscOps.Copy[ from: LOOPHOLE[writer.buffer, LONG POINTER] + overhead, nwords: WORDS[TEXT[nB]] - WORDS[TEXT[0]], to: LOOPHOLE[contents, LONG POINTER] + overhead]; RETURN [contents]; }; }; BitsWritten: PUBLIC PROC [writer: Writer] RETURNS [INT] = { <> RETURN [writer.bitsWritten]; }; PutBool: PUBLIC PROC [writer: Writer, bool: Bool] = { <> PutBits32[writer, Card32ToBits32[ORD[bool]], bitsPerWord-1, 1]; }; PutByteSeq: PUBLIC PROC [writer: Writer, seq: ByteSequence, len: INT] = { <> IF len > 0 THEN { buffer: REF TEXT = EnsureBytes[writer, len]; offset: BitIndex = BitOffsetInWord[writer.bitsWritten]; IF offset # 0 THEN ERROR NotAligned; FOR i: INT IN [0..len) DO PutBits32[writer, CharToBits32[Rope.Fetch[seq, i]], bitsPerWord-8, 8]; ENDLOOP; }; }; PutCard: PUBLIC PROC [writer: Writer, card: Card32, bits: BitLength] = { <> IF bits # 0 THEN PutBits32[writer, Card32ToBits32[card], bitsPerWord-bits, bits]; }; PutCard32: PUBLIC PROC [writer: Writer, card: Card32] = { <> PutBits32[writer, Card32ToBits32[card], 0, bitsPerWord]; }; PutChar: PUBLIC PROC [writer: Writer, char: Char] = { <> PutBits32[writer, CharToBits32[char], bitsPerWord-8, 8]; }; PutInt: PUBLIC PROC [writer: Writer, int: Int32, bits: BitLength] = { <> SignCheck[int, bits]; PutBits32[writer, Int32ToBits32[int], bitsPerWord-bits, bits]; }; PutInt32: PUBLIC PROC [writer: Writer, int: Int32] = { <> PutBits32[writer, Int32ToBits32[int], 0, bitsPerWord]; }; PutPadBits: PUBLIC PROC [writer: Writer, bits: BitLength] = { <> PutBits32[writer, nullBits32, 0, bits]; }; <<>> PutReal: PUBLIC PROC [writer: Writer, real: Real] = { <> WITH real SELECT FROM real32: real32 Real => PutBits32[writer, Real32ToBits32[real32.real32], 0, bitsPerWord]; ENDCASE => ERROR NotImplemented; }; SetOutputIndex: PUBLIC PROC [writer: Writer, bits: INT] = { <> SELECT TRUE FROM bits < 0 => ERROR InvalidArgument; BitsToBytes[bits] > (LAST[NAT]-20) => ERROR InvalidArgument; ENDCASE; AdvanceWriterPos[writer, bits]; }; GetOutputIndex: PUBLIC PROC [writer: Writer] RETURNS [INT] = { <> RETURN [writer.bitPos]; }; <> NewReader: PUBLIC PROC [seq: ByteSequence, start: INT ¬ 0, len: INT ¬ LAST[INT]] RETURNS [reader: Reader] = { <> reader ¬ z.NEW[ReaderRep]; InitReader[reader, seq, start, len]; }; InitReader: PUBLIC PROC [reader: Reader, seq: ByteSequence, start: INT ¬ 0, len: INT ¬ LAST[INT]] = { <> lim: INT = Rope.Length[seq]; IF start < 0 OR start > lim THEN ERROR InvalidArgument; IF len < 0 THEN len ¬ 0 ELSE len ¬ MIN[len, lim-start]; reader­ ¬ [ bitsRead: 0, bytesRead: start, lastByteIndex: start+len-1, bitsLength: len*8, partialWord: nullWord, buffer: seq]; IF reader.bitsLength # 0 THEN ReadAhead[reader]; }; RemainingBits: PUBLIC PROC [reader: Reader] RETURNS [INT] = { <> RETURN [reader.bitsLength-reader.bitsRead]; }; BitsRead: PUBLIC PROC [reader: Reader] RETURNS [INT] = { <> RETURN [reader.bitsRead]; }; GetBool: PUBLIC PROC [reader: Reader] RETURNS [Bool] = { <> bits32: Bits32 = GetBits32[reader, 0, 1]; RETURN [VAL[bits32[0]]]; }; GetByteSequence: PUBLIC PROC [reader: Reader, len: INT] RETURNS [ByteSequence] = { <> offset: BitIndex ¬ BitOffsetInWord[reader.bitsRead]; IF offset # 0 THEN ERROR NotAligned; IF len > 0 THEN { lim: NAT ¬ len; new: Rope.Text ¬ z.NEW[Rope.TextRep[lim]]; FOR pos: NAT IN [0..lim) DO new[pos] ¬ ByteToChar[Bits32ToBytes[GetBits32[reader, 0, 8]][0]]; ENDLOOP; RETURN [new]; }; RETURN [NIL]; }; GetCard: PUBLIC PROC [reader: Reader, bits: BitLength] RETURNS [Card32 ¬ 0] = { <> IF bits # 0 THEN { bits32: Bits32 = GetBits32[reader, bitsPerWord-bits, bits]; RETURN [Bits32ToCard32[bits32]]; }; }; GetCard32: PUBLIC PROC [reader: Reader] RETURNS [Card32] = { <> RETURN [Bits32ToCard32[GetBits32[reader, 0, bitsPerWord]]]; }; GetChar: PUBLIC PROC [reader: Reader] RETURNS [Char] = { <> RETURN [Bits32ToChar[GetBits32[reader, bitsPerWord-8, 8]]]; }; GetInt: PUBLIC PROC [reader: Reader, bits: BitLength] RETURNS [Int32 ¬ 0] = { <> IF bits = 0 THEN ERROR InvalidArgument; RETURN [SignExtend[Bits32ToInt32[GetBits32[reader, bitsPerWord-bits, bits]], bits]]; }; GetInt32: PUBLIC PROC [reader: Reader] RETURNS [Int32] = { <> RETURN [Bits32ToInt32[GetBits32[reader, 0, bitsPerWord]]]; }; SkipPadBits: PUBLIC PROC [reader: Reader, bits: BitLength] = { <> [] ¬ GetBits32[reader, 0, bits]; }; GetReal: PUBLIC PROC [reader: Reader, kind: RealKind ¬ real32] RETURNS [Real] = { <> IF kind # real32 THEN ERROR NotImplemented; RETURN [[real32[Bits32ToReal32[GetBits32[reader, 0, bitsPerWord]]]]]; }; SetInputIndex: PUBLIC PROC [reader: Reader, bits: INT] = { <> offset: BitIndex; SELECT bits FROM < 0, > reader.bitsLength => ERROR InvalidArgument; ENDCASE; offset ¬ BitOffsetInWord[bits]; IF offset # 0 THEN bits ¬ bits - offset; reader.bytesRead ¬ BitsToBytes[bits]; ReadAhead[reader]; IF offset # 0 THEN [] ¬ GetBits32[reader, 0, offset]; }; <> <> <<{w: Writer _ NewWriter[]; Put&[w, &&]; RESULT[BitStreamToByteSeq[w]]};>> <<>> BoolToByteSeq: PUBLIC PROC [bool: Bool] RETURNS [ByteSequence] = { bits32: Bits32 ¬ nullBits32; bits32[0] ¬ ORD[bool]; RETURN [Bits32ToByteSequence[bits32, 0, 1]]; }; CardToByteSeq: PUBLIC PROC [card: Card32, bits: BitLength] RETURNS [ByteSequence] = { RETURN [Bits32ToByteSequence[Card32ToBits32[card], bitsPerWord-bits, bits]]; }; Card32ToByteSeq: PUBLIC PROC [card: Card32] RETURNS [ByteSequence] = { RETURN [Bits32ToByteSequence[Card32ToBits32[card], 0, bitsPerWord]]; }; CharToByteSeq: PUBLIC PROC [char: Char] RETURNS [ByteSequence] = { bytes: Bytes ¬ nullBytes; bytes[0] ¬ CharToByte[char]; RETURN [Bits32ToByteSequence[BytesToBits32[bytes], 0, 8]]; }; IntToByteSeq: PUBLIC PROC [int: Int32, bits: BitLength] RETURNS [ByteSequence] = { SignCheck[int, bits]; RETURN [Bits32ToByteSequence[Int32ToBits32[int], bitsPerWord-bits, bits]]; }; Int32ToByteSeq: PUBLIC PROC [int: Int32] RETURNS [ByteSequence] = { RETURN [Bits32ToByteSequence[Int32ToBits32[int], 0, bitsPerWord]]; }; RealToByteSeq: PUBLIC PROC [real: Real] RETURNS [ByteSequence] = { WITH real SELECT FROM real32: real32 Real => RETURN [Bits32ToByteSequence[Real32ToBits32[real32.real32], 0, bitsPerWord]]; ENDCASE => ERROR NotImplemented; }; <> <> <> <<>> ByteSeqToBool: PUBLIC PROC [seq: ByteSequence] RETURNS [Bool] = { RETURN [VAL[ByteSequenceToBits32[seq, 0, 1][0]]]; }; ByteSeqToCard: PUBLIC PROC [seq: ByteSequence, bits: BitLength] RETURNS [Card32] = { IF bits = 0 THEN ERROR InvalidArgument; RETURN [Bits32ToCard32[ByteSequenceToBits32[seq, bitsPerWord-bits, bits]]]; }; ByteSeqToCard32: PUBLIC PROC [seq: ByteSequence] RETURNS [Card32] = { RETURN [Bits32ToCard32[ByteSequenceToBits32[seq, 0, bitsPerWord]]]; }; ByteSeqToChar: PUBLIC PROC [seq: ByteSequence] RETURNS [Char] = { RETURN [Bits32ToChar[ByteSequenceToBits32[seq, bitsPerWord-8, 8]]]; }; ByteSeqToInt: PUBLIC PROC [seq: ByteSequence, bits: BitLength] RETURNS [Int32] = { IF bits = 0 THEN ERROR InvalidArgument; RETURN [SignExtend[Bits32ToInt32[ByteSequenceToBits32[seq, bitsPerWord-bits, bits]], bits]]; }; ByteSeqToInt32: PUBLIC PROC [seq: ByteSequence] RETURNS [Int32] = { RETURN [Bits32ToInt32[ByteSequenceToBits32[seq, 0, bitsPerWord]]]; }; ByteSeqToReal: PUBLIC PROC [seq: ByteSequence, kind: RealKind ¬ real32] RETURNS [Real] = { IF kind # real32 THEN ERROR NotImplemented; RETURN [[real32[Bits32ToReal32[ByteSequenceToBits32[seq, 0, bitsPerWord]]]]]; }; END.