plsm-ts/examples/LinkedList.plsm
2025-03-18 19:49:59 +01:00

170 lines
2.7 KiB
Plaintext

module std/list;
import std/io;
import std/heap;
trait Queue<T> : Collection<T> {
put(item: &T) void;
take() &T;
poll() &T?;
peek() &T?;
}
pub 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();
}
});
ret res;
}
all(fn: (&T) -> bool) bool {
let mut res = true;
self.each((item, break) -> {
if !fn(item) {
res = false;
break();
}
});
ret res;
}
// map<S>(fn: (&T) -> &S) -> Collection<S>;
// filter(fn: (&T) -> bool) -> Collection<T>;
}
trait Stack<T> : Collection<T> {
push(item: &T) void;
pop() &T;
peek() &T?;
}
pub 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;
ret;
}
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 {
ret;
}
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;
ret;
}
self.tail.remove(item);
self.size = self.size - 1;
}
contains(item: &T) bool {
if self.head == null {
ret false;
}
if self.head == item {
ret true;
}
ret self.tail.contains(item);
}
size() u64 {
ret self.size;
}
each(fn: (item: &T, break: () -> void) -> void) void {
if self.head == null {
ret;
}
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
ret null;
}
let item = self.head;
self.remove(item);
ret item;
}
poll() &T? {
if self.head == null {
ret null;
}
let item = self.head;
self.remove(item);
ret item;
}
peek() &T? = self.head;
}