September Morn Update

This commit is contained in:
Ingy döt Net 2019-09-12 10:33:56 -07:00
parent 4e2d22a71d
commit aac6731f2c
6856 changed files with 141342 additions and 21127 deletions

View file

@ -1,63 +1,81 @@
MODULE Queue;
IMPORT StdLog,Boxes;
IMPORT
Boxes;
TYPE
Queue* = POINTER TO RECORD
first,last: LONGINT;
queue: POINTER TO ARRAY OF Boxes.Object;
END;
PROCEDURE NewQueue*(cap: LONGINT): Queue;
VAR
q: Queue;
BEGIN
NEW(q);q.first := 0; q.last := 0;
NEW(q.queue,cap);
RETURN q
END NewQueue;
PROCEDURE (q: Queue) IsEmpty*(): BOOLEAN, NEW;
VAR
BEGIN
RETURN (q.first = q.last)
END IsEmpty;
PROCEDURE (q: Queue) Push*(o: Boxes.Object),NEW;
VAR
i,j,oldSize,newSize: LONGINT;
queue: POINTER TO ARRAY OF Boxes.Object;
BEGIN
IF q.IsEmpty() THEN
q.queue[q.last] := o;
q.last := (q.last + 1) MOD LEN(q.queue)
ELSE
q.queue[q.last] := o;
q.last := (q.last + 1) MOD LEN(q.queue);
IF q.first = q.last THEN
(* grow queue *)
newSize := LEN(q.queue) + (LEN(q.queue) DIV 2);
(* new queue*)
NEW(queue,newSize);
(* move data from old queue to new queue *)
i := q.first; j := 0;oldSize := LEN(q.queue) - q.first + q.last;
WHILE (j < oldSize ) & (j < LEN(queue) - 1) DO
queue[j] := q.queue[i];
i := (i + 1) MOD LEN(q.queue);INC(j)
END;
q.queue := queue;q.first := 0;q.last := j
END
END;
END Push;
PROCEDURE (q: Queue) Pop*(): Boxes.Object, NEW;
VAR
o: Boxes.Object;
BEGIN
ASSERT(~q.IsEmpty());
o := q.queue[q.first];
q.queue[q.first] := NIL;
q.first := (q.first + 1) MOD LEN(q.queue);
RETURN o;
END Pop;
Instance* = POINTER TO LIMITED RECORD
size: LONGINT;
first,last: LONGINT;
_queue: POINTER TO ARRAY OF Boxes.Box;
END;
PROCEDURE (self: Instance) Initialize(capacity: LONGINT),NEW;
BEGIN
self.size := 0;
self.first := 0;
self.last := 0;
NEW(self._queue,capacity)
END Initialize;
PROCEDURE New*(capacity: LONGINT): Instance;
VAR
aQueue: Instance;
BEGIN
NEW(aQueue);aQueue.Initialize(capacity);RETURN aQueue
END New;
PROCEDURE (self: Instance) IsEmpty*(): BOOLEAN, NEW;
BEGIN
RETURN self.size = 0;
END IsEmpty;
PROCEDURE (self: Instance) Capacity*(): LONGINT, NEW;
BEGIN
RETURN LEN(self._queue)
END Capacity;
PROCEDURE (self: Instance) Size*(): LONGINT, NEW;
BEGIN
RETURN self.size
END Size;
PROCEDURE (self: Instance) IsFull*(): BOOLEAN, NEW;
BEGIN
RETURN self.size = self.Capacity()
END IsFull;
PROCEDURE (self: Instance) Push*(b: Boxes.Box), NEW;
VAR
i, j, newCapacity, oldSize: LONGINT;
queue: POINTER TO ARRAY OF Boxes.Box;
BEGIN
INC(self.size);
self._queue[self.last] := b;
self.last := (self.last + 1) MOD self.Capacity();
IF self.IsFull() THEN
(* grow queue *)
newCapacity := self.Capacity() + (self.Capacity() DIV 2);
(* new queue *)
NEW(queue,newCapacity);
(* move data from old to new queue *)
i := self.first; j := 0; oldSize := self.Capacity() - self.first + self.last;
WHILE (j < oldSize) & (j < newCapacity - 1) DO
queue[j] := self._queue[i];
i := (i + 1) MOD newCapacity;INC(j)
END;
self._queue := queue;self.first := 0;self.last := j
END
END Push;
PROCEDURE (self: Instance) Pop*(): Boxes.Box, NEW;
VAR
b: Boxes.Box;
BEGIN
ASSERT(~self.IsEmpty());
DEC(self.size);
b := self._queue[self.first];
self._queue[self.first] := NIL;
self.first := (self.first + 1) MOD self.Capacity();
RETURN b
END Pop;
END Queue.