Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 7596 → Rev 7597

/programs/develop/oberon07/Source/LISTS.ob07
0,0 → 1,184
(*
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.