MODULE lili; (* Linked Lists with Mocka *) IMPORT InOut, Strings, SYSTEM; FROM MemPools IMPORT KillPool, MemPool, NewPool, PoolAllocate; TYPE Identifier = ARRAY [0..57] OF CHAR; NamePtr = POINTER TO NameNode; NameNode = RECORD Name : Identifier; next : NamePtr END; VAR string : Identifier; allNames : MemPool; FirstName : NamePtr; PROCEDURE StoreName (str : Identifier) : BOOLEAN; VAR this, prev, new : NamePtr; result : INTEGER; BEGIN this := FirstName; prev := NIL; LOOP result := Strings.compare (this^.Name, str); IF result = 0 THEN RETURN FALSE END; IF result = 1 THEN EXIT END; prev := this; this := this^.next END; PoolAllocate (allNames, new, SYSTEM.TSIZE (NameNode)); new^.Name := str; new^.next := this; IF prev = NIL THEN FirstName := new ELSE prev^.next := new END; RETURN TRUE END StoreName; PROCEDURE PrintNames; VAR ThisOne : NamePtr; BEGIN ThisOne := FirstName; IF Strings.StrEq (ThisOne^.Name, "Guard") THEN ThisOne := ThisOne^.next END; LOOP InOut.WriteString (ThisOne^.Name); InOut.WriteLn; IF ThisOne^.next = NIL THEN EXIT ELSE ThisOne := ThisOne^.next END END END PrintNames; PROCEDURE Init; BEGIN NewPool (allNames); PoolAllocate (allNames, FirstName, SYSTEM.TSIZE (NameNode)); WITH FirstName^ DO Name := "|"; next := NIL END END Init; BEGIN Init; LOOP InOut.ReadString (string); IF Strings.StrEq (string, "Exit") THEN EXIT END; IF StoreName (string) = FALSE THEN InOut.WriteString (">>> Duplicate name"); InOut.WriteLn END END; PrintNames; KillPool (allNames) END lili.