DIRECTORY Basics, Rope; RopeParts: CEDAR DEFINITIONS IMPORTS Rope = BEGIN RopePart: TYPE ~ RECORD [base: ROPE, start, len: INT]; ROPE: TYPE = Rope.ROPE; nil: RopePart ~ [NIL, 0, 0]; --one of the possible representations of the empty sequence MaxLen: INT ~ Rope.MaxLen; Make: PROC [base: ROPE, start: INT _ 0, len: INT _ MaxLen] RETURNS [RopePart]; InlineMake: PROC [base: ROPE, start: INT _ 0, len: INT _ MaxLen] RETURNS [RopePart] ~ INLINE {limit: INT ~ base.InlineLength[]; IF start>limit THEN RETURN [nil]; RETURN [[base, start, MIN[len, limit-start]]]}; FromChar: PROC [CHAR] RETURNS [RopePart]; ToRope: PROC [RopePart] RETURNS [ROPE]; InlineToRope: PROC [rp: RopePart] RETURNS [ROPE] ~ INLINE {RETURN rp.base.Substr[start: rp.start, len: rp.len]}; Simplify: PROC [rp: RopePart, start, end: BOOL _ TRUE] RETURNS [RopePart]; Cat: PROC [r1, r2, r3, r4, r5: RopePart _ nil] RETURNS [RopePart]; Concat: PROC [base, rest: RopePart _ nil] RETURNS [RopePart]; EasyConcat: PROC [base, rest: RopePart _ nil] RETURNS [BOOL, RopePart]; Compare: PROC [s1, s2: RopePart, case: BOOL _ TRUE] RETURNS [Basics.Comparison]; Equal: PROC [s1, s2: RopePart, case: BOOL _ TRUE] RETURNS [BOOL]; EqualToRope: PROC [s1: RopePart, s2: ROPE, case: BOOL _ TRUE] RETURNS [BOOL]; Fetch: PROC [base: RopePart, index: INT _ 0] RETURNS [c: CHAR]; InlineFetch: PROC [base: RopePart, index: INT] RETURNS [c: CHAR] ~ INLINE {RETURN base.base.InlineFetch[base.start+index]}; Index: PROC [s1, s2: RopePart, pos1: INT _ 0, case: BOOL _ TRUE, clipBeforeSeek: BOOL _ FALSE] RETURNS [INT]; Find: PROC [s1, s2: RopePart, pos1: INT _ 0, case: BOOL _ TRUE, clipBeforeSeek: BOOL _ FALSE] RETURNS [INT]; FindBackward: PROC [s1, s2: RopePart, pos1: INT _ MaxLen, case: BOOL _ TRUE, clipBeforeSeek: BOOL _ FALSE] RETURNS [INT]; IsEmpty: PROC [RopePart] RETURNS [BOOL]; InlineIsEmpty: PROC [r: RopePart] RETURNS [BOOL] ~ INLINE {RETURN[r.len = 0]}; Length: PROC [base: RopePart] RETURNS [INT]; InlineLength: PROC [base: RopePart] RETURNS [INT] ~ INLINE {RETURN[base.len]}; Size: PROC [base: RopePart] RETURNS [INT]; InlineSize: PROC [base: RopePart] RETURNS [INT] ~ INLINE {RETURN[base.len]}; Substr: PROC [base: RopePart, start: INT _ 0, len: INT _ MaxLen] RETURNS [RopePart]; Replace: PROC [base: RopePart, start: INT _ 0, len: INT _ MaxLen, with: RopePart _ nil] RETURNS [RopePart]; ReplaceElt: PROC [base: RopePart, index: INT, with: CHAR] RETURNS [RopePart]; ActionType: TYPE ~ Rope.ActionType; TranslatorType: TYPE ~ Rope.TranslatorType; Run: PROC [s1: RopePart, pos1: INT _ 0, s2: RopePart, pos2: INT _ 0, case: BOOL _ TRUE] RETURNS [INT]; IsPrefix: PROC [prefix, subject: RopePart, case: BOOL _ TRUE] RETURNS [BOOL]; IsSuffix: PROC [suffix, subject: RopePart, case: BOOL _ TRUE] RETURNS [BOOL]; Match: PROC [pattern, object: RopePart, case: BOOL _ TRUE] RETURNS [BOOL]; SkipTo: PROC [s: RopePart, pos: INT _ 0, skip: RopePart] RETURNS [INT]; SkipOver: PROC [s: RopePart, pos: INT _ 0, skip: RopePart] RETURNS [INT]; Map: PROC [base: RopePart, action: ActionType] RETURNS [BOOL]; Translate: PROC [base: RopePart, translator: TranslatorType _ NIL] RETURNS [RopePart]; ToRefText: PROC [base: RopePart] RETURNS [REF TEXT]; AppendChars: PROC [to: REF TEXT, from: RopePart] RETURNS [charsMoved: NAT]; UnsafeMoveChars: UNSAFE PROC [to: Basics.UnsafeBlock, from: RopePart] RETURNS [charsMoved: INT]; Hash: PROC [base: RopePart, case: BOOL _ TRUE, seed: CARDINAL _ defaultSeed] RETURNS [CARDINAL]; defaultSeed: CARDINAL ~ 31415; END. ΚRopeParts.mesa Copyright Σ 1990 by Xerox Corporation. All rights reserved. Last tweaked by Mike Spreitzer on October 5, 1990 7:51:52 am PDT A RopePart represents the same thing as a ROPE: an immutable object containg a sequence of characters, indexed starting at 0 for Length characters. The difference is in the costs of the representation: a RopePart takes 3 times as much stack space, and admits a Substr implementation that does no heap allocation. Many procedures in this interface have the same names and semantics as those in the Rope interface. Part 1: Basic operations and definitions Invariant: 0 <= start <= start+len <= base.Length. No guarantees about what the following procedures do with a broken RopePart. Returns a RopePart that represents the same sequence as Rope.Substr[base, start, len]. start => result.start = 0. end => result.start+result.len = result.base.Length. Returns [TRUE, concatenation] if it can be done without allocating; otherwise, returns [FALSE, nil]. Like Rope.Index. clipBeforeSeek says it would be better to allocate a smaller rope than to search, in s1.base, past the end of the range relevent to s1. Size[base] = Length[base] Part 2: Extended operations and definitions Κ˜codešœ™Kšœ<™K˜—š  œœ/œœ ˜VK˜—š   œœœœœ˜4K˜—š   œœœœœœ˜KK˜—š  œœœ*œœ˜`K˜—š œœœœœœœ˜`Kšœ œ ˜——K˜Kšœ˜—…— Κš