| |
 |
|
This example program implements a generic version of a linked list. Note that in order to demonstrate a generic method,
we define a simple identity method, PHelper.Identity.
MODULE GListMod;
TYPE
IDisplayable = EXTENSIBLE INTERFACE RECORD (ANYIFACE) END;
PIDisplayable = POINTER TO IDisplayable;
GList<X:PIDisplayable> =
EXTENSIBLE RECORD (ANYREC + IDisplayable)
head: X;
tail: PGList<X>;
END;
PGList<X:PIDisplayable> =
POINTER TO GList<X:PIDisplayable>;
Integer = EXTENSIBLE RECORD (ANYREC + IDisplayable)
val: INTEGER;
END;
PInteger = POINTER TO Integer;
Helper = RECORD (ANYREC) END;
PHelper = POINTER TO Helper;
VAR
list: PGList<PInteger>;
helper: PHelper;
head: PInteger;
PROCEDURE (this: PIDisplayable) Display (), NEW, ABSTRACT;
PROCEDURE (this: PInteger) Display ();
BEGIN
util.WriteInt(this.val);
END Display;
PROCEDURE (this: PGList<X:PIDisplayable>) Display ();
BEGIN
IF util.Not(util.PEquals(this.head, NIL)) THEN
this.head.Display();
END;
util.WriteString("\n");
IF util.Not(util.PEquals(this.tail, NIL)) THEN
this.tail.Display();
END;
END Display;
PROCEDURE (this: PGList<X:PIDisplayable>) Insert (elem: X), NEW, EXTENSIBLE;
VAR
newList: PGList<X>;
BEGIN
IF util.Not(util.PEquals(this.tail, NIL)) THEN
this.tail.Insert(elem);
ELSE
NEW(newList);
newList.head := elem;
this.tail := newList;
END;
END Insert;
PROCEDURE (this: PGList<X:PIDisplayable>) Head (): X, NEW, EXTENSIBLE;
BEGIN
RETURN this.head;
END Head;
PROCEDURE (this: PGList<X:PIDisplayable>) Last (): X, NEW, EXTENSIBLE;
VAR
retVal: X;
BEGIN
IF util.Not(util.PEquals(this.tail, NIL)) THEN
retVal := this.tail.Last();
ELSE
retVal := this.head;
END;
RETURN retVal;
END Last;
PROCEDURE (this: PHelper) NewPInteger (val: INTEGER): PInteger, NEW;
VAR
p: PInteger;
BEGIN
NEW(p);
p.val := val;
RETURN p;
END NewPInteger;
PROCEDURE (this: PHelper) Identity <X:ANYPTR> (x: X): X, NEW;
BEGIN
RETURN x;
END Identity;
BEGIN
util.WriteString("GListMod test program\n");
NEW(list);
NEW(helper);
list.head := helper.NewPInteger(5);
list.Insert(helper.NewPInteger(10));
list.Insert(helper.NewPInteger(12));
list.Display();
head := list.Head();
util.WriteInt(head.val);
util.WriteString("\n");
head := list.Last();
util.WriteInt(head.val);
util.WriteString("\n");
util.WriteInt(helper.Identity<PInteger>(head).val);
END GListMod.
|