polymorhic solving bugfix and added quicksort
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Sat, 11 Sep 2021 22:49:51 +0000 (17:49 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Sat, 11 Sep 2021 22:49:51 +0000 (17:49 -0500)
bin/onyx
core/container/array.onyx
include/types.h
src/polymorph.c

index 3fd0ae4f8b665f81041d4bf7d736c7e887020337..fe7a9ff27dc1f51a074848f2edcd91d554ebeacb 100755 (executable)
Binary files a/bin/onyx and b/bin/onyx differ
index ceca3ae41f52788723f40e162886b7b25b1f7884..22be9629ff2c9327da7fc921370328bfc5fbfb07 100644 (file)
@@ -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);
index 448e803761e4a6f3b23658746b039f869d5f6e7a..481dd3eb845fa3759aee2b94444a1d0710de2731 100644 (file)
@@ -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; })                    \
index 7fa6442b7eae2489a62d2ef352284121b8e349c1..8320f48b976734fbe43f353348856499101ac6cd 100644 (file)
@@ -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;