forked from KolibriOS/kolibrios
184 lines
3.0 KiB
Plaintext
184 lines
3.0 KiB
Plaintext
|
(*
|
||
|
BSD 2-Clause License
|
||
|
|
||
|
Copyright (c) 2018, Anton Krotov
|
||
|
All rights reserved.
|
||
|
*)
|
||
|
|
||
|
MODULE LISTS;
|
||
|
|
||
|
IMPORT C := COLLECTIONS;
|
||
|
|
||
|
|
||
|
TYPE
|
||
|
|
||
|
ITEM* = POINTER TO RECORD (C.ITEM)
|
||
|
|
||
|
prev*, next*: ITEM
|
||
|
|
||
|
END;
|
||
|
|
||
|
LIST* = POINTER TO RECORD
|
||
|
|
||
|
first*, last*: ITEM
|
||
|
|
||
|
END;
|
||
|
|
||
|
|
||
|
PROCEDURE push* (list: LIST; item: ITEM);
|
||
|
BEGIN
|
||
|
ASSERT(list # NIL);
|
||
|
ASSERT(item # NIL);
|
||
|
|
||
|
IF list.first = NIL THEN
|
||
|
list.first := item;
|
||
|
list.last := item;
|
||
|
item.prev := NIL;
|
||
|
item.next := NIL
|
||
|
ELSE
|
||
|
ASSERT(list.last # NIL);
|
||
|
|
||
|
item.prev := list.last;
|
||
|
list.last.next := item;
|
||
|
item.next := NIL;
|
||
|
list.last := item
|
||
|
END
|
||
|
END push;
|
||
|
|
||
|
|
||
|
PROCEDURE pop* (list: LIST): ITEM;
|
||
|
VAR
|
||
|
last: ITEM;
|
||
|
|
||
|
BEGIN
|
||
|
ASSERT(list # NIL);
|
||
|
|
||
|
last := list.last;
|
||
|
|
||
|
IF last # NIL THEN
|
||
|
IF last = list.first THEN
|
||
|
list.first := NIL;
|
||
|
list.last := NIL
|
||
|
ELSE
|
||
|
list.last := last.prev;
|
||
|
list.last.next := NIL
|
||
|
END;
|
||
|
|
||
|
last.next := NIL;
|
||
|
last.prev := NIL
|
||
|
END
|
||
|
|
||
|
RETURN last
|
||
|
END pop;
|
||
|
|
||
|
|
||
|
PROCEDURE insert* (list: LIST; cur, nov: ITEM);
|
||
|
VAR
|
||
|
next: ITEM;
|
||
|
|
||
|
BEGIN
|
||
|
ASSERT(list # NIL);
|
||
|
ASSERT(nov # NIL);
|
||
|
ASSERT(cur # NIL);
|
||
|
|
||
|
next := cur.next;
|
||
|
|
||
|
IF next # NIL THEN
|
||
|
next.prev := nov;
|
||
|
nov.next := next;
|
||
|
cur.next := nov;
|
||
|
nov.prev := cur
|
||
|
ELSE
|
||
|
push(list, nov)
|
||
|
END
|
||
|
|
||
|
END insert;
|
||
|
|
||
|
|
||
|
PROCEDURE insertL* (list: LIST; cur, nov: ITEM);
|
||
|
VAR
|
||
|
prev: ITEM;
|
||
|
|
||
|
BEGIN
|
||
|
ASSERT(list # NIL);
|
||
|
ASSERT(nov # NIL);
|
||
|
ASSERT(cur # NIL);
|
||
|
|
||
|
prev := cur.prev;
|
||
|
|
||
|
IF prev # NIL THEN
|
||
|
prev.next := nov;
|
||
|
nov.prev := prev;
|
||
|
cur.prev := nov;
|
||
|
nov.next := cur
|
||
|
ELSE
|
||
|
nov.prev := NIL;
|
||
|
cur.prev := nov;
|
||
|
nov.next := cur;
|
||
|
list.first := nov
|
||
|
END
|
||
|
|
||
|
END insertL;
|
||
|
|
||
|
|
||
|
PROCEDURE delete* (list: LIST; item: ITEM);
|
||
|
VAR
|
||
|
prev, next: ITEM;
|
||
|
|
||
|
BEGIN
|
||
|
ASSERT(list # NIL);
|
||
|
ASSERT(item # NIL);
|
||
|
|
||
|
prev := item.prev;
|
||
|
next := item.next;
|
||
|
|
||
|
IF (next # NIL) & (prev # NIL) THEN
|
||
|
prev.next := next;
|
||
|
next.prev := prev
|
||
|
ELSIF (next = NIL) & (prev = NIL) THEN
|
||
|
list.first := NIL;
|
||
|
list.last := NIL
|
||
|
ELSIF (next = NIL) & (prev # NIL) THEN
|
||
|
prev.next := NIL;
|
||
|
list.last := prev
|
||
|
ELSIF (next # NIL) & (prev = NIL) THEN
|
||
|
next.prev := NIL;
|
||
|
list.first := next
|
||
|
END
|
||
|
|
||
|
END delete;
|
||
|
|
||
|
|
||
|
PROCEDURE count* (list: LIST): INTEGER;
|
||
|
VAR
|
||
|
item: ITEM;
|
||
|
res: INTEGER;
|
||
|
|
||
|
BEGIN
|
||
|
ASSERT(list # NIL);
|
||
|
res := 0;
|
||
|
|
||
|
item := list.first;
|
||
|
WHILE item # NIL DO
|
||
|
INC(res);
|
||
|
item := item.next
|
||
|
END
|
||
|
|
||
|
RETURN res
|
||
|
END count;
|
||
|
|
||
|
|
||
|
PROCEDURE create* (list: LIST): LIST;
|
||
|
BEGIN
|
||
|
IF list = NIL THEN
|
||
|
NEW(list)
|
||
|
END;
|
||
|
|
||
|
list.first := NIL;
|
||
|
list.last := NIL
|
||
|
|
||
|
RETURN list
|
||
|
END create;
|
||
|
|
||
|
|
||
|
END LISTS.
|