From 576326c1c05e1787f8f0e09f891521629b228c29 Mon Sep 17 00:00:00 2001 From: Brendan Hansen Date: Fri, 26 Nov 2021 09:38:32 -0600 Subject: [PATCH] added functionality to list and iter packages --- core/container/iter.onyx | 75 +++++++++++++++++++++++++++++++--------- core/container/list.onyx | 70 +++++++++++++++++++++++++++++++++---- 2 files changed, 122 insertions(+), 23 deletions(-) diff --git a/core/container/iter.onyx b/core/container/iter.onyx index 4a52400f..698b40bb 100644 --- a/core/container/iter.onyx +++ b/core/container/iter.onyx @@ -287,23 +287,6 @@ enumerate :: #match {} }; } -fold :: (it: Iterator($T), initial_value: R, combine: (T, $R) -> R) -> R { - for value: it { - initial_value = combine(value, initial_value); - } - - return initial_value; -} - -to_array :: (it: Iterator($T), allocator := context.allocator) -> [..] T { - array :: package core.array - - arr := array.make(T, allocator=allocator); - for v: it do array.push(^arr, v); - - return arr; -} - #match as_iterator from_array from_array :: (arr: [] $T) -> Iterator(^T) { Context :: struct (T: type_expr) { @@ -377,3 +360,61 @@ from_array :: (arr: [] $T) -> Iterator(^T) { close = close, }; } + +fold :: #match {} +@Cleanup // some way to shorten this would be nice +#match fold macro (it: $T, init: $R, combine: $S) -> #auto where Iterable(T) { + fold :: fold + return fold(it, init, combine); +} + +#match fold (it: Iterator($T), initial_value: R, combine: (T, $R) -> R) -> R { + for value: it { + initial_value = combine(value, initial_value); + } + + return initial_value; +} + +count :: #match {} +#match count macro (it: $T, cond: $F) -> #auto where Iterable(T) { + count :: count + return count(it, cond); +} + +#match count (it: Iterator($T), cond: (T) -> bool) -> i32 { + c := 0; + for value: it do if cond(value) do c += 1; + return c; +} + +some :: #match {} +#match some macro (it: $T, cond: $F) -> #auto where Iterable(T) { + some :: some + return some(it, cond); +} + +#match some (it: Iterator($T), cond: (T) -> bool) -> bool { + for value: it do if cond(value) do return true; + return false; +} + +every :: #match {} +#match every macro (it: $T, cond: $F) -> #auto where Iterable(T) { + every :: every + return every(it, cond); +} + +#match every (it: Iterator($T), cond: (T) -> bool) -> bool { + for value: it do if !cond(value) do return false; + return true; +} + +to_array :: (it: Iterator($T), allocator := context.allocator) -> [..] T { + array :: package core.array + + arr := array.make(T, allocator=allocator); + for v: it do array.push(^arr, v); + + return arr; +} diff --git a/core/container/list.onyx b/core/container/list.onyx index 04c82d93..9d8ee581 100644 --- a/core/container/list.onyx +++ b/core/container/list.onyx @@ -13,12 +13,34 @@ List :: struct (T: type_expr) { first: ^ListElem(T) = null; last: ^ListElem(T) = null; + + // "Method" like things + free :: free + push_end :: push_end + push_begin :: push_begin + pop_end :: pop_end + pop_begin :: pop_begin + count :: count + at :: at + contains :: contains + fold :: fold + map :: map + get_iterator :: get_iterator } make :: ($T: type_expr, allocator := context.allocator) -> List(T) { return .{ allocator = allocator }; } +free :: (list: ^List($T)) { + elem := list.first; + while elem != null { + to_delete := elem; + elem = elem.next; + raw_free(list.allocator, elem); + } +} + push_end :: (list: ^List($T), x: T) { new_elem := allocate_elem(list); new_elem.data = x; @@ -63,6 +85,28 @@ pop_begin :: (list: ^List($T), default: T = __zero_value(T)) -> T { return begin.data; } +count :: (list: ^List($T)) -> i32 { + c := 0; + elem := list.first; + while elem != null { + c += 1; + elem = elem.next; + } + + return c; +} + +at :: (list: ^List($T), index: i32) -> ^T { + elem := list.first; + while elem != null { + if index == 0 do return ^elem.data; + index -= 1; + elem = elem.next; + } + + return null; +} + contains :: (list: ^List($T), x: T) -> bool { elem := list.first; while elem != null { @@ -85,11 +129,26 @@ fold :: (list: ^List($T), init: $R, f: (T, R) -> R) -> R { return val; } -// map :: #match { -// (list: ^List($T), f: (^T) -> void) { -// } -// } +map :: #match {} +#match map (list: ^List($T), f: (^T) -> void) { + elem := list.first; + while elem != null { + f(^elem.data); + elem = elem.next; + } +} + +#match map (list: ^List($T), f: (T) -> $R) -> List(R) { + new_list := make(R, allocator=list.allocator); + elem := list.first; + while elem != null { + push_end(new_list, f(elem.data)); + elem = elem.next; + } +} +#local iter :: package core.iter +#match iter.as_iterator get_iterator get_iterator :: (list: ^List($T)) -> Iterator(T) { iterator_next :: (list_iter: ^ListIterator($T)) -> (T, bool) { use package core.intrinsics.onyx { __zero_value } @@ -113,5 +172,4 @@ get_iterator :: (list: ^List($T)) -> Iterator(T) { }; } -#local -allocate_elem :: macro (list: ^List($T)) => new(ListElem(T), allocator=list.allocator); +#local allocate_elem :: macro (list: ^List($T)) => new(ListElem(T), allocator=list.allocator); -- 2.25.1