From: Brendan Hansen Date: Sat, 11 Sep 2021 22:49:51 +0000 (-0500) Subject: polymorhic solving bugfix and added quicksort X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=4d1094bd4f8169b93a46f05007a1cb7233a3f051;p=onyx.git polymorhic solving bugfix and added quicksort --- diff --git a/bin/onyx b/bin/onyx index 3fd0ae4f..fe7a9ff2 100755 Binary files a/bin/onyx and b/bin/onyx differ diff --git a/core/container/array.onyx b/core/container/array.onyx index ceca3ae4..22be9629 100644 --- a/core/container/array.onyx +++ b/core/container/array.onyx @@ -310,6 +310,52 @@ sort :: #match { } } +quicksort :: #match { + (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); , +} + +#private_file { + quicksort_impl :: (arr: [] $T, cmp: $PredicateFunction, lo, hi: i32) { + if lo < 0 || hi < 0 do return; + if lo >= hi do return; + + pivot := quicksort_partition(arr, cmp, lo, hi); + quicksort_impl(arr, cmp, lo, pivot - 1); + quicksort_impl(arr, cmp, pivot + 1, hi); + } + + quicksort_partition :: #match { + (arr: [] $T, cmp: (T, T) -> i32, lo, hi: i32) -> i32 { + pivot := arr[hi]; + i := lo - 1; + + for j: lo .. hi+1 { + if cmp(arr[j], pivot) <= 0 { + i += 1; + arr[i], arr[j] = arr[j], arr[i]; + } + } + + return i; + }, + + (arr: [] $T, cmp: (^T, ^T) -> i32, lo, hi: i32) -> i32 { + pivot := ^arr[hi]; + i := lo - 1; + + for j: lo .. hi+1 { + if cmp(^arr[j], pivot) <= 0 { + i += 1; + arr[i], arr[j] = arr[j], arr[i]; + } + } + + return i; + } + } +} + fold :: (arr: [] $T, init: $R, f: (T, R) -> R) -> R { val := init; for it: arr do val = f(it, val); diff --git a/include/types.h b/include/types.h index 448e8037..481dd3eb 100644 --- a/include/types.h +++ b/include/types.h @@ -112,7 +112,7 @@ struct TypeWithOffset { bh_arr(TypeWithOffset) linear_members; \ Type* types[]; \ }) \ - TYPE_KIND(Array, struct { u32 size; u32 count; Type *elem; }) \ + TYPE_KIND(Array, struct { Type* elem; u32 size; u32 count; }) \ TYPE_KIND(Slice, struct { Type *elem; }) \ TYPE_KIND(DynArray, struct { Type *elem; }) \ TYPE_KIND(VarArgs, struct { Type *elem; }) \ diff --git a/src/polymorph.c b/src/polymorph.c index 7fa6442b..8320f48b 100644 --- a/src/polymorph.c +++ b/src/polymorph.c @@ -277,13 +277,14 @@ static PolySolveResult solve_poly_type(AstNode* target, AstType* type_expr, Type } case Ast_Kind_Slice_Type: { - if (elem.actual->kind != Type_Kind_Slice && elem.actual->kind != Type_Kind_DynArray && elem.actual->kind != Type_Kind_VarArgs) break; + if (elem.actual->kind != Type_Kind_Slice && elem.actual->kind != Type_Kind_DynArray + && elem.actual->kind != Type_Kind_VarArgs && elem.actual->kind != Type_Kind_Array) break; bh_arr_push(elem_queue, ((PolySolveElem) { .type_expr = ((AstSliceType *) elem.type_expr)->elem, .kind = PSK_Type, - // HACK: This makes the assumption that slices, dynamic arrays and varargs have the same element type at the same location. + // HACK: This makes the assumption that arrays, slices, dynamic arrays and varargs have the same element type at the same location. .actual = elem.actual->Slice.elem, })); break;