Subversion Repositories Kolibri OS

Rev

Rev 9010 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. (*
  2.     Copyright 2021 Anton Krotov
  3.  
  4.     This file is part of CEdit.
  5.  
  6.     CEdit is free software: you can redistribute it and/or modify
  7.     it under the terms of the GNU General Public License as published by
  8.     the Free Software Foundation, either version 3 of the License, or
  9.     (at your option) any later version.
  10.  
  11.     CEdit is distributed in the hope that it will be useful,
  12.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.     GNU General Public License for more details.
  15.  
  16.     You should have received a copy of the GNU General Public License
  17.     along with CEdit. If not, see <http://www.gnu.org/licenses/>.
  18. *)
  19.  
  20. MODULE List;
  21.  
  22. TYPE
  23.  
  24.     tItem* = POINTER TO RECORD
  25.         prev*, next*: tItem
  26.     END;
  27.  
  28.     tList* = POINTER TO RECORD
  29.         first*, last*: tItem;
  30.         count*: INTEGER
  31.     END;
  32.  
  33.     PmovInt = PROCEDURE (VAR v: INTEGER; x: INTEGER);
  34.     PmovPtr = PROCEDURE (VAR v: tItem; x: tItem);
  35.  
  36.  
  37. VAR
  38.  
  39.     _movInt: PmovInt;
  40.     _movPtr: PmovPtr;
  41.  
  42.  
  43. PROCEDURE create* (list: tList): tList;
  44. BEGIN
  45.     IF list = NIL THEN
  46.         NEW(list)
  47.     END;
  48.     list.first := NIL;
  49.     list.last  := NIL;
  50.     list.count := 0
  51.     RETURN list
  52. END create;
  53.  
  54.  
  55. PROCEDURE getItem* (list: tList; idx: INTEGER): tItem;
  56. VAR
  57.     item: tItem;
  58. BEGIN
  59.     IF idx < 0 THEN
  60.         item := NIL
  61.     ELSE
  62.         item := list.first;
  63.         WHILE (idx > 0) & (item # NIL) DO
  64.             item := item.next;
  65.             DEC(idx)
  66.         END
  67.     END
  68.     RETURN item
  69. END getItem;
  70.  
  71.  
  72. PROCEDURE delete* (list: tList; item: tItem);
  73. VAR
  74.     prev, next: tItem;
  75. BEGIN
  76.     prev := item.prev;
  77.     next := item.next;
  78.     IF prev # NIL THEN
  79.         prev.next := next;
  80.         IF next # NIL THEN
  81.             next.prev := prev
  82.         ELSE
  83.             list.last := prev
  84.         END
  85.     ELSE
  86.         list.first := next;
  87.         IF next # NIL THEN
  88.            next.prev := NIL
  89.         ELSE
  90.            list.last := NIL
  91.         END
  92.     END;
  93.     DEC(list.count)
  94. END delete;
  95.  
  96.  
  97. PROCEDURE movInt (VAR v: INTEGER; x: INTEGER);
  98. BEGIN
  99.     _movInt(v, x);
  100.     v := x
  101. END movInt;
  102.  
  103.  
  104. PROCEDURE movPtr (VAR v: tItem; x: tItem);
  105. BEGIN
  106.     _movPtr(v, x);
  107.     v := x
  108. END movPtr;
  109.  
  110.  
  111. PROCEDURE _delete* (list: tList; item: tItem);
  112. VAR
  113.     prev, next: tItem;
  114. BEGIN
  115.     prev := item.prev;
  116.     next := item.next;
  117.     IF prev # NIL THEN
  118.         movPtr(prev.next, next);
  119.         IF next # NIL THEN
  120.             movPtr(next.prev, prev)
  121.         ELSE
  122.             movPtr(list.last, prev)
  123.         END
  124.     ELSE
  125.         movPtr(list.first, next);
  126.         IF next # NIL THEN
  127.            movPtr(next.prev, NIL)
  128.         ELSE
  129.            movPtr(list.last, NIL)
  130.         END
  131.     END;
  132.     movInt(list.count, list.count - 1)
  133. END _delete;
  134.  
  135.  
  136. PROCEDURE _append* (list: tList; item: tItem);
  137. BEGIN
  138.     movPtr(item.prev, list.last);
  139.     IF list.last # NIL THEN
  140.         movPtr(list.last.next, item)
  141.     ELSE
  142.         movPtr(list.first, item)
  143.     END;
  144.     movPtr(list.last, item);
  145.     movPtr(item.next, NIL);
  146.     movInt(list.count, list.count + 1)
  147. END _append;
  148.  
  149.  
  150. PROCEDURE _insert* (list: tList; item, newItem: tItem);
  151. VAR
  152.     next: tItem;
  153. BEGIN
  154.     next := item.next;
  155.     IF next # NIL THEN
  156.         movPtr(next.prev, newItem);
  157.         movPtr(newItem.next, next);
  158.         movPtr(item.next, newItem);
  159.         movPtr(newItem.prev, item);
  160.         movInt(list.count, list.count + 1)
  161.     ELSE
  162.         _append(list, newItem)
  163.     END
  164. END _insert;
  165.  
  166.  
  167. PROCEDURE _exchange* (list: tList; a, b: tItem);
  168. VAR
  169.     a0, b0: tItem;
  170. BEGIN
  171.     IF (a # NIL) & (b # NIL) THEN
  172.         ASSERT((a.next = b) & (b.prev = a));
  173.         a0 := a.prev;
  174.         b0 := b.next;
  175.         movPtr(b.prev, a0);
  176.         movPtr(a.next, b0);
  177.         movPtr(b.next, a);
  178.         movPtr(a.prev, b);
  179.         IF a0 # NIL THEN
  180.             IF b0 # NIL THEN
  181.                 movPtr(a0.next, b);
  182.                 movPtr(b0.prev, a);
  183.             ELSE
  184.                 movPtr(a0.next, b);
  185.                 movPtr(list.last, a)
  186.             END
  187.         ELSE
  188.             IF b0 # NIL THEN
  189.                 movPtr(b0.prev, a);
  190.                 movPtr(list.first, b)
  191.             ELSE
  192.                 movPtr(list.first, b);
  193.                 movPtr(list.last, a)
  194.             END
  195.         END
  196.     END
  197. END _exchange;
  198.  
  199.  
  200. PROCEDURE append* (list: tList; item: tItem);
  201. BEGIN
  202.     item.prev := list.last;
  203.     IF list.last # NIL THEN
  204.         list.last.next := item
  205.     ELSE
  206.         list.first := item
  207.     END;
  208.     list.last := item;
  209.     item.next := NIL;
  210.     INC(list.count)
  211. END append;
  212.  
  213.  
  214. PROCEDURE insert* (list: tList; item, newItem: tItem);
  215. VAR
  216.     next: tItem;
  217. BEGIN
  218.     next := item.next;
  219.     IF next # NIL THEN
  220.         next.prev := newItem;
  221.         newItem.next := next;
  222.         item.next := newItem;
  223.         newItem.prev := item;
  224.         INC(list.count)
  225.     ELSE
  226.         append(list, newItem)
  227.     END
  228. END insert;
  229.  
  230.  
  231. PROCEDURE pop* (list: tList): tItem;
  232. VAR
  233.     res: tItem;
  234. BEGIN
  235.     IF list.count # 0 THEN
  236.         res := list.last;
  237.         list.last := res.prev;
  238.         DEC(list.count);
  239.         IF list.count # 0 THEN
  240.             list.last.next := NIL
  241.         ELSE
  242.             list.first := NIL
  243.         END;
  244.         res.prev := NIL;
  245.         res.next := NIL
  246.     ELSE
  247.         res := NIL
  248.     END
  249.     RETURN res
  250. END pop;
  251.  
  252.  
  253. PROCEDURE init* (movInt: PmovInt; movPtr: PmovPtr);
  254. BEGIN
  255.     _movInt := movInt;
  256.     _movPtr := movPtr
  257. END init;
  258.  
  259.  
  260. END List.