diff options
Diffstat (limited to 'std/prelude/lists.pk')
-rw-r--r-- | std/prelude/lists.pk | 109 |
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 |