66 lines
1.4 KiB
Plaintext
66 lines
1.4 KiB
Plaintext
include "strings.coh";
|
|
include "malloc.coh";
|
|
|
|
# Define types. The calling code is expected to provide a QueueData type.
|
|
record QueueItem is
|
|
data: QueueData;
|
|
next: [QueueItem];
|
|
end record;
|
|
|
|
record QueueMeta is
|
|
head: [QueueItem];
|
|
tail: [QueueItem];
|
|
end record;
|
|
|
|
typedef Queue is [QueueMeta];
|
|
const Q_NONE := 0 as [QueueItem];
|
|
|
|
# Allocate and free the queue datastructure.
|
|
sub MakeQueue(): (q: Queue) is
|
|
q := Alloc(@bytesof QueueMeta) as Queue;
|
|
q.head := Q_NONE;
|
|
q.tail := Q_NONE;
|
|
end sub;
|
|
|
|
sub FreeQueue(q: Queue) is
|
|
var cur := q.head;
|
|
while cur != Q_NONE loop
|
|
var next := cur.next;
|
|
Free(cur as [uint8]);
|
|
cur := next;
|
|
end loop;
|
|
Free(q as [uint8]);
|
|
end sub;
|
|
|
|
# Check if queue is empty.
|
|
sub QueueEmpty(q: Queue): (r: uint8) is
|
|
r := 0;
|
|
if q.head == Q_NONE then
|
|
r := 1;
|
|
end if;
|
|
end sub;
|
|
|
|
# Enqueue and dequeue data. Cowgol has no exceptions, so the calling code
|
|
# should check QueueEmpty first.
|
|
sub Enqueue(q: Queue, d: QueueData) is
|
|
var item := Alloc(@bytesof QueueItem) as [QueueItem];
|
|
item.data := d;
|
|
item.next := Q_NONE;
|
|
if q.head == Q_NONE then
|
|
q.head := item;
|
|
else
|
|
q.tail.next := item;
|
|
end if;
|
|
q.tail := item;
|
|
end sub;
|
|
|
|
sub Dequeue(q: Queue): (d: QueueData) is
|
|
d := q.head.data;
|
|
var cur := q.head;
|
|
q.head := q.head.next;
|
|
Free(cur as [uint8]);
|
|
if q.head == Q_NONE then
|
|
q.tail := Q_NONE;
|
|
end if;
|
|
end sub;
|