-- BcdStampsImpl.mesa
-- last edit by Satterthwaite, July 30, 1983 11:27 am
DIRECTORY
BcdStamps: TYPE USING [],
CompilerOps: TYPE USING [LetterSwitches],
Environment: TYPE USING [Comparison],
Inline: TYPE USING [LongNumber],
TimeStamp: TYPE USING [Stamp];
BcdStampsImpl: CEDAR PROGRAM EXPORTS BcdStamps ~ {
StampSize: NAT ~ 3;
Stamp: TYPE ~ RECORD [word: ARRAY[0..StampSize) OF WORD];
-- the directoryStamps are in the order of the DIRECTORY clause
-- does not include the stamps for the hidden directory entries
Compute: PUBLIC PROC[
srcCreate: LONG CARDINAL,
switches: CompilerOps.LetterSwitches, compilerVersion: TimeStamp.Stamp,
directoryEnumerator: PROC[PROC[TimeStamp.Stamp]]]
RETURNS[bcdVers: TimeStamp.Stamp] ~ {
stamp: Stamp;
ForEach: PROC[time: TimeStamp.Stamp] ~ {
stamp ← MergeStamps[stamp, TimeToStamp[time]]};
switches['d] ← switches['g] ← switches['p] ← FALSE; -- not part of the version stamp
stamp ← TimeToStamp[[0, 0, srcCreate]];
-- encode switches, compiler version (see DIRECTORY processing also)
stamp ← MergeStamps[stamp, TimeToStamp[[0, 0, LOOPHOLE[switches]]]];
stamp ← MergeStamps[stamp, TimeToStamp[compilerVersion]];
directoryEnumerator[ForEach];
bcdVers ← LOOPHOLE[stamp]};
CompareStamps: PUBLIC PROC[s1, s2: TimeStamp.Stamp] RETURNS[Environment.Comparison] ~ {
RETURN[SELECT s1.time FROM
< s2.time => $less, > s2.time => $greater,
ENDCASE => SELECT s1.host - s2.host FROM -- can't overflow
< 0 => $less, > 0 => $greater,
ENDCASE => SELECT s1.net - s2.net FROM
< 0 => $less, > 0 => $greater, ENDCASE => $equal]
};
MergeStamps: PROC[sum, item: Stamp] RETURNS[Stamp] ~ {
RETURN[AddStamps[RotateStamp[sum], item]]};
AddStamps: PROC[s1, s2: Stamp] RETURNS[sum: Stamp] ~ {
carry: [0..1] ← 0;
i: [0..StampSize);
FOR i DECREASING IN [0..StampSize) DO
t: Inline.LongNumber ~ [lc[s1.word[i].LONG + s2.word[i].LONG + carry.LONG]];
sum.word[i] ← t.lowbits; carry ← t.highbits;
ENDLOOP;
FOR i DECREASING IN [0..StampSize) WHILE carry # 0 DO
t: Inline.LongNumber ~ [lc[sum.word[i].LONG + carry.LONG]];
sum.word[i] ← t.lowbits; carry ← t.highbits;
ENDLOOP};
RotateStamp: PROC[s: Stamp] RETURNS[Stamp] ~ INLINE {RETURN[AddStamps[s, s]]};
TimeToStamp: PROC[time: TimeStamp.Stamp] RETURNS[Stamp] ~ INLINE {
RETURN[LOOPHOLE[time]]};
}.