reorganized build-ins and implement a circular queue as an example

This commit is contained in:
cozis
2022-08-18 19:01:26 +02:00
parent b5b3a3e315
commit 782985e8b7
36 changed files with 486 additions and 259 deletions
+142
View File
@@ -0,0 +1,142 @@
# This script implements a circular queue and
# it's relative tests!
fun newCircularQueue(T: Type = int, max: int = 3) {
if T == None:
error("Invalid type");
if max <= 0:
error("Maximum queue size must be positive");
list = [];
i = 0;
while i < max: {
list[i] = none;
i = i+1;
}
return {
max: max,
head: 0,
tail: 0,
list: list,
type: T
};
}
fun getSize(queue: Map) {
size = none;
if queue.tail == queue.head: {
if queue.list[queue.tail] == none: {
size = 0;
} else {
size = queue.max;
}
} else if queue.tail < queue.head: {
size = queue.head
- queue.tail;
} else {
size = queue.head
+ queue.max
- queue.tail;
}
return size;
}
fun append(queue: Map, value) {
if type(value) != queue.type:
error("Invalid type");
size = getSize(queue);
queue.list[queue.head] = value;
if size == queue.max: {
queue.tail = queue.tail+1;
if queue.tail == queue.max:
queue.tail = 0;
}
queue.head = queue.head+1;
if queue.head == queue.max:
queue.head = 0;
}
fun pop(queue: Map) {
if getSize(queue) == 0:
return none;
value = queue.list[queue.tail];
queue.list[queue.tail] = none;
queue.tail = queue.tail+1;
if queue.tail == queue.max:
queue.tail = 0;
return value;
}
{
utils = import("../utils.noja");
queue = newCircularQueue(int, 3);
assert(getSize(queue) == 0);
assert(queue.head == 0);
assert(queue.tail == 0);
append(queue, 1);
assert(queue.head == 1);
assert(queue.tail == 0);
assert(getSize(queue) == 1);
assert(utils.compareAny(queue.list, [1, none, none]));
append(queue, 2);
assert(queue.head == 2);
assert(queue.tail == 0);
assert(getSize(queue) == 2);
assert(utils.compareAny(queue.list, [1, 2, none]));
append(queue, 3);
assert(queue.head == 0);
assert(queue.tail == 0);
assert(getSize(queue) == 3);
assert(utils.compareAny(queue.list, [1, 2, 3]));
append(queue, 4);
assert(queue.head == 1);
assert(queue.tail == 1);
assert(getSize(queue) == 3);
assert(utils.compareAny(queue.list, [4, 2, 3]));
v = pop(queue);
assert(v == 2);
assert(queue.head == 1);
assert(queue.tail == 2);
assert(getSize(queue) == 2);
assert(utils.compareAny(queue.list, [4, none, 3]));
v = pop(queue);
assert(v == 3);
assert(queue.head == 1);
assert(queue.tail == 0);
assert(getSize(queue) == 1);
assert(utils.compareAny(queue.list, [4, none, none]));
v = pop(queue);
assert(v == 4);
assert(queue.head == 1);
assert(queue.tail == 1);
assert(getSize(queue) == 0);
assert(utils.compareAny(queue.list, [none, none, none]));
v = pop(queue);
assert(v == none);
assert(queue.head == 1);
assert(queue.tail == 1);
assert(getSize(queue) == 0);
assert(utils.compareAny(queue.list, [none, none, none]));
}
+67
View File
@@ -0,0 +1,67 @@
# Implementation of a stack using a linked list.
fun Stack_New(T) {
if T == None:
return none, "The type can't be None";
return { count: 0, head: none, type: T };
}
fun Stack_Push(stack: Map, value) {
assert(stack.type != None);
if type(value) != stack.type:
error("Invalid type");
node = {prev: none, item: value};
node.prev = stack.head;
stack.head = node;
stack.count = stack.count + 1;
}
fun Stack_Pop(stack: Map) {
if stack.head == none:
return none;
value = stack.head.item;
stack.head = stack.head.prev;
stack.count = stack.count - 1;
return value;
}
fun Stack_Print(stack: Map) {
print("[");
curr = stack.head;
while curr != none: {
print(curr.item);
curr = curr.prev;
if curr != none:
print(", ");
}
print("]");
}
stack = Stack_New(int);
Stack_Push(stack, 1);
Stack_Push(stack, 2);
Stack_Push(stack, 3);
Stack_Print(stack);
print("\n");
x = Stack_Pop(stack);
y = Stack_Pop(stack);
z = Stack_Pop(stack);
w = Stack_Pop(stack);
assert(x == 3);
assert(y == 2);
assert(z == 1);
assert(w == none);
Stack_Print(stack);
print("\n");