-- LogInline.mesa
-- Useful procs for manipulating RecordIDs.
-- Last edited by
-- MBrown on January 30, 1984 10:14:00 am PST
DIRECTORY
AlpineEnvironment,
Basics,
Log,
RuntimeError;
LogInline: DEFINITIONS
IMPORTS
Basics,
RuntimeError
= BEGIN
Comparison: TYPE = Basics.Comparison;
RecordID: TYPE = Log.RecordID;
PageNumber: TYPE = AlpineEnvironment.PageNumber;
WordNumber: TYPE = INT;
wordsPerPage: CARDINAL = AlpineEnvironment.wordsPerPage;
logWordsPerPage: CARDINAL = AlpineEnvironment.logWordsPerPage;
RecordID1: TYPE = MACHINE DEPENDENT RECORD [
page0 (0: 0..7): [0..256),
offsetInPage (0: 8..15): [0..AlpineEnvironment.wordsPerPage),
page1 (1: 0..31): LONG CARDINAL];
-- This is one way to decompose a Log.RecordID.
-- Notice that like all long numbers, the least-significant bits come in the first word.
RecordID2: TYPE = MACHINE DEPENDENT RECORD [
lowbits: CARDINAL, highbits: LONG CARDINAL ];
-- Operations on RecordIDs
Compare: PROC [a, b: RecordID] RETURNS [Comparison] = INLINE {
IF a.highBits = b.highBits THEN RETURN [Basics.CompareCard[a.lowBits, b.lowBits]]
ELSE RETURN [Basics.CompareCard[a.highBits, b.highBits]];
};
Min: PROC [a, b: RecordID] RETURNS [RecordID] = INLINE {
RETURN [IF Compare[a, b] = greater THEN b ELSE a];
};
Max: PROC [a, b: RecordID] RETURNS [RecordID] = INLINE {
RETURN [IF Compare[a, b] = less THEN b ELSE a];
};
WordsFromSubtract: PROC [larger, smaller: RecordID] RETURNS [result: INT] = INLINE {
result ← LOOPHOLE[larger.lowBits-smaller.lowBits, INT];
IF (larger.highBits # smaller.highBits AND larger.highBits # smaller.highBits+1)
OR result < 0 THEN ERROR RuntimeError.BoundsFault;
RETURN [result]
};
AddC: PROC [r: RecordID, words: CARDINAL] RETURNS [RecordID] = INLINE {
-- Returns r+c.
low: Basics.LongNumber[num] =
LOOPHOLE[LONG[words] + LONG[LOOPHOLE[r, RecordID2].lowbits]];
high: LONG CARDINAL = LONG[low.highbits] + LOOPHOLE[r, RecordID2].highbits;
RETURN [LOOPHOLE[RecordID2[highbits: high, lowbits: low.lowbits]]];
};
AddLC: PROC [r: RecordID, words: LONG CARDINAL] RETURNS [RecordID] = INLINE {
-- Returns r+words.
low: Basics.LongNumber[num] = LOOPHOLE[
LONG[LOOPHOLE[words, Basics.LongNumber[num]].lowbits] +
LONG[LOOPHOLE[r, RecordID2].lowbits] ];
high: LONG CARDINAL = LONG[low.highbits] +
LONG[LOOPHOLE[words, Basics.LongNumber[num]].highbits] +
LOOPHOLE[r, RecordID2].highbits;
RETURN [LOOPHOLE[RecordID2[highbits: high, lowbits: low.lowbits]]];
};
RecordIDFromWordNumber: PROC [w: WordNumber] RETURNS [RecordID] = INLINE {
RETURN [[lowBits: LOOPHOLE[w], highBits: 0]] };
WordInPageFromRecordID: PROC [r: RecordID] RETURNS [CARDINAL] = INLINE {
RETURN [LOOPHOLE[r, RecordID1].offsetInPage] };
END.
CHANGE LOG
Created by MBrown on September 21, 1982 2:45 pm
Changed by MBrown on September 25, 1982 3:50 pm
-- Moved stuff here from LogCoreImpl: Compare, DecomposeWordNumber, etc.
Changed by MBrown on October 4, 1982 10:19 pm
-- Cedar 3.4: use Environment.Comparison, Inline.CompareCard.
Changed by MBrown on October 25, 1982 10:45 pm
-- Eliminate dependency on LogBasic so that this interface can be made public.
Changed by MBrown on November 9, 1982 3:01 pm
-- Moved page <-> word stuff to AlpineInline.
Changed by MBrown on January 30, 1984 10:11:20 am PST
-- Cedar 5.0: use Basics, RuntimeError.