Created
April 3, 2023 00:12
-
-
Save yorickpeterse/03c84cd278ee6993b35071742d8243cf to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import std::drop::(Drop) | |
import std::stdio::STDOUT | |
import std::iter::Iter | |
class Node[T] { | |
let @next: Option[Node[T]] | |
let @prev: Option[mut Node[T]] | |
let @value: T | |
fn mut take_next -> Option[Node[T]] { | |
@next := Option.None | |
} | |
fn move into_value -> T { | |
@value | |
} | |
} | |
class List[T] { | |
let @head: Option[Node[T]] | |
let @tail: Option[mut Node[T]] | |
fn static new -> List[T] { | |
List { @head = Option.None, @tail = Option.None } | |
} | |
fn mut push(value: T) { | |
let node = Node { | |
@next = Option.None, | |
@prev = @tail.as_mut, | |
@value = value | |
} | |
let tail = Option.Some(mut node) | |
match @tail { | |
case Some(n) -> { | |
@tail = tail | |
n.next = Option.Some(node) | |
} | |
case _ -> { | |
@head = Option.Some(node) | |
@tail = tail | |
} | |
} | |
} | |
fn mut pop -> Option[T] { | |
match @tail { | |
case Some(tail_ref) -> match tail_ref.prev { | |
case Some(before_tail) -> match before_tail.take_next { | |
case Some({ @value = value }) -> { | |
@tail = Option.Some(before_tail) | |
Option.Some(value) | |
} | |
case _ -> Option.None | |
} | |
# The tail points to the first node. | |
case _ -> { | |
match @head := Option.None { | |
case Some({ @value = value }) -> { | |
@tail = Option.None | |
Option.Some(value) | |
} | |
case _ -> Option.None | |
} | |
} | |
} | |
case _ -> Option.None | |
} | |
} | |
fn iter -> Iterator[T] { | |
Iterator { @node = @head.as_ref } | |
} | |
} | |
class Iterator[T] { | |
let @node: Option[ref Node[T]] | |
} | |
impl Iter[ref T, Never] for Iterator { | |
fn pub mut next -> Option[ref T] { | |
match @node { | |
case Some(node) -> { | |
@node = node.next.as_ref | |
Option.Some(node.value) | |
} | |
case _ -> Option.None | |
} | |
} | |
} | |
impl Drop for List { | |
fn mut drop { | |
while pop.some? {} | |
} | |
} | |
class async Main { | |
fn async main { | |
let list = List.new | |
let out = STDOUT.new | |
list.push(10) | |
list.push(20) | |
list.iter.each fn (val) { out.print(val.to_string) } | |
out.print(list.pop.unwrap.to_string) | |
out.print(list.pop.unwrap.to_string) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment