home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Programming / Misc / OB3.2D2.DMS / in.adf / Module / Lists.mod < prev    next >
Encoding:
Text File  |  1994-08-05  |  4.6 KB  |  239 lines

  1. (*-------------------------------------------------------------------------*)
  2. (*                                                                         *)
  3. (*  Amiga Oberon Library Module: Lists                Date: 02-Nov-92      *)
  4. (*                                                                         *)
  5. (*   © 1992 by Fridtjof Siebert                                            *)
  6. (*                                                                         *)
  7. (*-------------------------------------------------------------------------*)
  8.  
  9. MODULE Lists;
  10.  
  11. IMPORT BT * := BasicTypes;
  12.  
  13. TYPE
  14.   NodePtr* = POINTER TO Node;
  15.   Node* = RECORD (BT.ANYDesc)
  16.     next-: NodePtr;
  17.     prev-: NodePtr;
  18.   END;
  19.  
  20.   ListPtr * = POINTER TO List;
  21.   List* = RECORD (BT.COLLECTIONDesc)
  22.     head-: NodePtr;
  23.     tail-: NodePtr;
  24.     remallowed: INTEGER;
  25.     numElements: LONGINT;
  26.   END;
  27.  
  28.   DoProc * = PROCEDURE(n: NodePtr);
  29.  
  30. (* Die DoProc darf Remove(), RemHead() und RemTail() nicht benutzen. *)
  31.  
  32.  
  33. PROCEDURE Init*(VAR list: List);
  34. BEGIN
  35.   list.head := NIL;
  36.   list.tail := NIL;
  37.   list.remallowed := 0;
  38.   list.numElements := 0;
  39. END Init;
  40.  
  41.  
  42. PROCEDURE AddHead*(VAR list: List; n: NodePtr);
  43. BEGIN
  44.   n.next := list.head;
  45.   n.prev := NIL;
  46.   IF n.next=NIL THEN list.tail   := n;
  47.                 ELSE n.next.prev := n END;
  48.   list.head := n;
  49.   INC(list.numElements);
  50. END AddHead;
  51.  
  52.  
  53. PROCEDURE AddTail*(VAR list: List; n: NodePtr);
  54. BEGIN
  55.   n.prev := list.tail;
  56.   n.next := NIL;
  57.   IF n.prev=NIL THEN list.head   := n;
  58.                 ELSE n.prev.next := n END;
  59.   list.tail := n;
  60.   INC(list.numElements);
  61. END AddTail;
  62.  
  63.  
  64. PROCEDURE Remove*(VAR list: List; n: NodePtr);
  65. BEGIN
  66.   IF n#NIL THEN
  67.     IF list.remallowed # 0 THEN HALT(20) END;
  68.     IF n.next#NIL THEN n.next.prev := n.prev ELSE list.tail := n.prev END;
  69.     IF n.prev#NIL THEN n.prev.next := n.next ELSE list.head := n.next END;
  70.     DEC(list.numElements);
  71.   END;
  72. END Remove;
  73.  
  74.  
  75. PROCEDURE RemHead*(VAR list: List): NodePtr;
  76. VAR n: NodePtr;
  77. BEGIN
  78.   n := list.head; Remove(list,n); RETURN n;
  79. END RemHead;
  80.  
  81.  
  82. PROCEDURE RemTail*(VAR list: List): NodePtr;
  83. VAR n: NodePtr;
  84. BEGIN
  85.   n := list.tail; Remove(list,n); RETURN n;
  86. END RemTail;
  87.  
  88.  
  89. PROCEDURE AddBefore*(VAR list: List;
  90.                          n,x: NodePtr);
  91. (* fügt n vor x in die Liste ein *)
  92.  
  93. BEGIN
  94.   n.prev := x.prev;
  95.   n.next := x;
  96.   x .prev := n;
  97.   IF n.prev=NIL THEN list.head   := n
  98.                 ELSE n.prev.next := n END;
  99.   INC(list.numElements);
  100. END AddBefore;
  101.  
  102.  
  103. PROCEDURE AddBehind*(VAR list: List;
  104.                          n,x: NodePtr);
  105. (* fügt n hinter x in die Liste ein *)
  106.  
  107. BEGIN
  108.   n.next := x.next;
  109.   n.prev := x;
  110.   x .next := n;
  111.   IF n.next=NIL THEN list.tail   := n
  112.                 ELSE n.next.prev := n END;
  113.   INC(list.numElements);
  114. END AddBehind;
  115.  
  116.  
  117. PROCEDURE Empty*(VAR list: List): BOOLEAN;
  118. BEGIN
  119.   RETURN list.numElements=0
  120. END Empty;
  121.  
  122.  
  123. PROCEDURE CountElements*(VAR list: List): LONGINT;
  124. BEGIN
  125.   RETURN list.numElements;
  126. END CountElements;
  127.  
  128.  
  129. PROCEDURE DoForward*(VAR list: List; proc: DoProc);
  130. VAR n: NodePtr;
  131. BEGIN
  132.   INC(list.remallowed);
  133.   n := list.head; WHILE n#NIL DO proc(n); n := n.next END;
  134.   DEC(list.remallowed);
  135. END DoForward;
  136.  
  137.  
  138. PROCEDURE DoBackward*(VAR list: List; proc: DoProc);
  139. VAR n: NodePtr;
  140. BEGIN
  141.   INC(list.remallowed);
  142.   n := list.tail; WHILE n#NIL DO proc(n); n := n.prev END;
  143.   DEC(list.remallowed);
  144. END DoBackward;
  145.  
  146.  
  147. PROCEDURE Next*(VAR n: NodePtr): BOOLEAN;
  148. BEGIN
  149.   n := n.next;
  150.   RETURN n#NIL;
  151. END Next;
  152.  
  153.  
  154. PROCEDURE Previous*(VAR n: NodePtr): BOOLEAN;
  155. BEGIN
  156.   n := n.prev;
  157.   RETURN n#NIL;
  158. END Previous;
  159.  
  160.  
  161. PROCEDURE Succ*(VAR n: NodePtr);
  162. BEGIN
  163.   n := n.next;
  164. END Succ;
  165.  
  166.  
  167. PROCEDURE Pred*(VAR n: NodePtr);
  168. BEGIN
  169.   n := n.prev;
  170. END Pred;
  171.  
  172.  
  173. PROCEDURE Head*(VAR list: List): NodePtr;
  174. BEGIN
  175.   RETURN list.head;
  176. END Head;
  177.  
  178.  
  179. PROCEDURE Tail*(VAR list: List): NodePtr;
  180. BEGIN
  181.   RETURN list.tail;
  182. END Tail;
  183.  
  184.  
  185. PROCEDURE (list: ListPtr) Add        * (x: BT.ANY);  
  186. (*
  187.  * Adds x to the tail of list.
  188.  *)
  189. BEGIN
  190.   AddTail(list^,x(Node));
  191. END Add;
  192.  
  193.  
  194. PROCEDURE (list: ListPtr) Remove     * (x: BT.ANY);
  195. (*
  196.  * removes x from list.
  197.  *)
  198. BEGIN
  199.   Remove(list^,x(Node));
  200. END Remove;
  201.  
  202.  
  203. PROCEDURE (list: ListPtr) nbElements * (): LONGINT;
  204. (* returns the number of elements within list.
  205.  *)
  206. BEGIN
  207.   RETURN list.numElements
  208. END nbElements;
  209.  
  210.  
  211. PROCEDURE (list: ListPtr) isEmpty * (): BOOLEAN;
  212. (* is list empty?
  213.  *)
  214. BEGIN
  215.   RETURN list.numElements=0
  216. END isEmpty;
  217.  
  218.  
  219. PROCEDURE (list: ListPtr) Do         * (p: BT.DoProc; par: BT.ANY);
  220. (* calls p(x,par) for every element x stored within list.
  221.  * par passes some additional information to p. par is not touched by Do.
  222.  *)
  223. VAR
  224.   n: NodePtr;
  225. BEGIN
  226.   INC(list.remallowed);
  227.   n := list.head; WHILE n#NIL DO p(n,par); n := n.next END;
  228.   DEC(list.remallowed);
  229. END Do;
  230.  
  231.  
  232. END Lists.
  233.  
  234.  
  235.  
  236.  
  237.  
  238.  
  239.