-- TreeEdit.mesa
-- written by Bill Paxton, May 1981
-- last edit by Bill Paxton, 18-Jun-81 11:25:02

-- This package provides editing of trees as used in Tioga

DIRECTORY
TextNode;

TreeEdit: DEFINITIONS =
BEGIN
OPEN nodeI:TextNode;

Ref: TYPE = nodeI.Ref;
RefTextNode: TYPE = nodeI.RefTextNode;
RefOtherNode: TYPE = nodeI.RefOtherNode;
Offset: TYPE = nodeI.Offset;
MaxLen: Offset = LAST[Offset];

-- **** Editing Operations for tree structure ****

	-- in all the following, parameters of the form Xfirst, Xlast require that
	-- Xlast be reachable from Xfirst by 0 or more Next's
	
ReplaceNodes: PROC [destFirst, destLast, sourceFirst, sourceLast: Ref];
	-- replace branches from destFirst to destLast
	-- by copies of branches from sourceFirst to sourceLast

DeleteNodes: PROC [delFirst, delLast: Ref] = INLINE { ReplaceNodes[delFirst,delLast,NIL,NIL] };

DeleteNode: PROC [node: Ref] = INLINE { DeleteNodes[node,node] };
	
CopyNodes: PROC [dest, sourceFirst, sourceLast: Ref, child: BOOLEAN ← TRUE];
	-- copy branches from sourceFirst to sourceLast
	-- if child is true, new branches are inserted before first child of dest
	-- otherwise, new branches become next siblings of dest

CopyNode: PROC [dest, source: Ref, child: BOOLEAN ← TRUE] =
	INLINE { CopyNodes[dest,source,source,child] };

MoveNodes: PROC [dest, moveFirst, moveLast: Ref, child: BOOLEAN ← TRUE];
	-- dest cannot be within source branches
	-- if child is true, moved branches are inserted before first child of dest
	-- otherwise, moved branches become next siblings of dest

MoveNode: PROC [dest, source: Ref, child: BOOLEAN ← TRUE] =
	INLINE { MoveNodes[dest,source,source,child] };

MoveNodesOnto: PROC [destFirst, destLast, moveFirst, moveLast: Ref];
	-- replace destFirst..destLast by moving moveFirst..moveLast onto them
	-- dest cannot be embedded within source
BadMove: ERROR; -- dest was inside source for move

TransposeNodes: PROC [alphaFirst, alphaLast, betaFirst, betaLast: Ref];
	-- alpha and beta must not overlap
BadTranspose: ERROR; -- overlapping spans for transpose

InsertTextNode: PROC [dest: Ref, inherit, child: BOOLEAN ← TRUE] RETURNS [new: RefTextNode];
	-- insert a new text node
	-- if child is true, new node becomes first child of dest
	-- otherwise, new node becomes next sibling of dest
	-- if inherit is true, new gets same typename and stylename as dest
		-- otherwise gets null typename and stylename

InsertOtherNode: PROC [dest: Ref, inherit, child: BOOLEAN ← TRUE] RETURNS [new: RefOtherNode];
	-- same as InsertTextNode, except creates a new "other" node

SplitNode: PROC [node: RefTextNode, textLoc: Offset, inherit, child: BOOLEAN ← TRUE];
	-- split the text node at specified character position
		-- text before the split will remain in the node
	-- other text goes in new node
	-- if child is true, new node becomes first child of node
	-- otherwise, new node becomes next sibling of node
	-- if inherit is true, new gets same typename and stylename as node
		-- otherwise gets null typename and stylename

MergeNodes: PROC [node: RefTextNode];
	-- merge node and its next sibling
	-- sibling must also be a text node
	-- node must be terminal
	-- copies text of node to start of sibling, then deletes


-- **** Operations for creating nodes ****

CreateTextNode: PROC RETURNS [RefTextNode];

CreateOtherNode: PROC RETURNS [RefOtherNode];


-- **** Miscellaneous ****

Relatives: PROC [destFirst, destLast:Ref] RETURNS [destParent, destPrev, destAfter:Ref];

CopySpan: PROC [sourceFirst, sourceLast: Ref] RETURNS [first, last: Ref];

InsideSpan: PROC [node, first, last: Ref] RETURNS [inside: BOOLEAN];
	-- returns true if node is inside the span of branches [first..last]

InsideSiblings: PROC [node,first,last: Ref] RETURNS [inside: BOOLEAN];
	-- returns true if node is inside the span of siblings [first..last]
	-- i.e., Next*[first]=node and Next*[node]=last

OverlappingSpans: PROC [alphaFirst, alphaLast, betaFirst, betaLast: Ref]
	RETURNS [overlap: BOOLEAN];
	-- returns true if branches [alphaFirst..alphaLast] overlap [betaFirst..betaLast]


-- ***** Initialization

Start: PROC; -- for initialization only

END.