-- RopeEdit.mesa
-- written by Bill Paxton, February 1981
-- last edit by Bill Paxton, 17-Jan-82 15:44:31
-- This module provides editing and filing operations for ropes
-- The edit functions are
-- Replace, Delete, Insert, Copy, Move, Transpose
-- ReplaceByChar, InsertChar, AppendChar,
-- ReplaceByString, InsertString, AppendString
-- The filing functions are
-- ToFile[fileName] and ToFileC[fileCapability]
-- FromFile[fileName] and FromFileC[fileCapability]
-- There are also two routines for use with FileByteStreams
-- PutRope[fileByteStream,rope] and GetRope[fileByteStream,length]
-- Finally, there are a few miscellaneous Rope operations
-- Size, Fetch, Flatten
DIRECTORY
Rope,
IOStream,
Mopcodes,
RopeFrom;
RopeEdit: DEFINITIONS
IMPORTS Rope, Mopcodes, RopeFrom
SHARES Rope =
BEGIN OPEN r:Rope, fromI:RopeFrom;
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: ROPE ← NIL,
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];
Move: PROC [base: ROPE, dest, start: Offset ← 0, len, baseSize: Offset ← MaxLen]
RETURNS [ROPE];
-- no-op if dest in [start..start+len]
Transpose: PROC [
base: ROPE, astart, alen, bstart, blen: Offset,
baseSize: Offset ← MaxLen]
RETURNS [ROPE];
-- [astart..astart+alen) must not intersect [bstart..bstart+blen)
BadTranspose: ERROR;
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 { RETURN [
-- string is inserted at loc
-- inserts stringNum chars from string starting with stringStart
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]] };
-- **** Filing Operations ****
ToFile: PROC [fileName, rope: ROPE, start: Offset ← 0];
-- write the rope on the specified file
-- starts writing at given address in file
-- truncates file to end of rope
FromFile: PROC [fileName: ROPE, start: Offset ← 0, len: Offset ← MaxLen,
okToMapFile: BOOLEAN ← FALSE]
RETURNS [ROPE];
-- create rope from the contents of a file
-- starts reading at given start address in file
-- pretends that start+len is the end of the file
-- set okToMapFile to TRUE if you will not want to overwrite the contents later
-- **** IOStream Operations ****
PutRope: PROC [stream: IOStream.Handle, rope: ROPE];
-- does a series of IOStream.PutBlock's
GetRope: PROC [stream: IOStream.Handle, len: Offset ← MaxLen]
RETURNS [rope: ROPE];
-- reads up to len chars from stream (via GetBlock's) and makes a rope
-- **** Miscellaneous Operations
Size: PROC [base: ROPE] RETURNS [Offset] = INLINE { -- copied from RopeInline.Mesa
OPEN Rope;
ExtendPositive: PROC [x: INTEGER] RETURNS [Offset] = MACHINE CODE {Mopcodes.zLI0};
FirstPtr: TYPE = LONG POINTER TO INTEGER;
Tobject: TYPE = object node RopeRep;
first: INTEGER;
IF base = NIL THEN RETURN [0];
IF (first ← LOOPHOLE[base,FirstPtr]↑) >= 0 THEN RETURN [ExtendPositive[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 {
RETURN [fromI.FlatSubstr[rope,0,MaxLen]] };
-- create a flat version of rope
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.