Copyright (C) 1994, Digital Equipment Corp. GENERIC INTERFACEThis interface provides a sequence abstraction, tailored to support the repetitive constructs in an Abstract Syntax Tree. It can also be used to support sets, provided the client enures no duplicates. There are no primitives to remove elements or to join sequences, since these notions are infrequent in ASTs, and can be programmed, admittedly inefficiently, in terms of the given primitives. Since this interface is instantiated many times, it is important to minimise its size.SeqElem (Elem);
Clients of this interface should provide their own locking in the case of multiple threads.
TYPE T <: REFANY; CONST Null: T = NIL;
To declare the null sequence do:VAR s := SeqElem.Null;Do not assume, however, that an empty sequence has the value NIL, useEmptyinstead.
PROCEDURE Empty(s: T): BOOLEAN RAISES {};
Returns TRUE iff s is the empty or null sequence, FALSE otherwise.
PROCEDURE Length(s: T): CARDINAL RAISES {};
Returns the length of sequence s. The null sequence has
length 0.
PROCEDURE AddFront(VAR (*inout*) s: T; elem: Elem.T) RAISES {};
Add the nodeelemto the front of sequences.
PROCEDURE AddRear(VAR (*inout*) s: T; elem: Elem.T) RAISES {};
Add the nodeelemto the rear of sequences.
PROCEDURE Insert(VAR (*inout*) s: T; elem: Elem.T; i: CARDINAL) RAISES {};
Insert the nodeelembefore the node at indexiin the sequence. The nodes are indexed from0toLength(s)-1, and0 <= i <= Length(s). Ifi = 0the call is equivalent toAddFront(s, elem). Ifi = Length(s), the call is equivalent toAddRear(s, elem).
PROCEDURE First(s: T): Elem.T RAISES {};
Return the first node in sequences. It is a checked run-time error ifEmpty(s).
TYPE Iter <: REFANY;
PROCEDURE NewIter(s: T): Iter RAISES {};
Create an iterator on sequence s. The behaviour of the iterator
is undefined if updates to the sequence occur during an iteration.
Each call creates a distinct iterator.
PROCEDURE Next(
VAR (*inout*) iter: Iter;
VAR (*out*) elem: Elem.T;
): BOOLEAN RAISES {};
Sequential calls ofNextreturn the members of the sequence in turn starting with the first. If there are no more members, FALSE is returned andelemis unchanged, elseelemis set to the member and TRUE is returned.
PROCEDURE Exhausted(iter: Iter): BOOLEAN RAISES {};
Return TRUE iffiteris exhausted, i.e. a call ofNextwould return FALSE.
PROCEDURE Update(VAR (*inout*) s: T; iter: Iter; new_elem: Elem.T) RAISES {};
IfNext(iter, elem)would return TRUE, then this procedure replaces the member ofs(whose old value waselem) withnew_elem. No actual call ofNexttakes place, however, anditeris NOT advanced. It is an unchecked run-time error ifsis not the same value that was passed to the call ofNewIterthat createditer. Typical usage is as follows:VAR iter, iter_u := SeqElem.NewIter(s); elem, new_elem: Elem.T; BEGIN WHILE SeqElem.Next(iter, elem) DO IF some-condition THEN SeqElem.Update(s, iter_u, new_elem) END: EVAL SeqElem.Next(iter_u, elem); END; END
PROCEDURE Ith(s: T; i: CARDINAL): Elem.T RAISES {};
Provides a view of the sequence as an array, indexed from0toLength(s)-1. It is a checked runtime error ifiis out of bounds. N.B. This is not an efficient way to iterate the sequence.
END SeqElem.