-- TextLooksSupport.mesa -- written by Bill Paxton, February 1981 -- last edit by Bill Paxton, March 24, 1981 2:27 PM -- Internal support interface for TextLooks DIRECTORY Inline, Mopcodes, TextLooks; TextLooksSupport: DEFINITIONS IMPORTS Inline, Mopcodes SHARES TextLooks = BEGIN OPEN ops:Mopcodes, TextLooks; -- support procedures BaseRun: PROC [x: BaseRuns, index: Card, lower: NAT _ 0, upper: NAT _ LAST[NAT]] RETURNS [NAT]; ExtractRuns: PROC [base: BaseRuns, ref: Runs, start, len: Card, index: NAT _ 0] RETURNS [NAT]; -- value is next index CountRunsAfterChanges: PROC [ref: Runs, start, len: Card, limit: Card _ MaxCard, remove, add: Looks, merge: BOOLEAN _ FALSE, firstLooks: Looks _ noLooks] RETURNS [count: NAT, nonempty: BOOLEAN, lastLooks: Looks]; ExtractRunsAfterChanges: PROC [base: BaseRuns, ref: Runs, remove, add: Looks, start: Card, len: Card, index: NAT _ 0] RETURNS [NAT]; -- value is next index -- inlines TbaseSize: PROC [x: BaseRuns] RETURNS [Card] = INLINE { RETURN [IF x.length=0 THEN 0 ELSE x[x.length-1].after] }; InsertRun: PROC [base: BaseRuns, len: Card, looks: Looks, index: NAT] RETURNS [NAT] = INLINE { -- value is next index IF index=0 THEN { base[0] _ [len, looks]; index _ 1 } ELSE { loc: Card _ base[index-1].after + len; IF base[index-1].looks=looks -- merge runs THEN base[index-1].after _ loc ELSE { base[index] _ [loc, looks]; index _ index+1 }}; RETURN [index]}; NewBase: PROC [runs: Card] RETURNS [BaseRuns]; -- = INLINE { RETURN [NEW[base RunsBody[Short[runs]]]] }; -- can't be an inline until compiler is fixed! FindBaseRuns: PROC [x: BaseRuns, start, len: Card] RETURNS [first, last: NAT] = INLINE { first _ BaseRun[x, start]; last _ IF len>1 THEN BaseRun[x, start+len-1, first] ELSE first }; BaseRunLengths: PROC [x: BaseRuns, start, len: Card, first, last: NAT] RETURNS [firstLen, lastLen: Card] = INLINE { IF first=last THEN RETURN[len,len]; RETURN[x[first].after-start, start+len-x[last-1].after] }; CopyRuns: PROC [to, from: BaseRuns, toLoc, fromLoc, nRuns: NAT] = INLINE { RunsOffset: NAT = SIZE[base RunsBody[0]]; nLeft: NAT; IF nRuns=0 THEN RETURN; IF fromLoc >= from.length OR toLoc >= to.length THEN ERROR; nLeft _ nRuns-1; to[toLoc+nLeft] _ from[fromLoc+nLeft]; -- bounds check Inline.LongCOPY[ from: LOOPHOLE[from,LONG POINTER]+fromLoc*SIZE[Run]+RunsOffset, to: LOOPHOLE[to,LONG POINTER]+toLoc*SIZE[Run]+RunsOffset, nwords: nLeft*SIZE[Run]]}; CARD: PROC [u: UNSPECIFIED] RETURNS [CARDINAL] = INLINE { RETURN [LOOPHOLE[u]] }; LU: PROC [u: Looks] RETURNS [LONG UNSPECIFIED] = INLINE { RETURN [LOOPHOLE[u]] }; ModifyLooks: PROC [old, remove, add: Looks] RETURNS [Looks] = INLINE { -- compute (old & ~remove) v add OPEN Inline; lowbits: CARDINAL _ CARD[BITOR[LowHalf[LU[add]], BITAND[BITNOT[LowHalf[LU[remove]]],LowHalf[LU[old]]]]]; highbits: CARDINAL _ CARD[BITOR[HighHalf[LU[add]], BITAND[BITNOT[HighHalf[LU[remove]]],HighHalf[LU[old]]]]]; looks: num LongNumber _ LongNumber[num[lowbits:lowbits, highbits:highbits]]; RETURN [LOOPHOLE[looks]] }; MergeChanges: PROC [oldrem, oldadd, rem, add: Looks] RETURNS [newrem, newadd: Looks] = INLINE { -- ((lks & ~oldrem) v oldadd) & ~rem) v add == -- lks & ~(oldrem v rem)) v ((oldadd & ~rem) v add -- thus, newrem _ oldrem v rem, newadd _ (oldadd & ~rem) v add OPEN Inline; lowbits: CARDINAL _ CARD[BITOR[LowHalf[LU[oldrem]],LowHalf[LU[rem]]]]; highbits: CARDINAL _ CARD[BITOR[HighHalf[LU[oldrem]],HighHalf[LU[rem]]]]; looks: num LongNumber _ LongNumber[num[lowbits:lowbits, highbits:highbits]]; newrem _ LOOPHOLE[looks]; newadd _ ModifyLooks[oldadd, rem, add]}; -- miscellaneous support routines Pair: TYPE = MACHINE DEPENDENT RECORD [low,high: CARDINAL]; Short: PROC [x: Card] RETURNS [NAT] = MACHINE CODE { -- quick range check and shortening ops.zLI1; ops.zBNDCK; ops.zPOP; ops.zLINI; ops.zBNDCK}; CheckLongSub: PROC [x,y: Card] RETURNS [Card] = MACHINE CODE { ops.zDSUB; ops.zLINI; ops.zBNDCK}; END. (635)