From 2a5b8646d6fc78d7c1876e45a7495338c838aa13 Mon Sep 17 00:00:00 2001 From: Brendan Hansen Date: Thu, 8 Dec 2022 10:36:19 -0600 Subject: [PATCH] bugfixes in standard library; added iter.skip_while --- core/alloc/gc.onyx | 6 +-- core/container/array.onyx | 14 ++++-- core/container/iter.onyx | 92 +++++++++++++++++++++++++++++++++++++++ core/string/string.onyx | 31 ++++++++++--- 4 files changed, 130 insertions(+), 13 deletions(-) diff --git a/core/alloc/gc.onyx b/core/alloc/gc.onyx index ac44b7b4..83eba584 100644 --- a/core/alloc/gc.onyx +++ b/core/alloc/gc.onyx @@ -52,10 +52,8 @@ auto :: #match { macro (body: Code) -> i32 { auto :: auto - #context_scope { - auto(); - #unquote body; - } + auto(); + #unquote body; return 0; } diff --git a/core/container/array.onyx b/core/container/array.onyx index be954731..051075c6 100644 --- a/core/container/array.onyx +++ b/core/container/array.onyx @@ -339,11 +339,13 @@ reverse :: (arr: [] $T) { // // Simple insertion sort // cmp should return >0 if left > right +// Returns the array to be used in '|>' chaining. +// NOT A COPY OF THE ARRAY. // sort :: #match #local {} #overload -sort :: (arr: [] $T, cmp: (T, T) -> i32) { +sort :: (arr: [] $T, cmp: (T, T) -> i32) -> [] T { for i: 1 .. arr.count { x := arr.data[i]; j := i - 1; @@ -360,10 +362,12 @@ sort :: (arr: [] $T, cmp: (T, T) -> i32) { arr.data[j + 1] = x; } + + return arr; } #overload -sort :: (arr: [] $T, cmp: (^T, ^T) -> i32) { +sort :: (arr: [] $T, cmp: (^T, ^T) -> i32) -> [] T { for i: 1 .. arr.count { j := i; @@ -376,11 +380,13 @@ sort :: (arr: [] $T, cmp: (^T, ^T) -> i32) { } } } + + return arr; } quicksort :: #match #locked { - (arr: [] $T, cmp: ( T, T) -> i32) do quicksort_impl(arr, cmp, 0, arr.count - 1); , - (arr: [] $T, cmp: (^T, ^T) -> i32) do quicksort_impl(arr, cmp, 0, arr.count - 1); , + (arr: [] $T, cmp: ( T, T) -> i32) => { quicksort_impl(arr, cmp, 0, arr.count - 1); return arr; }, + (arr: [] $T, cmp: (^T, ^T) -> i32) => { quicksort_impl(arr, cmp, 0, arr.count - 1); return arr; }, } #local { diff --git a/core/container/iter.onyx b/core/container/iter.onyx index 77f7bc38..d3e3fcab 100644 --- a/core/container/iter.onyx +++ b/core/container/iter.onyx @@ -313,6 +313,98 @@ skip :: (it: Iterator($T), count: u32, allocator := context.temp_allocator) -> I }; } +skip_while :: #match #local {} + +#overload +skip_while :: (it: Iterator($T), predicate: (T) -> bool, allocator := context.temp_allocator) -> Iterator(T) { + SkipIterator :: struct (T: type_expr) { + iterator: Iterator(T); + allocator: Allocator; + predicate: (T) -> bool; + skipped := false; + } + + skip_iterator := new(SkipIterator(T), allocator=allocator); + skip_iterator.iterator = it; + skip_iterator.allocator = allocator; + skip_iterator.predicate = predicate; + + next :: (si: ^SkipIterator($T)) -> (T, bool) { + while !si.skipped { + value, cont := si.iterator.next(si.iterator.data); + + if !cont { + si.skipped = true; + return value, false; + } + + if !si.predicate(value) { + si.skipped = true; + return value, true; + } + } + + return si.iterator.next(si.iterator.data); + } + + close :: (si: ^SkipIterator($T)) { + if si.iterator.close != null_proc do si.iterator.close(si.iterator.data); + raw_free(si.allocator, si); + } + + return .{ + data = skip_iterator, + next = #solidify next { T=T }, + close = #solidify close { T=T }, + }; +} + +#overload +skip_while :: (it: Iterator($T), ctx: $Ctx, predicate: (T, Ctx) -> bool, allocator := context.temp_allocator) -> Iterator(T) { + SkipIterator :: struct (T: type_expr, Ctx: type_expr) { + iterator: Iterator(T); + allocator: Allocator; + predicate: (T, Ctx) -> bool; + ctx: Ctx; + skipped := false; + } + + skip_iterator := new(SkipIterator(T, Ctx), allocator=allocator); + skip_iterator.iterator = it; + skip_iterator.allocator = allocator; + skip_iterator.predicate = predicate; + skip_iterator.ctx = ctx; + + next :: (si: ^SkipIterator($T, $Ctx)) -> (T, bool) { + while !si.skipped { + value, cont := si.iterator.next(si.iterator.data); + + if !cont { + si.skipped = true; + return value, false; + } + + if !si.predicate(value, si.ctx) { + si.skipped = true; + return value, true; + } + } + + return si.iterator.next(si.iterator.data); + } + + close :: (si: ^SkipIterator($T, $Ctx)) { + if si.iterator.close != null_proc do si.iterator.close(si.iterator.data); + raw_free(si.allocator, si); + } + + return .{ + data = skip_iterator, + next = #solidify next { T=T, Ctx=Ctx }, + close = #solidify close { T=T, Ctx=Ctx }, + }; +} + #local Zipped :: struct (T: type_expr, R: type_expr) { first: T; second: R; diff --git a/core/string/string.onyx b/core/string/string.onyx index 55ed6e80..bb19ac63 100644 --- a/core/string/string.onyx +++ b/core/string/string.onyx @@ -138,9 +138,10 @@ contains :: (s: str, c: u8) -> bool { #overload contains :: (s: str, substr: str) -> bool { while i := 0; i < s.count { + defer i += 1; + while j := 0; j < substr.count { if s[i + j] != substr[j] { - i += j + 1; continue continue; } @@ -253,17 +254,17 @@ index_of :: (s: str, c: u8) -> i32 { #overload index_of :: (s: str, substr: str) -> i32 { while i := 0; i < s.count { - start := i; + defer i += 1; + while j := 0; j < substr.count { if s[i + j] != substr[j] { - i += j + 1; continue continue; } j += 1; } - return start; + return i; } return -1; @@ -568,6 +569,9 @@ split :: (s: str, delim: u8, allocator := context.allocator) -> []str { return strarr[0 .. delim_count + 1]; } +split_iter :: #match #local {} + +#overload split_iter :: (s: str, delim: u8) -> Iterator(str) { return iter.generator( ^.{ s = s, delim = delim }, @@ -584,6 +588,23 @@ split_iter :: (s: str, delim: u8) -> Iterator(str) { ); } +#overload +split_iter :: (s: str, delim: str) -> Iterator(str) { + return iter.generator( + ^.{ s = s, delim = delim }, + + (ctx: ^$T) -> (str, bool) { + if string.empty(ctx.s) { + return "", false; + } + + ret: str; + ret, ctx.s = bisect(ctx.s, ctx.delim); + return ret, true; + } + ); +} + // // Splits a string into two parts, divided by the // first instance of the provided character. Either @@ -610,6 +631,6 @@ bisect :: (s: str, substr: str) -> (str, str) { return s, ""; } - return s[0 .. index], s[index+1 .. s.length]; + return s[0 .. index], s[index+substr.length .. s.length]; } -- 2.25.1