-- RopeInline.mesa -- Russ Atkinson, August 30, 1982 1:45 pm DIRECTORY Mopcodes USING [zAND, zBNDCK, zDADD, zLI0, zLI1, zLINB, zLINI, zNEG, zPOP, zRSTRL, zWSTRL], Rope; RopeInline: CEDAR DEFINITIONS IMPORTS Rope SHARES Rope = BEGIN OPEN Mopcodes, Rope; FirstPtr: TYPE = LONG POINTER TO INTEGER; Node: TYPE = REF Node; NodeRep: TYPE = node RopeRep; Ttext: TYPE = text RopeRep; Tsubstr: TYPE = substr node RopeRep; Tconcat: TYPE = concat node RopeRep; Treplace: TYPE = replace node RopeRep; Tobject: TYPE = object node RopeRep; MaxDepth: CARDINAL = 40; Pair: TYPE = MACHINE DEPENDENT RECORD [low: CARDINAL, high: INTEGER]; HighPart: PROC [x: INT] RETURNS [INTEGER] = INLINE {TRUSTED { RETURN [LOOPHOLE[x, Pair].high]}}; LowPart: PROC [x: INT] RETURNS [CARDINAL] = INLINE {TRUSTED { RETURN [LOOPHOLE[x, Pair].low]}}; QShort: PROC [x: INT] RETURNS [CARDINAL] = INLINE {TRUSTED { RETURN [LOOPHOLE[x, Pair].low]}}; RoundToFit: PROC [n: NAT] RETURNS [NAT] = TRUSTED MACHINE CODE { zNEG; zLINB, 370B; zAND; zNEG}; BoundsFault: PROC = TRUSTED MACHINE CODE { zLI1; zLI0; zBNDCK}; NonNeg: PROC [x: INT] RETURNS [INT] = TRUSTED MACHINE CODE { zLINI; zBNDCK;}; Short: PROC [x: INT] RETURNS [CARDINAL] = TRUSTED MACHINE CODE { zLI1; zBNDCK; zPOP; zLINI; zBNDCK;}; CheckLongAdd: PROC [x,y: INT] RETURNS [INT] = TRUSTED MACHINE CODE { zDADD; zLINI; zBNDCK;}; ExtendPositive: PROC [x: INTEGER] RETURNS [INT] = TRUSTED MACHINE CODE { zLI0}; NewText: PROC [size: NAT] RETURNS [Text]; -- here for compatibility, no longer an INLINE InlineFetch: PROC [base: ROPE, index: INT] RETURNS [c: CHAR] = INLINE {TRUSTED { IF base # NIL THEN {first: INTEGER _ LOOPHOLE[base, FirstPtr]^; IF first > 0 AND index < first THEN RETURN [QFetch[LOOPHOLE[base, Text], LowPart[index]]]}; RETURN [Rope.Fetch[base, index]]}}; InlineSize: PROC [base: ROPE] RETURNS [INT] = INLINE {TRUSTED { IF base = NIL THEN RETURN [0]; {first: INTEGER _ LOOPHOLE[base, FirstPtr]^; IF first >= 0 THEN RETURN [ExtendPositive[first]]}; RETURN [LOOPHOLE[base, REF Tobject].size]; }}; IsEmpty: PROC [base: ROPE] RETURNS [BOOL] = INLINE {TRUSTED { IF base = NIL THEN RETURN [TRUE]; {first: INTEGER _ LOOPHOLE[base, FirstPtr]^; IF first >= 0 THEN RETURN [first = 0]}; RETURN [LOOPHOLE[base, REF Tobject].size = 0]; }}; SingleSize: PROC [base: ROPE] RETURNS [INT,Text] = INLINE {TRUSTED { IF base = NIL THEN RETURN [0, NIL]; {first: INTEGER _ LOOPHOLE[base, FirstPtr]^; IF first >= 0 THEN RETURN [ExtendPositive[first], LOOPHOLE[base]]}; RETURN [LOOPHOLE[base, REF Tobject].size, NIL]; }}; DoubleSize: PROC [r1,r2: ROPE] RETURNS [s1: INT, s2: INT, both: BOOL] = INLINE {TRUSTED { t1,t2: Text; [s1,t1] _ SingleSize[r1]; [s2,t2] _ SingleSize[r2]; both _ t1 # NIL AND t2 # NIL; }}; Lower: PROC [c: CHAR] RETURNS [CHAR] = INLINE {RETURN [IF c IN ['A .. 'Z] THEN c+40B ELSE c]}; InlineDepth: PROC [r: ROPE] RETURNS [INTEGER] = INLINE {TRUSTED { IF r = NIL THEN RETURN [0]; WITH r: r SELECT FROM node => WITH x: r SELECT FROM substr => {RETURN [x.depth]}; concat => {RETURN [x.depth]}; replace => {RETURN [x.depth]}; ENDCASE; ENDCASE; RETURN [1]}}; InlineFlatten: PROC [r: ROPE] RETURNS [Text] = INLINE {TRUSTED { IF r = NIL THEN RETURN [NIL]; IF LOOPHOLE[r, FirstPtr]^ >= 0 THEN RETURN [LOOPHOLE[r]]; RETURN [Rope.Flatten[r]]}}; -- the unsafe procs follow QFetch: UNSAFE PROC [base: Text, index: CARDINAL] RETURNS [CHAR] = UNCHECKED MACHINE CODE { -- quick fetch using the index, no NIL or bounds checking zRSTRL, 4}; QStore: UNSAFE PROC [c: CHAR, base: Text, index: CARDINAL] = UNCHECKED MACHINE CODE { -- quick store into string for hack purposes, no NIL or bounds check zWSTRL, 4}; END.