RopeEdit.mesa
written by Bill Paxton, February 1981
Paxton, August 24, 1982 9:53 am
Maxwell, January 5, 1983 11:51 am
Russ Atkinson, July 21, 1983 7:27 pm
This module provides editing operations for ropes.
The edit functions are
Replace, Delete, Insert, Copy
ReplaceByChar, InsertChar, AppendChar,
ReplaceByString, InsertString, AppendString
Finally, there are a few miscellaneous Rope operations
Size, Fetch, Flatten
DIRECTORY
Rope,
RopeFrom;
RopeEdit: CEDAR DEFINITIONS
IMPORTS Rope, RopeFrom
SHARES Rope
= BEGIN
ROPE: TYPE = Rope.ROPE;
Offset: TYPE = INT;
MaxLen: Offset = LAST[Offset];
MaxNat: NAT = LAST[NAT];
**** Editing Operations ****
Substr: PROC [base: ROPE, start: Offset ← 0, len: Offset ← MaxLen] RETURNS [ROPE];
... returns a subrope of the base
Concat: PROC [base, rest: ROPE, baseLen, restLen: Offset ← MaxLen] RETURNS [ROPE];
... returns the concatenation of two ropes
Replace: PROC
[base: ROPE, start: Offset ← 0, len: Offset ← MaxLen, replace: ROPENIL, baseSize, repSize: Offset ← MaxLen]
RETURNS [ROPE];
... returns a new rope with the given range replaced
Delete: PROC [base: ROPE, start, len, baseSize: Offset] RETURNS [ROPE] = INLINE {
RETURN [Replace[base,start,len,NIL,baseSize,0]];
};
Insert: PROC
[dest: ROPE, destLoc: Offset ← 0, source: ROPE, destSize, sourceSize: Offset ← MaxLen]
RETURNS [ROPE] = INLINE {
RETURN [Replace[dest,destLoc,0,source,destSize,sourceSize]];
};
Copy: PROC
[dest: ROPE, destLoc: Offset ← 0, source: ROPE, start: Offset ← 0, len: Offset ← MaxLen, destSize: Offset ← MaxLen] RETURNS [ROPE];
ReplaceByChar: PROC
[base: ROPE, char: CHAR, start: Offset ← 0, len, baseSize: Offset ← MaxLen]
RETURNS [ROPE];
InsertChar: PROC
[base: ROPE, char: CHAR, loc: Offset ← 0, baseSize: Offset ← MaxLen]
RETURNS [ROPE] = INLINE {
RETURN [ReplaceByChar[base,char,loc,0,baseSize]];
};
AppendChar: PROC
[base: ROPE, char: CHAR, baseSize: Offset ← MaxLen] RETURNS [ROPE] = INLINE {
RETURN [ReplaceByChar[base,char,MaxLen,0,baseSize]];
};
AppendByte: PROC
[base: ROPE, x: UNSPECIFIED, baseSize: Offset ← MaxLen] RETURNS [ROPE] = INLINE {
RETURN [AppendChar[base,LOOPHOLE[x,CHAR],baseSize]];
};
String: TYPE = REF READONLY TEXT;
ReplaceByString: PROC
[base: ROPE, string: String, stringStart: NAT ← 0, stringNum: NAT ← MaxNat, start: Offset ← 0, len, baseSize: Offset ← MaxLen]
RETURNS [new: ROPE];
InsertString: PROC
[base: ROPE, string: String, stringStart: NAT ← 0, stringNum: NAT ← MaxNat, loc: Offset ← 0, baseSize: Offset ← MaxLen]
RETURNS [ROPE] = INLINE {
-- string is inserted at loc
-- inserts stringNum chars from string starting with stringStart
RETURN [ReplaceByString[base,string,stringStart,stringNum,loc,0,baseSize]];
};
AppendString: PROC [
base: ROPE, string: String, stringStart:NAT ← 0, stringNum: NAT ← MaxNat, baseSize: Offset ← MaxLen]
RETURNS [ROPE] = INLINE {
RETURN [ReplaceByString[base,string,stringStart,stringNum,MaxLen,0,baseSize]];
};
**** Miscellaneous Operations
Size: PROC [base: ROPE] RETURNS [Offset] = INLINE {
copied from RopeInline.Mesa
FirstPtr: TYPE = LONG POINTER TO CARDINAL;
Tobject: TYPE = object node Rope.RopeRep;
IF base = NIL THEN RETURN [0];
TRUSTED {
first: CARDINAL = LOOPHOLE[base, FirstPtr]^;
IF first < 100000B THEN RETURN [first];
RETURN [LOOPHOLE[base, REF Tobject].size];
};
};
Fetch: PROC [rope: ROPE, index: Offset] RETURNS [CHAR] = INLINE {
RETURN [Rope.Fetch[rope,index]];
};
CountPieces: PROC [rope: ROPE] RETURNS [count: Offset] = INLINE {
[,count,] ← RopeStats[rope];
};
RopeStats: PROC [base: ROPE, start: Offset ← 0, len: Offset ← MaxLen]
RETURNS [size, pieces, depth: Offset];
Flatten: PROC [rope: ROPE] RETURNS [ROPE] = INLINE {
create a flat version of rope
RETURN [RopeFrom.FlatSubstr[rope,0,MaxLen]];
};
SemiFlatten: PROC [base: ROPE] RETURNS [ROPE];
create a version with at most 5 pieces.
avoids copying biggest existing pieces in base
Depth: PROC [rope: ROPE] RETURNS [depth: INTEGER];
***** Character property information
CharProperty: TYPE = {white, alphaNumeric, punctuation, illegal};
CharPropertyTable: TYPE = PACKED ARRAY CHAR OF CharProperty;
charPropertyTable: REF READONLY CharPropertyTable;
WhiteChar, BlankChar: PROC [char: CHAR] RETURNS [BOOLEAN] = INLINE {
Returns TRUE iff char has property=white.
RETURN [charPropertyTable[char] = white];
};
AlphaNumericChar: PROC [char: CHAR] RETURNS [BOOLEAN] = INLINE {
Returns TRUE iff char has property=alphaNumeric.
RETURN [charPropertyTable[char] = alphaNumeric];
};
PunctuationChar: PROC [char: CHAR] RETURNS [BOOLEAN] = INLINE {
Returns TRUE iff char has property=punctuation.
RETURN [charPropertyTable[char] = punctuation];
};
IllegalChar: PROC [char: CHAR] RETURNS [BOOLEAN] = INLINE {
Returns TRUE iff char has property=illegal.
RETURN [charPropertyTable[char] = illegal] };
TestCharProp: PROC [char: CHAR, property: CharProperty] RETURNS [BOOLEAN] = INLINE {
Returns TRUE iff char has property.
RETURN [charPropertyTable[char] = property];
};
GetCharProp: PROC [char: CHAR] RETURNS[property: CharProperty] = INLINE {
Returns property {white, alphaNumeric, punctuation, illegal} for char.
RETURN [charPropertyTable[char]];
};
CR: CHAR = 'M-100B;
TAB: CHAR = 'I-100B;
SP: CHAR = ' ;
UpperCase: PROC [c: CHAR] RETURNS [CHAR] = INLINE {
RETURN [IF c IN ['a..'z] THEN c-40B ELSE c];
};
LowerCase: PROC [c: CHAR] RETURNS [CHAR] = INLINE {
RETURN [IF c IN ['A..'Z] THEN c+40B ELSE c];
};
-- ***** Initialization
Start: PROC; -- for initialization only
END.