aboutsummaryrefslogtreecommitdiff
path: root/std/prelude/lists.pk
diff options
context:
space:
mode:
Diffstat (limited to 'std/prelude/lists.pk')
-rw-r--r--std/prelude/lists.pk109
1 files changed, 109 insertions, 0 deletions
diff --git a/std/prelude/lists.pk b/std/prelude/lists.pk
new file mode 100644
index 0000000..410cfed
--- /dev/null
+++ b/std/prelude/lists.pk
@@ -0,0 +1,109 @@
+## std.lists: Dynamic arrays.
+## This module is imported by default.
+# reference: https://doc.rust-lang.org/nomicon/vec/vec.html
+
+use std.pointers
+
+## The list type.
+type list[T] = struct
+ data: unique[T] # hrm
+ capacity: int
+ length: int
+
+## Initialize and return an empty list with inner type T.
+pub func init[T](): list[T] =
+ ... # malloc? idk
+ let (data, )
+ { data: , capacity: 0, length: 0 }
+
+## Gets the length of a list.
+pub func len[T](self: list[T]): uint =
+ self.length
+
+pub func empty[T](self: list[T]): bool =
+ self.length == 0
+
+## Gets the internal capacity of a list.
+func cap[T](self: list[T]): uint =
+ self.capacity
+
+## Expands the capacity of a list.
+func grow[T](self: mut list[T]) =
+ ...
+
+## Pushes a new element to the end of a list.
+pub func push[T](self: mut list[T], val: owned T) =
+ if self.length == self.capacity:
+ self.grow()
+ unsafe: # todo: do we want unsafe blocks, as they are in rust?
+ self.data.raw_set(self.length, val) # fixme
+ # unsafe { ptr::write(self.ptr().add(self.length), val); }
+ self.length += 1
+
+## Takes ownership of and pushes all the values of a list into another list.
+pub func push[T](self: mut list[T], val: owned list[T]) =
+ ...
+
+## Removes & returns an element from the end of a list, if it exists.
+pub func pop[T](self: mut list[T]): T? =
+ if self.length == 0:
+ None
+ unsafe:
+ self.length -= 1
+ Some(self.data.raw_get[T](self.length)) # fixme
+ # unsafe { Some(ptr::read(self.ptr().add(self.length))) }
+
+## Returns a reference to an element of a list, if in range.
+pub func get[T](self: list[T], i: uint): lent T? =
+ ...
+
+## Sets the element of a list to a value. todo: when is `val` owned?
+## todo: how do we deal with having the wrong offset?
+pub func set[T](self: mut list[T], i: uint, val: owned T) =
+ ...
+
+## Inserts a value at a location and shifts elements of the list accordingly.
+pub func insert[T](self: mut list[T], i: uint, val: T) =
+ assert i <= self.length, "index out of bounds"
+ if self.cap == self.len:
+ self.grow()
+ ...
+ # unsafe {
+ # ptr::copy(
+ # self.ptr().add(index),
+ # self.ptr().add(index + 1),
+ # self.len - index,
+ # );
+ # ptr::write(self.ptr().add(index), elem);
+ # self.len += 1;
+ # }
+
+## Removes a value at a location and shifts elements of the list accordingly.
+pub func remove[T](self: mut list[T], i: uint): T =
+ assert index < self.length, "index out of bounds"
+ unsafe:
+ self.length -= 1
+ result = ...
+ # unsafe {
+ # self.len -= 1;
+ # let result = ptr::read(self.ptr().add(index));
+ # ptr::copy(
+ # self.ptr().add(index + 1),
+ # self.ptr().add(index),
+ # self.len - index,
+ # );
+ # result
+ # }
+
+## Gets the last element of a list, if it exists.
+pub func last[T](self: list[T]): lent T? =
+ self.get(self.len - 1)
+
+# todo: iteration...
+# todo: destructors...
+# todo: syntax for inlining + other pragmas... as a macro, perhaps?
+# todo: slices
+
+type slice[T] = struct
+ data: ptr[T] # hrm...
+ length: uint