LISTS.ob07 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. MODULE LISTS;
  2. IMPORT C := COLLECTIONS;
  3. TYPE
  4. ITEM* = POINTER TO RECORD (C.ITEM)
  5. prev*, next*: ITEM
  6. END;
  7. LIST* = POINTER TO RECORD
  8. first*, last*: ITEM
  9. END;
  10. PROCEDURE push* (list: LIST; item: ITEM);
  11. BEGIN
  12. ASSERT(list # NIL);
  13. ASSERT(item # NIL);
  14. IF list.first = NIL THEN
  15. list.first := item;
  16. item.prev := NIL
  17. ELSE
  18. ASSERT(list.last # NIL);
  19. item.prev := list.last;
  20. list.last.next := item
  21. END;
  22. list.last := item;
  23. item.next := NIL
  24. END push;
  25. PROCEDURE pop* (list: LIST): ITEM;
  26. VAR
  27. last: ITEM;
  28. BEGIN
  29. ASSERT(list # NIL);
  30. last := list.last;
  31. IF last # NIL THEN
  32. IF last = list.first THEN
  33. list.first := NIL;
  34. list.last := NIL
  35. ELSE
  36. list.last := last.prev;
  37. list.last.next := NIL
  38. END;
  39. last.next := NIL;
  40. last.prev := NIL
  41. END
  42. RETURN last
  43. END pop;
  44. PROCEDURE insert* (list: LIST; cur, nov: ITEM);
  45. VAR
  46. next: ITEM;
  47. BEGIN
  48. ASSERT(list # NIL);
  49. ASSERT(nov # NIL);
  50. ASSERT(cur # NIL);
  51. next := cur.next;
  52. IF next # NIL THEN
  53. next.prev := nov;
  54. nov.next := next;
  55. cur.next := nov;
  56. nov.prev := cur
  57. ELSE
  58. push(list, nov)
  59. END
  60. END insert;
  61. PROCEDURE insertL* (list: LIST; cur, nov: ITEM);
  62. VAR
  63. prev: ITEM;
  64. BEGIN
  65. ASSERT(list # NIL);
  66. ASSERT(nov # NIL);
  67. ASSERT(cur # NIL);
  68. prev := cur.prev;
  69. IF prev # NIL THEN
  70. prev.next := nov;
  71. nov.prev := prev
  72. ELSE
  73. nov.prev := NIL;
  74. list.first := nov
  75. END;
  76. cur.prev := nov;
  77. nov.next := cur
  78. END insertL;
  79. PROCEDURE delete* (list: LIST; item: ITEM);
  80. VAR
  81. prev, next: ITEM;
  82. BEGIN
  83. ASSERT(list # NIL);
  84. ASSERT(item # NIL);
  85. prev := item.prev;
  86. next := item.next;
  87. IF next # NIL THEN
  88. IF prev # NIL THEN
  89. prev.next := next;
  90. next.prev := prev
  91. ELSE
  92. next.prev := NIL;
  93. list.first := next
  94. END
  95. ELSE
  96. IF prev # NIL THEN
  97. prev.next := NIL;
  98. list.last := prev
  99. ELSE
  100. list.first := NIL;
  101. list.last := NIL
  102. END
  103. END
  104. END delete;
  105. PROCEDURE count* (list: LIST): INTEGER;
  106. VAR
  107. item: ITEM;
  108. res: INTEGER;
  109. BEGIN
  110. ASSERT(list # NIL);
  111. res := 0;
  112. item := list.first;
  113. WHILE item # NIL DO
  114. INC(res);
  115. item := item.next
  116. END
  117. RETURN res
  118. END count;
  119. PROCEDURE getidx* (list: LIST; idx: INTEGER): ITEM;
  120. VAR
  121. item: ITEM;
  122. BEGIN
  123. ASSERT(list # NIL);
  124. ASSERT(idx >= 0);
  125. item := list.first;
  126. WHILE (item # NIL) & (idx > 0) DO
  127. item := item.next;
  128. DEC(idx)
  129. END
  130. RETURN item
  131. END getidx;
  132. PROCEDURE create* (list: LIST): LIST;
  133. BEGIN
  134. IF list = NIL THEN
  135. NEW(list)
  136. END;
  137. list.first := NIL;
  138. list.last := NIL
  139. RETURN list
  140. END create;
  141. END LISTS.