-- 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]]}; }.