-- NodeAddrs.Mesa
-- written by Paxton. March 1981
-- last written by Paxton. March 20, 1981 2:42 PM
-- **** Persistent addressing for nodes ****
DIRECTORY
CardAddrs,
NodeProps,
TextNode;
NodeAddrs: DEFINITIONS
IMPORTS NodeProps, CardAddrs =
BEGIN
OPEN
nodeI: TextNode,
addrsI: CardAddrs,
propsI: NodeProps;
Card: TYPE = LONG CARDINAL;
Ref: TYPE = nodeI.Ref;
RefTextNode: TYPE = nodeI.RefTextNode;
-- **** Text Addr operations
PutTextAddr: PROC [n: RefTextNode, addr: REF, location: Card] = INLINE {
-- assigns addr to location in node
-- ok if addr was previously assigned elsewhere in the node
addrs: addrsI.Ref;
IF (addrs ← propsI.GetTextAddrs[n]) = NIL THEN
propsI.PutTextAddrs[n, addrs ← addrsI.Create[]];
addrsI.PutAddr[addrs, addr, location] };
RemTextAddr: PROC [n: RefTextNode, addr: REF] = INLINE
-- removes the given addr
{ addrsI.RemAddr[propsI.GetTextAddrs[n], addr] };
GetTextAddr: PROC [n: RefTextNode, addr: REF] RETURNS [location: Card] =
-- generates ERROR addrsI.AddrNotFound if the addr is not in the mapping
INLINE { RETURN [addrsI.GetAddr[propsI.GetTextAddrs[n], addr]] };
TryGetTextAddr: PROC [n: RefTextNode, addr: REF]
RETURNS [found: BOOLEAN, location: Card] = INLINE {
[found, location] ← addrsI.TryGetAddr[propsI.GetTextAddrs[n], addr] };
MapTextAddrs: PROC [n: RefTextNode, action: TextAddrsAction]
RETURNS [BOOLEAN] = INLINE
-- apply the action to each addr&location pair for the node
-- returns true if&when an action returns true
{ RETURN [addrsI.MapAddrs[propsI.GetTextAddrs[n], action]] };
TextAddrsAction: TYPE = addrsI.MapAddrsAction;
-- = PROC [addr: REF, location: Card] RETURNS [BOOLEAN];
-- **** Editing Operations for text addrs ****
Replace: PROC [n: RefTextNode, start, len, newlen: Card] = INLINE
-- replace chars in [start..start+len) by newlen chars
-- addrs that are in the replaced section move to start
-- add (newlen-len) to addrs that are after the replaced section
{ addrsI.Replace[propsI.GetTextAddrs[n], start, len, newlen] };
Insert: PROC [n: RefTextNode, start, length: Card] = INLINE {
-- adds len to addrs at or beyond start
Replace[n, start, 0, length] };
Delete: PROC [n: RefTextNode, start, length: Card] = INLINE {
Replace[n, start, length, 0] };
Move: PROC [n: RefTextNode, dest, start, len: Card] = INLINE
-- dest must not be in [start..start+len)
-- or get ERROR BadMove
{ addrsI.Move[propsI.GetTextAddrs[n], dest, start, len] };
Transpose: PROC [n: RefTextNode, astart, alen, bstart, blen: Card] = INLINE
-- [astart..astart+alen) must not intersect [bstart..bstart+blen)
-- or get ERROR BadTranspose
{ addrsI.Transpose[propsI.GetTextAddrs[n], astart, alen, bstart, blen] };
-- **** Child Addr operations
PutChildAddr: PROC [n: Ref, addr: REF, location: Card] = INLINE {
-- assigns addr to location in node
-- ok if addr was previously assigned elsewhere in the node
addrs: addrsI.Ref;
IF (addrs ← propsI.GetChildAddrs[n]) = NIL THEN
propsI.PutChildAddrs[n, addrs ← addrsI.Create[]];
addrsI.PutAddr[addrs, addr, location] };
RemChildAddr: PROC [n: Ref, addr: REF] = INLINE
-- removes the given addr
{ addrsI.RemAddr[propsI.GetChildAddrs[n], addr] };
GetChildAddr: PROC [n: Ref, addr: REF] RETURNS [location: Card] =
-- generates ERROR addrsI.AddrNotFound if the addr is not in the mapping
INLINE { RETURN [addrsI.GetAddr[propsI.GetChildAddrs[n], addr]] };
TryGetChildAddr: PROC [n: Ref, addr: REF]
RETURNS [found: BOOLEAN, location: Card] = INLINE {
[found, location] ← addrsI.TryGetAddr[propsI.GetChildAddrs[n], addr] };
FollowChildAddrs: PROC [node: Ref, addr: REF] RETURNS [Ref];
MapChildAddrs: PROC [n: Ref, action: ChildAddrsAction]
RETURNS [BOOLEAN] = INLINE
-- apply the action to each addr&location pair for the node
-- returns true if&when an action returns true
{ RETURN [addrsI.MapAddrs[propsI.GetChildAddrs[n], action]] };
ChildAddrsAction: TYPE = addrsI.MapAddrsAction;
-- = PROC [addr: REF, location: Card] RETURNS [BOOLEAN];
-- **** Editing Operations for child addrs ****
ReplaceNodes: PROC [n: Ref, start, len, newlen: Card] = INLINE
-- replace chars in [start..start+len) by newlen chars
-- addrs that are in the replaced section move to start
-- add (newlen-len) to addrs that are after the replaced section
{ addrsI.Replace[propsI.GetChildAddrs[n], start, len, newlen] };
MoveNodes: PROC [n: Ref, dest, start, len: Card] = INLINE
-- dest must not be in [start..start+len)
-- or get ERROR BadMove
{ addrsI.Move[propsI.GetChildAddrs[n], dest, start, len] };
InsertNode: PROC [n: Ref, start, length: Card] = INLINE {
-- adds len to addrs at or beyond start
ReplaceNodes[n, start, 0, length] };
TransposeNodes: PROC [n: Ref, astart, alen, bstart, blen: Card] = INLINE
-- [astart..astart+alen) must not intersect [bstart..bstart+blen)
-- or get ERROR BadTranspose
{ addrsI.Transpose[propsI.GetChildAddrs[n], astart, alen, bstart, blen] };
END.