170 lines
2.8 KiB
Plaintext
170 lines
2.8 KiB
Plaintext
module test;
|
|
|
|
import stdlib/io;
|
|
import stdlib/heap;
|
|
import stdlib/err;
|
|
|
|
trait Collection<T> {
|
|
add(item: &T) -> void;
|
|
remove(item: &T) -> void;
|
|
contains(item: &T) -> bool;
|
|
|
|
size() -> u64;
|
|
|
|
isEmpty() -> bool = self.size() > 0;
|
|
isNotEmpty() -> bool = self.size() <= 0;
|
|
|
|
each(fn: (item: &T, break: () -> void) -> void) -> void;
|
|
|
|
any(fn: (&T) -> bool) -> bool {
|
|
let mut res = false;
|
|
|
|
self.each((item, break) -> {
|
|
if fn(item) {
|
|
res = true;
|
|
break();
|
|
}
|
|
});
|
|
|
|
return res;
|
|
}
|
|
|
|
all(fn: (&T) -> bool) -> bool {
|
|
let mut res = true;
|
|
|
|
self.each((item, break) -> {
|
|
if !fn(item) {
|
|
res = false;
|
|
break();
|
|
}
|
|
});
|
|
|
|
return res;
|
|
}
|
|
|
|
// map<S>(fn: (&T) -> &S) -> Collection<S>;
|
|
// filter(fn: (&T) -> bool) -> Collection<T>;
|
|
}
|
|
|
|
trait Queue<T> : Collection<T> {
|
|
put(item: &T) -> void;
|
|
take() -> &T;
|
|
poll() -> &T?;
|
|
peek() -> &T?;
|
|
}
|
|
|
|
trait Stack<T> : Collection<T> {
|
|
push(item: &T) -> void;
|
|
pop() -> &T;
|
|
peek() -> &T?;
|
|
}
|
|
|
|
struct LinkedList<T> {
|
|
pub mut head: &T?;
|
|
pub mut tail: &LinkedList<T>?;
|
|
mut size: u64;
|
|
|
|
init() -> void {
|
|
self.head = null;
|
|
self.tail = null;
|
|
self.size = 0;
|
|
}
|
|
}
|
|
|
|
impl Collection<T> for LinkedList<T> {
|
|
add(item: &T) -> void {
|
|
if self.head == null {
|
|
self.head = item;
|
|
self.size = self.size + 1;
|
|
return;
|
|
}
|
|
|
|
if self.tail == null {
|
|
self.tail = heap.new(LinkedList);
|
|
self.tail.init();
|
|
}
|
|
|
|
self.tail.add(item);
|
|
self.size = self.size + 1;
|
|
}
|
|
|
|
remove(item: &T) -> void {
|
|
if self.head == null {
|
|
return;
|
|
}
|
|
|
|
if self.head == item {
|
|
let next = self.tail;
|
|
if next != null {
|
|
self.head = self.tail.head;
|
|
self.tail = self.tail.tail;
|
|
heap.free(next);
|
|
} else {
|
|
self.head = null;
|
|
}
|
|
|
|
self.size = self.size - 1;
|
|
return;
|
|
}
|
|
|
|
self.tail.remove(item);
|
|
self.size = self.size - 1;
|
|
}
|
|
|
|
contains(item: &T) -> bool {
|
|
if self.head == null {
|
|
return false;
|
|
}
|
|
|
|
if self.head == item {
|
|
return true;
|
|
}
|
|
|
|
return self.tail.contains(item);
|
|
}
|
|
|
|
size() -> u64 {
|
|
return self.size;
|
|
}
|
|
|
|
each(fn: (item: &T, break: () -> void) -> void) -> void {
|
|
if self.head == null {
|
|
return;
|
|
}
|
|
|
|
let mut continue = true;
|
|
fn(self.head, () -> { continue = false; });
|
|
|
|
if continue && self.tail != null {
|
|
self.tail.each(fn);
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Queue<T> for LinkedList<T> {
|
|
put(item: &T) -> void = self.add(item);
|
|
|
|
take() -> &T {
|
|
if head == null {
|
|
// TODO: wait for item to be available
|
|
return null;
|
|
}
|
|
|
|
let item = self.head;
|
|
self.remove(item);
|
|
return item;
|
|
}
|
|
|
|
poll() -> &T? {
|
|
if self.head == null {
|
|
return null;
|
|
}
|
|
|
|
let item = self.head;
|
|
self.remove(item);
|
|
return item;
|
|
}
|
|
|
|
peek() -> &T? = self.head;
|
|
}
|