<> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> DIRECTORY Rope USING [ROPE]; TextLooks: CEDAR DEFINITIONS = BEGIN Runs: TYPE = REF RunsBody; Looks: TYPE = PACKED ARRAY Look OF Bit; Look: TYPE = CHAR ['a..'a+31]; -- 32 bits; indexed from "a" Bit: TYPE = BOOL _ FALSE; noLooks: Looks = ALL[FALSE]; allLooks: Looks = ALL[TRUE]; Offset: TYPE = INT; MaxOffset: INT = LAST[INT]; <> CreateRun: PROC [len: INT, looks: Looks _ noLooks] RETURNS [Runs]; FetchLooks: PROC [runs: Runs, index: INT] RETURNS [Looks]; <> CountRuns: PROC [runs: Runs, start, len: INT, limit: INT _ MaxOffset, merge: BOOL _ FALSE, firstLooks: Looks _ noLooks ] RETURNS [count: INT, nonempty: BOOL, lastLooks: Looks]; <> <> <> Size: PROC [base: Runs] RETURNS [size: INT]; <> ChangeLooks: PROC [runs: Runs, size: INT, remove, add: Looks, start: INT _ 0, len: INT _ MaxOffset] RETURNS [Runs]; <> <> Substr: PROC [base: Runs, start: INT, len: INT] RETURNS [Runs]; <> Flatten: PROC [base: Runs] RETURNS [new: Runs]; <> Concat: PROC [base, rest: Runs, baseLen, restLen: INT] RETURNS [Runs]; <> Replace: PROC [base: Runs, start, len: INT, replace: Runs, baseSize, repSize: INT, tryFlat: BOOL _ TRUE] RETURNS [Runs]; <> Copy: PROC [dest: Runs, destLoc: INT, source: Runs, start, len, destSize: INT] RETURNS [Runs]; ReplaceByRun: PROC [dest: Runs, start, len, runLen, destSize: INT, inherit: BOOL, looks: Looks] RETURNS [Runs]; <> <> <> <> <> <> < 0, then looks of previous char,>> <> LooksStats: PROC [base: Runs, start: INT _ 0, len: INT _ MaxOffset] RETURNS [size, pieces, depth: INT]; <> OutOfBounds: ERROR; LooksToRope: PROC [looks: Looks] RETURNS [rope: Rope.ROPE]; RopeToLooks: PROC [rope: Rope.ROPE] RETURNS [looks: Looks]; <> LooksBytes: TYPE = MACHINE DEPENDENT RECORD [ byte0(0:0..7), byte1(0:8..15), byte2(1:0..7), byte3(1:8..15): [0..255] _ 0 ]; RunsBody: TYPE = RECORD [ SELECT tag: * FROM base => [runs: SEQUENCE length: NAT OF Run], node => [ SELECT case: * FROM substr => [size: INT, base: Runs, start: INT], concat => [size: INT, base, rest: Runs, pos: INT], replace => [size: INT, base, replace: Runs, start, oldPos, newPos: INT], change => [size: INT, base: Runs, remove, add: Looks, start, len: INT], ENDCASE ], ENDCASE ]; <> <<>> Run: TYPE = RECORD [after: INT _ 0, looks: Looks _ noLooks]; BaseRuns: TYPE = REF Tbase; Tbase: TYPE = base RunsBody; Tsubstr: TYPE = substr node RunsBody; Tconcat: TYPE = concat node RunsBody; Treplace: TYPE = replace node RunsBody; Tchange: TYPE = change node RunsBody; FlatMax: INT = 10; -- flatten if length of run <= FlatMax END.