From 99ce4edcc11745a3743db8913239e91319541199 Mon Sep 17 00:00:00 2001 From: Brendan Hansen Date: Fri, 10 Sep 2021 15:55:27 -0500 Subject: [PATCH] made the array functions work with slices too --- bin/onyx | Bin 435384 -> 435384 bytes core/container/array.onyx | 248 +++++++----------- core/container/set.onyx | 2 +- .../immediate_mode/immediate_renderer.onyx | 16 +- modules/wasm_utils/parser.onyx | 3 +- src/polymorph.c | 4 +- tests/aoc-2020/day10.onyx | 2 +- tests/aoc-2020/day19.onyx | 4 +- tests/aoc-2020/day21.onyx | 4 +- tests/aoc-2020/day23.onyx | 4 +- tests/aoc-2020/day5.onyx | 2 +- 11 files changed, 120 insertions(+), 169 deletions(-) diff --git a/bin/onyx b/bin/onyx index 0857ba0003720aa0040b276d1fba7f8f70e7e13f..fec3be71882c3b62898f97275da7d04413f84c89 100755 GIT binary patch delta 972 zcmZ8fU1$_n6ux)P&Stk7XNyU?t{U4oK_x^S*hs*nvYN<^jv8@Ws-iBjeJE0}+ECPJ zpgThxhVjX86@pTsQhbttov;*Ke?x2oV&WenQM54ANQ>3R#B{ly*%hij%$;-3J?FdM z`Mx_alo%LFoI3&)!zUNN*jF2y-ePn%W@;8LntlH#Bijc(eL&qlkb0-3Um|=|f*Ssr zkS6K=-VLxp>Wp%2RcKys4!)u~|CoYBkMOe;_R??pdwX)60lQhJ7`g&6Ni zWt-HnV&=IggGT@2i7+huD6tYq%1*2EnB7o?ae%+fOY?LXK9SbRyg3u9=CLqD>DT;J z7?Lw9UI`H(Ns2kd$HIv8l7CnR$+pu|0y(v)5#3IzEFiY+C1#xRN1G&sjrcllTTP)D z*$^SAte}c<08?5XV@X$9ANsp->s{wZ%RucWrDkVisrlK&`{-jq#wmZ$UMhGL^xpWg zAW{Q?RLmM=)@^@nkj=fHy@fNdY?m4#0awL1Rs`=-+jXb*n|~GWGCUfDqJZRMX`uEGAx&fuCzR4_Q5!_lB%cu7O*_T+N?pZ_DbMUQf;;T_0}Y_ zn=8H#(g`P3mG>&+*MaR;YPT?l6PSD+Pb*~5)QIoco*(yEE^4t~*sL^zJe-p@P} zg-@5>3uH3$ohLkH*SoTf_h}Q%98%1kD3o7R_9_283i0ldj{hs~FzXVtCjD9e2{9<2 z?*bBBUR2+&6sY@|w~C8y*hQTimajk|?9H*_TgDNqaqmTMzL^RsF>5s{aZNG*EIoq4 z7ZS-mL-Z=;S24Lb~DRgA&Z++iYo^9%-wD zN~zJqeWi|EUh4t5tqyKU7Q36UnSqfOQ^Gxbj|7c$p*bMI21+~490x>cW@wG-QnVKnw*BdB028O8-RGZW z@X>EP-wE?)fc~5we8)ieXL*gT4u(%aB9?!#rLgR2G z3*Quh46I}k*&YKLky+T7_LDd)K6<;>Ge>jIGiEv5RxB(C-;? zR|}9$+OQISjaLu!2?OHma2^$*<12}BZWS-~-~@Ykg9p~8y%Y9mv7_x)Ccox^?6i8c zBcAl{D}RmveIu4>tr>r8yI+nr0}+HtTjSGhH1z78Nj9HP8d$h`HL5hWdXt|f%ASw8 zmGR=gQaqFC>+yCE6m29mU8zPQ(Gg^4k-}&Y{f!il<6@oJkg)f;mMi&TJlH%w1%D3O zW4=#=SvfS#oLB&FWLj`)umJFJn1cm!(C;xXC+riK5_Zg7QYZVu^qsk5Sl$);2b0Ko AXaE2J diff --git a/core/container/array.onyx b/core/container/array.onyx index 2998fcb4..ceca3ae4 100644 --- a/core/container/array.onyx +++ b/core/container/array.onyx @@ -5,7 +5,7 @@ use package core.intrinsics.onyx { __zero_value } // [..] T == Array(T) // where // Array :: struct (T: type_expr) { -// data : T; +// data : ^T; // count : u32; // capacity : u32; // allocator : Allocator; @@ -139,7 +139,61 @@ pop :: (arr: ^[..] $T) -> T { return arr.data[arr.count]; } -transplant :: (arr: ^[..] $T, old_index: i32, new_index: i32) -> bool { +concat :: (arr: ^[..] $T, other: [..] T) { + for ^o: other do push(arr, *o); +} + + +fold_idx_elem :: #match { + (arr: ^[..] $T, cmp: (T, T) -> bool) -> (i32, T) { + return fold_idx_elem(arr.data, arr.count, cmp); + }, + + (arr: ^$T, count: i32, cmp: (T, T) -> bool) -> (i32, T) { + idx := 0; + elem := arr[0]; + + for i: 1 .. count { + if cmp(arr[i], elem) { + idx = i; + elem = arr[i]; + } + } + + return idx, elem; + }, +} + +#private_file cmp_greater :: (x: $T, y: T) -> bool do return x > y; +#private_file cmp_less :: (x: $T, y: T) -> bool do return x < y; + +greatest :: #match { + (arr: [..] $T) -> (i32, T) { return fold_idx_elem(arr.data, arr.count, cmp_greater); }, + (arr: [] $T) -> (i32, T) { return fold_idx_elem(arr.data, arr.count, cmp_greater); }, + (arr: [$N] $T) -> (i32, T) { return fold_idx_elem(cast(^T) arr, N, cmp_greater); }, +} + +least :: #match { + (arr: [..] $T) -> (i32, T) { return fold_idx_elem(arr.data, arr.count, cmp_less); }, + (arr: [] $T) -> (i32, T) { return fold_idx_elem(arr.data, arr.count, cmp_less); }, + (arr: [$N] $T) -> (i32, T) { return fold_idx_elem(cast(^T) arr, N, cmp_less); }, +} + + +// Useful structure when talking about dynamic arrays where you don't know of what +// type they store. For example, when passing a dynamic array as an 'any' argument. +Untyped_Array :: struct { + data: rawptr; + count: u32; + capacity: u32; + allocator: Allocator; +} + + + +// Things that work with slices and arrays + +transplant :: (arr: [] $T, old_index: i32, new_index: i32) -> bool { if old_index < 0 || old_index >= arr.count do return false; if new_index < 0 || new_index >= arr.count do return false; if old_index == new_index do return true; @@ -163,7 +217,7 @@ transplant :: (arr: ^[..] $T, old_index: i32, new_index: i32) -> bool { return true; } -get :: (arr: ^[..] $T, idx: i32) -> T { +get :: (arr: [] $T, idx: i32) -> T { if arr.count == 0 do return __zero_value(T); while idx < 0 do idx += arr.count; @@ -172,7 +226,7 @@ get :: (arr: ^[..] $T, idx: i32) -> T { return arr.data[idx]; } -get_ptr :: (arr: ^[..] $T, idx: i32) -> ^T { +get_ptr :: (arr: [] $T, idx: i32) -> ^T { if arr.count == 0 do return null; while idx < 0 do idx += arr.count; @@ -181,7 +235,7 @@ get_ptr :: (arr: ^[..] $T, idx: i32) -> ^T { return ^arr.data[idx]; } -set :: (arr: ^[..] $T, idx: i32, value: T) { +set :: (arr: [] $T, idx: i32, value: T) { if arr.count == 0 do return; while idx < 0 do idx += arr.count; @@ -190,75 +244,38 @@ set :: (arr: ^[..] $T, idx: i32, value: T) { arr.data[idx] = value; } -concat :: (arr: ^[..] $T, other: [..] T) { - for ^o: other do push(arr, *o); -} - // Uses '==' to compare for equality. -contains :: #match { - (arr: ^[..] $T, x: T) -> bool { - for it: *arr do if it == x do return true; - return false; - }, - - (arr: [] $T, x: T) -> bool { - for it: arr do if it == x do return true; - return false; - } +contains :: (arr: [] $T, x: T) -> bool { + for it: arr do if it == x do return true; + return false; } // Uses '+' to sum. -sum :: #match { - (arr: ^[..] $T, start: T = 0) -> T { - sum := start; - for it: *arr do sum += it; - return sum; - }, - - (arr: [] $T, start: T = 0) -> T { - sum := start; - for it: arr do sum += it; - return sum; - } +sum :: (arr: [] $T, start: T = 0) -> T { + sum := start; + for it: arr do sum += it; + return sum; } -product :: #match { - (arr: ^[..] $T, start: T = 1) -> T { - sum := start; - for it: *arr do sum *= it; - return sum; - }, - - (arr: [] $T, start: T = 1) -> T { - sum := start; - for it: arr do sum *= it; - return sum; - } +product :: (arr: [] $T, start: T = 1) -> T { + prod := start; + for it: arr do prod *= it; + return prod; } -average :: (arr: ^[..] $T) -> T { +average :: (arr: [] $T) -> T { sum := cast(T) 0; for it: *arr do sum += it; return sum / cast(T) arr.count; } -to_slice :: #match { - (arr: [..] $T) -> [] T { - return arr.data[0 .. arr.count]; - }, - - (arr: ^[..] $T) -> [] T { - return arr.data[0 .. arr.count]; - }, -} - -/* -** Simple insertion sort -** cmp should return >0 if left > right -*/ +// +// Simple insertion sort +// cmp should return >0 if left > right +// sort :: #match { - (arr: ^[..] $T, cmp: (T, T) -> i32) { + (arr: [] $T, cmp: (T, T) -> i32) { for i: 1 .. arr.count { x := arr.data[i]; j := i - 1; @@ -277,7 +294,7 @@ sort :: #match { } }, - (arr: ^[..] $T, cmp: (^T, ^T) -> i32) { + (arr: [] $T, cmp: (^T, ^T) -> i32) { for i: 1 .. arr.count { j := i; @@ -293,26 +310,13 @@ sort :: #match { } } -fold :: #match { - (arr: ^[..] $T, init: $R, f: (T, R) -> R) -> R { - val := init; - for it: *arr do val = f(it, val); - return val; - }, - - (arr: [] $T, init: $R, f: (T, R) -> R) -> R { - val := init; - for it: arr do val = f(it, val); - return val; - } +fold :: (arr: [] $T, init: $R, f: (T, R) -> R) -> R { + val := init; + for it: arr do val = f(it, val); + return val; } map :: #match { - macro (arr: [..] $T, f: (^T) -> void) do for ^it: arr do f(it);, - macro (arr: [..] $T, f: (T) -> T) do for ^it: arr do *it = f(*it);, - macro (arr: [..] $T, body: Code) do for ^it: arr do #insert body;, - macro (arr: [..] $T, data: $R, f: (^T, R) -> void) do for ^it: arr do f(it, data);, - macro (arr: [..] $T, data: $R, f: (T, R) -> T) do for ^it: arr do *it = f(*it, data);, macro (arr: [] $T, f: (^T) -> void) do for ^it: arr do f(it);, macro (arr: [] $T, f: (T) -> T) do for ^it: arr do *it = f(*it);, macro (arr: [] $T, body: Code) do for ^it: arr do #insert body;, @@ -320,45 +324,45 @@ map :: #match { macro (arr: [] $T, data: $R, f: (T, R) -> T) do for ^it: arr do *it = f(*it, data);, } -every :: (arr: ^[..] $T, predicate: (T) -> bool) -> bool { +every :: (arr: [] $T, predicate: (T) -> bool) -> bool { val := true; - for ^it: *arr do val = val && predicate(*it); + for ^it: arr do val = val && predicate(*it); return val; } -some :: (arr: ^[..] $T, predicate: (T) -> bool) -> bool { +some :: (arr: [] $T, predicate: (T) -> bool) -> bool { val := false; - for ^it: *arr { + for ^it: arr { val = val || predicate(*it); if val do break; } return val; } -fill :: (arr: ^[..] $T, value: T) { +fill :: (arr: [] $T, value: T) { for i: arr.count { - arr.data[i] = value; + arr[i] = value; } } -fill_range :: (arr: ^[..] $T, r: range, value: T) { +fill_range :: (arr: [] $T, r: range, value: T) { for i: r { if i >= arr.count || i < 0 do continue; - arr.data[i] = value; + arr[i] = value; } } -to_list :: (arr: ^[..] $T, allocator := context.allocator) -> List(T) { +to_list :: (arr: [] $T, allocator := context.allocator) -> List(T) { new_list := list.make(T, allocator); - for ^it: *arr { + for ^it: arr { list.push_end(^new_list, *it); } return new_list; } -find :: (arr: ^[..] $T, value: T) -> i32 { +find :: (arr: [] $T, value: T) -> i32 { for i: arr.count { if value == arr.data[i] do return i; } @@ -366,33 +370,23 @@ find :: (arr: ^[..] $T, value: T) -> i32 { return -1; } -find_ptr :: (arr: ^[..] $T, value: T) -> ^T { - for ^it: *arr { +find_ptr :: (arr: [] $T, value: T) -> ^T { + for ^it: arr { if value == *it do return it; } return null; } -first :: #match { - (arr: ^[..] $T, predicate: (T) -> bool) -> ^T { - first((#type [] T).{ arr.data, arr.count }, predicate); - }, - - (arr: [] $T, predicate: (T) -> bool) -> ^T { - for ^it: arr { - if predicate(*it) do return it; - } +first :: (arr: [] $T, predicate: (T) -> bool) -> ^T { + for ^it: arr { + if predicate(*it) do return it; + } - return null; - }, + return null; } count_where :: #match { - (arr: ^[..] $T, predicate: $Pred) -> u32 { - return count_where((#type [] T).{ arr.data, arr.count }, predicate); - }, - (arr: [] $T, predicate: (T) -> bool) -> u32 { count: u32 = 0; for ^it: arr do if predicate(*it) do count += 1; @@ -406,47 +400,3 @@ count_where :: #match { }, } -fold_idx_elem :: #match { - (arr: ^[..] $T, cmp: (T, T) -> bool) -> (i32, T) { - return fold_idx_elem(arr.data, arr.count, cmp); - }, - - (arr: ^$T, count: i32, cmp: (T, T) -> bool) -> (i32, T) { - idx := 0; - elem := arr[0]; - - for i: 1 .. count { - if cmp(arr[i], elem) { - idx = i; - elem = arr[i]; - } - } - - return idx, elem; - }, -} - -#private_file cmp_greater :: (x: $T, y: T) -> bool do return x > y; -#private_file cmp_less :: (x: $T, y: T) -> bool do return x < y; - -greatest :: #match { - (arr: [..] $T) -> (i32, T) { return fold_idx_elem(arr.data, arr.count, cmp_greater); }, - (arr: [] $T) -> (i32, T) { return fold_idx_elem(arr.data, arr.count, cmp_greater); }, - (arr: [$N] $T) -> (i32, T) { return fold_idx_elem(cast(^T) arr, N, cmp_greater); }, -} - -least :: #match { - (arr: [..] $T) -> (i32, T) { return fold_idx_elem(arr.data, arr.count, cmp_less); }, - (arr: [] $T) -> (i32, T) { return fold_idx_elem(arr.data, arr.count, cmp_less); }, - (arr: [$N] $T) -> (i32, T) { return fold_idx_elem(cast(^T) arr, N, cmp_less); }, -} - - -// Useful structure when talking about dynamic arrays where you don't know of what -// type they store. For example, when passing a dynamic array as an 'any' argument. -Untyped_Array :: struct { - data: rawptr; - count: u32; - capacity: u32; - allocator: Allocator; -} diff --git a/core/container/set.onyx b/core/container/set.onyx index e15a43a7..1946ee60 100644 --- a/core/container/set.onyx +++ b/core/container/set.onyx @@ -25,7 +25,7 @@ make :: ($T: type_expr, default := __zero_value(T), hash_count: i32 = 16) -> Set init :: (use set: ^Set($T), default := __zero_value(T), hash_count: i32 = 16) { array.init(^hashes, hash_count); hashes.count = hash_count; - array.fill(^hashes, -1); + array.fill(hashes, -1); array.init(^entries, 4); diff --git a/modules/immediate_mode/immediate_renderer.onyx b/modules/immediate_mode/immediate_renderer.onyx index f34242d9..ccdf9acb 100644 --- a/modules/immediate_mode/immediate_renderer.onyx +++ b/modules/immediate_mode/immediate_renderer.onyx @@ -92,7 +92,7 @@ Immediate_Renderer :: struct { world_transform_stack = array.make(Transform, capacity=1); array.insert_empty(^world_transform_stack, 0); - transform_identity(array.get_ptr(^world_transform_stack, -1)); + transform_identity(array.get_ptr(world_transform_stack, -1)); scissor_stack = array.make(Scissor_State); @@ -128,7 +128,7 @@ Immediate_Renderer :: struct { gl.bindBuffer(gl.ARRAY_BUFFER, -1); - world_transform := array.get_ptr(^world_transform_stack, -1); + world_transform := array.get_ptr(world_transform_stack, -1); world_matrix := transform_to_matrix(world_transform); gl.uniformMatrix4(shader.world_uniform, false, world_matrix); @@ -148,7 +148,7 @@ Immediate_Renderer :: struct { if world_transform_dirty { world_transform_dirty = false; - world_transform := array.get_ptr(^world_transform_stack, -1); + world_transform := array.get_ptr(world_transform_stack, -1); world_matrix := transform_to_matrix(world_transform); for shader: (#type ^Shader).[ ^simple_shader, ^textured_shader, ^alpha_shader ] { @@ -384,7 +384,7 @@ Immediate_Renderer :: struct { world_transform_dirty = true; array.push(^world_transform_stack, world_transform_stack[world_transform_stack.count - 1]); - *array.get_ptr(^world_transform_stack, -1) = *array.get_ptr(^world_transform_stack, -2); + *array.get_ptr(world_transform_stack, -1) = *array.get_ptr(world_transform_stack, -2); // transform_identity(array.get_ptr(^world_transform_stack, -1)); } @@ -397,15 +397,15 @@ Immediate_Renderer :: struct { } identity :: (use ir: ^Immediate_Renderer) { - transform_identity(array.get_ptr(^world_transform_stack, -1)); + transform_identity(array.get_ptr(world_transform_stack, -1)); } get_transform :: (use ir: ^Immediate_Renderer) -> ^Transform { - return array.get_ptr(^world_transform_stack, -1); + return array.get_ptr(world_transform_stack, -1); } apply_transform :: (use ir: ^Immediate_Renderer, transform: Transform) { - transform_apply(array.get_ptr(^world_transform_stack, -1), transform); + transform_apply(array.get_ptr(world_transform_stack, -1), transform); world_transform_dirty = true; } @@ -526,4 +526,4 @@ save_matrix :: macro () { I.push_matrix(); defer I.pop_matrix(); -} \ No newline at end of file +} diff --git a/modules/wasm_utils/parser.onyx b/modules/wasm_utils/parser.onyx index 3475f97c..7d83b963 100644 --- a/modules/wasm_utils/parser.onyx +++ b/modules/wasm_utils/parser.onyx @@ -275,8 +275,7 @@ parse_code_section :: (use bin: ^WasmBinary, allocator := context.allocator) -> _, pos := io.stream_tell(reader.stream); io.stream_seek(reader.stream, before_locals + size, .Start); - locals_slice := array.copy_range(^locals, 0 .. local_index, allocator=wasm_allocator) - |> array.to_slice(); + locals_slice: [] WasmLocal = array.copy_range(^locals, 0 .. local_index, allocator=wasm_allocator); return .{ size, locals_slice, pos }; } diff --git a/src/polymorph.c b/src/polymorph.c index e5e70971..7fa6442b 100644 --- a/src/polymorph.c +++ b/src/polymorph.c @@ -277,11 +277,13 @@ static PolySolveResult solve_poly_type(AstNode* target, AstType* type_expr, Type } case Ast_Kind_Slice_Type: { - if (elem.actual->kind != Type_Kind_Slice) break; + if (elem.actual->kind != Type_Kind_Slice && elem.actual->kind != Type_Kind_DynArray && elem.actual->kind != Type_Kind_VarArgs) 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. .actual = elem.actual->Slice.elem, })); break; diff --git a/tests/aoc-2020/day10.onyx b/tests/aoc-2020/day10.onyx index 81fa2746..31f764e8 100644 --- a/tests/aoc-2020/day10.onyx +++ b/tests/aoc-2020/day10.onyx @@ -40,7 +40,7 @@ main :: (args: [] cstr) { array.push(^nums, 0); cmp_asc :: (a: $T, b: T) -> i32 do return ~~(a - b); - array.sort(^nums, cmp_asc); + array.sort(nums, cmp_asc); diffs: [3] u32; for ^d: diffs do *d = 0; diff --git a/tests/aoc-2020/day19.onyx b/tests/aoc-2020/day19.onyx index 3327b85f..1adaed1f 100644 --- a/tests/aoc-2020/day19.onyx +++ b/tests/aoc-2020/day19.onyx @@ -63,11 +63,11 @@ grammar_prepare :: (use g: ^Grammar) { } } - array.sort(^terminate_rules, (a: Term, b: Term) -> i32 { + array.sort(terminate_rules, (a: Term, b: Term) -> i32 { return (cast(i32) a.nt) - (cast(i32) b.nt); }); - array.sort(^production_rules, (a: Prod, b: Prod) -> i32 { + array.sort(production_rules, (a: Prod, b: Prod) -> i32 { return (cast(i32) a.nt0) - (cast(i32) b.nt0); }); diff --git a/tests/aoc-2020/day21.onyx b/tests/aoc-2020/day21.onyx index f10729d8..a2326d1a 100644 --- a/tests/aoc-2020/day21.onyx +++ b/tests/aoc-2020/day21.onyx @@ -143,7 +143,7 @@ main :: (args: [] cstr) { matches := true; for ap: allergen_entry.value.appears_on { - if !array.contains(^ingredient_entry.value.appears_on, ap) do matches = false; + if !array.contains(ingredient_entry.value.appears_on, ap) do matches = false; } if matches { @@ -162,7 +162,7 @@ main :: (args: [] cstr) { } } - array.sort(^matched_ingredients, (i1: ^Ingredient, i2: ^Ingredient) -> i32 { + array.sort(matched_ingredients, (i1: ^Ingredient, i2: ^Ingredient) -> i32 { return string.compare(i1.allergen, i2.allergen); }); diff --git a/tests/aoc-2020/day23.onyx b/tests/aoc-2020/day23.onyx index 7f64f0cc..b51cf013 100644 --- a/tests/aoc-2020/day23.onyx +++ b/tests/aoc-2020/day23.onyx @@ -68,7 +68,7 @@ main :: (args: [] cstr) { // Part 2 for i: 9 .. 1000000 do array.push(^cups, i); - simulate(array.to_slice(^cups), 10000000); + simulate(cups, 10000000); // Undo the zero-indexing for ^cup: cups do *cup += 1; @@ -81,7 +81,7 @@ main :: (args: [] cstr) { // printf("\n"); // Part 2 - one_idx := get_idx(array.to_slice(^cups), 1); + one_idx := get_idx(cups, 1); prod: i64 = cast(i64) (cups[w(one_idx + 1)]) * cast(i64) (cups[w(one_idx + 2)]); printf("Cup product: {}\n", prod); } diff --git a/tests/aoc-2020/day5.onyx b/tests/aoc-2020/day5.onyx index 0fa91620..98bc6f36 100644 --- a/tests/aoc-2020/day5.onyx +++ b/tests/aoc-2020/day5.onyx @@ -26,7 +26,7 @@ main :: (args: [] cstr) { } missing := 0; - array.sort(^vals, cmp_asc); + array.sort(vals, cmp_asc); for i: 0 .. vals.count - 1 { if vals[i + 1] - vals[i] != 1 do missing = vals[i] + 1; } -- 2.25.1