plsm-ts/examples/LinkedList.plsm
2025-03-05 17:02:04 +01:00

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;
}