The generic interface List
provides operations on linked lists of
arbitrary element types.
GENERIC INTERFACEList (Elem);
WhereElem.T
is not an open array type andElem
contains
CONST Brand = <text-constant>; PROCEDURE Equal(k1, k2: Elem.T): BOOLEAN;Brand
must be a text constant. It will be used to construct a brand for any generic types instantiated with theList
interface. For a non-generic interface, we recommend choosing the name of the interface.
Equal
may be declared with a parameter mode of eitherVALUE
orREADONLY
, but notVAR
.
CONST Brand = "(List " & Elem.Brand & ")"; TYPE T = OBJECT head: Elem.T; tail: T END;A
List.T
represents a linked list of items of type Elem.T
.
None of the operations of this interface modify the head
field of
an existing list element. Operations that may modify the tail
field of existing list elements are called {\it destructive}. By
convention, their names end in D
.
\index{naming conventions!destructive list operations}
PROCEDURE Cons(READONLY head: Elem.T; tail: T): T;
Equivalent to NEW(T, head := head, tail := tail)
.
PROCEDURE List1(READONLY e1: Elem.T): T;
Return a list containing the single element e1
.
PROCEDURE List2(READONLY e1, e2: Elem.T): T;
Return a list containing the element sequencee1
,e2
.
PROCEDURE List3(READONLY e1, e2, e3: Elem.T): T;
Return a list containing the element sequencee1
,e2
,e3
.
PROCEDURE FromArray(READONLY e: ARRAY OF Elem.T): T;
Return a list containing the elements of e
in order.
PROCEDURE Length(l: T): CARDINAL;
Return the number of elements of l
.
PROCEDURE Nth(l: T; n: CARDINAL): Elem.T;
Return elementn
of listl
. Element 0 isl.head
, element 1 isl.tail.head
, etc. Cause a checked runtime error ifn >= Length(l)
.
PROCEDURE Member(l: T; READONLY e: Elem.T): BOOLEAN;
ReturnTRUE
if some element ofl
is equal toe
, else returnFALSE
. The comparison is performed byElem.Equal
.
PROCEDURE Append(l1: T; l2: T): T; PROCEDURE AppendD(l1: T; l2: T): T;
Append two lists together, returning the new list.Append
does this by making a copy of the cells ofl1
;AppendD
modifies thetail
field in the last cell ofl1
.
PROCEDURE Reverse(l: T): T; PROCEDURE ReverseD(l: T): T;
Return a list containing the elements ofl
in reverse order.Reverse
copies the cells;ReverseD
modifies thetail
fields of the existing cells.
END List. <*PRAGMA SPEC*> <*SPEC Cons(head, tail) ENSURES RES # NIL AND FRESH(RES) AND RES.head = head AND RES.tail = tail *> <*SPEC List1(e1) ENSURES RES # NIL AND FRESH(RES) AND RES.head = e1 AND RES.tail = NIL *> <*SPEC List2(e1, e2) ENSURES RES # NIL AND FRESH(RES) AND RES.head = e1 AND RES.tail # NIL AND FRESH(RES.tail) AND RES.tail.head = e2 AND RES.tail.tail = NIL *> <*SPEC List3(e1, e2, e3) ENSURES RES # NIL AND FRESH(RES) AND RES.head = e1 AND RES.tail # NIL AND FRESH(RES.tail) AND RES.tail.head = e2 AND RES.tail.tail # NIL AND FRESH(RES.tail.tail) AND RES.tail.tail.head = e3 AND RES.tail.tail.tail = NIL *>