<> <> <> <> <> <> DIRECTORY Basics USING [Comparison], PrincOps USING [zLI1, zLI0, zBNDCK], Rope USING [ActionType, Compare, Equal, Find, Map, Match, SkipOver, SkipTo, ROPE, Text]; RefText: CEDAR DEFINITIONS IMPORTS Rope = BEGIN <> <> <> <> <> < s.length THEN BoundsFault ELSE len _ MIN[len, s.length-start].>> <> <> <> <> PureText: TYPE = REF READONLY TEXT; ROPE: TYPE = Rope.ROPE; MaxLen: NAT = NAT.LAST; <> New: PROC[nChars: NAT] RETURNS[REF TEXT]; <> <<>> <> Error: ERROR[ec: ErrorCode]; ErrorCode: TYPE = { clientModifiedReleasedText }; <> ObtainScratch: PROC[nChars: NAT] RETURNS[REF TEXT]; <> <= nChars. This TEXT is generally obtained from a pool of TEXTs.>> <> <> ReleaseScratch: PROC[t: REF TEXT]; <> <> <<>> line: NAT = 100; page: NAT = 512; <> <> Append: PROC[to: REF TEXT, from: PureText, start: NAT _ 0, len: NAT _ MaxLen] RETURNS[REF TEXT]; <> < to.maxLength or length of result text would exceed MaxLen)>> <<>> AppendTextRope: PROC[to: REF TEXT, from: Rope.Text, start: NAT _ 0, len: NAT _ MaxLen] RETURNS[REF TEXT] = INLINE { <> < to.maxLength or length of result text would exceed MaxLen)>> RETURN[Append[to, TrustTextRopeAsText[from], start, len]]; }; AppendRope: PROC[to: REF TEXT, from: ROPE, start: INT _ 0, len: NAT _ MaxLen] RETURNS[REF TEXT]; <> < to.maxLength or length of result text would exceed MaxLen)>> <<>> AppendChar: PROC[to: REF TEXT, from: CHAR] RETURNS[REF TEXT]; <> < to.maxLength or length of result text would exceed MaxLen)>> <<>> InlineAppendChar: PROC[to: REF TEXT, from: CHAR] RETURNS[REF TEXT] = INLINE { <> < to.maxLength or length of result text would exceed MaxLen)>> IF to.length >= to.maxLength THEN RETURN [AppendChar[to, from]]; to[to.length] _ from; to.length _ to.length + 1; RETURN [to]; }; ReserveChars: PROC[to: REF TEXT, nChars: NAT] RETURNS[REF TEXT]; <> <> <> <= to.length + nChars).>> <<>> InlineReserveChars: PROC[to: REF TEXT, nChars: NAT] RETURNS[REF TEXT] = INLINE { <> <> IF LOOPHOLE[to.maxLength, INTEGER]-LOOPHOLE[nChars, INTEGER] < LOOPHOLE[to.length, INTEGER] THEN RETURN [ReserveChars[to, nChars]]; RETURN [to]; }; <<>> <> Compare: PROC[s1, s2: PureText, case: BOOL _ TRUE] RETURNS[Basics.Comparison] = INLINE { <> < case of characters is significant>> RETURN [Rope.Compare[TrustTextAsRope[s1], TrustTextAsRope[s2], case]]; }; Equal: PROC[s1, s2: PureText, case: BOOL _ TRUE] RETURNS[BOOL] = INLINE { <> RETURN [Rope.Equal[TrustTextAsRope[s1], TrustTextAsRope[s2], case]]; }; Fetch: PROC[base: PureText, index: NAT] RETURNS[CHAR] = INLINE { < base.length)>> <> IF base = NIL OR index > base.length THEN BoundsFault[]; RETURN [base[index]]; }; Find: PROC[s1, s2: PureText, pos1: NAT _ 0, case: BOOL _ TRUE] RETURNS[INTEGER] = INLINE { <> <> <= Length[s1])>> RETURN [Rope.Find[TrustTextAsRope[s1], TrustTextAsRope[s2], pos1, case]]; }; Length: PROC[base: PureText] RETURNS[NAT] = INLINE { <> RETURN [IF base = NIL THEN 0 ELSE base.length]; }; ActionType: TYPE = PROC[CHAR] RETURNS[BOOL]; <> Map: PROC[s: PureText, start: NAT _ 0, len: NAT _ MaxLen, action: ActionType] RETURNS[quit: BOOL] = INLINE { < s.length)>> <> <> RETURN [Rope.Map[TrustTextAsRope[s], start, len, action]]; }; Match: PROC[pattern, object: PureText, case: BOOL _ TRUE] RETURNS[BOOL] = INLINE { <> <> RETURN [Rope.Match[TrustTextAsRope[pattern], TrustTextAsRope[object], case]]; }; SkipTo: PROC[s: PureText, pos: NAT _ 0, skip: PureText] RETURNS[NAT] = INLINE { <> RETURN [Rope.SkipTo[TrustTextAsRope[s], pos, TrustTextAsRope[skip]]]; }; SkipOver: PROC[s: PureText, pos: NAT _ 0, skip: PureText] RETURNS[NAT] = INLINE { <> RETURN [Rope.SkipOver[TrustTextAsRope[s], pos, TrustTextAsRope[skip]]]; }; <<>> <> TrustTextAsRope: PROC[text: PureText] RETURNS[Rope.Text] = TRUSTED INLINE { <> <<1. You do NOT alter the text while there is a ROPE reference to the object>> <<2. You do not care about the runtime type of the object>> RETURN [LOOPHOLE[text]]; }; <<>> TrustTextRopeAsText: PROC[rope: Rope.Text] RETURNS[PureText] = TRUSTED INLINE { <> <> RETURN [LOOPHOLE[rope]]; }; BoundsFault: PROC = TRUSTED MACHINE CODE { <> PrincOps.zLI1; PrincOps.zLI0; PrincOps.zBNDCK; }; END.