From c0fdb048553de4935582349d9b5c6fa448cf2fe1 Mon Sep 17 00:00:00 2001 From: Brendan Hansen Date: Tue, 1 Sep 2020 09:33:07 -0500 Subject: [PATCH] refactoring core arrays --- core/array.onyx | 109 ++++++++++++++++++++++ core/builtin.onyx | 111 +---------------------- core/std/js.onyx | 1 + core/std/wasi.onyx | 1 + docs/plan | 22 +++-- onyx | Bin 586696 -> 586696 bytes progs/poly_test.onyx | 7 +- progs/stack_based.onyx | 200 ----------------------------------------- src/onyxparser.c | 4 +- 9 files changed, 130 insertions(+), 325 deletions(-) create mode 100644 core/array.onyx delete mode 100644 progs/stack_based.onyx diff --git a/core/array.onyx b/core/array.onyx new file mode 100644 index 00000000..2498d4a4 --- /dev/null +++ b/core/array.onyx @@ -0,0 +1,109 @@ +package core + +// --------------------------------- +// Dynamic Arrays +// --------------------------------- +array_init :: proc (arr: ^[..] $T, initial_cap := 4) { + arr.count = 0; + arr.capacity = initial_cap; + arr.data = calloc(sizeof T * arr.capacity); +} + +array_free :: proc (arr: ^[..] $T) { + arr.count = 0; + arr.capacity = 0; + + cfree(arr.data); + arr.data = null; +} + +array_clear :: proc (arr: ^[..] $T) { + arr.count = 0; +} + +array_ensure_capacity :: proc (arr: ^[..] $T, cap: u32) { + if arr.capacity >= cap do return; + + while cap > arr.capacity do arr.capacity <<= 1; + arr.data = cresize(arr.data, sizeof T * arr.capacity); +} + +array_push :: proc (arr: ^[..] $T, x: T) { + array_ensure_capacity(arr, arr.count + 1); + arr.data[arr.count] = x; + arr.count += 1; +} + +array_insert :: proc (arr: ^[..] $T, idx: u32, x: T) { + array_ensure_capacity(arr, arr.count + 1); + + arr.count += 1; + while i := arr.count; i > idx { + arr.data[i] = arr.data[i - 1]; + i -= 1; + } + + arr.data[idx] = x; +} + +array_remove :: proc (arr: ^[..] $T, elem: T) { + move := 0; + + for i: 0, arr.count - move { + if arr.data[i + move] == elem do move += 1; + if move != 0 do arr.data[i] = arr.data[i + move]; + } + + arr.count -= move; +} + +array_delete :: proc (arr: ^[..] $T, idx: u32) { + if idx >= arr.count do return; + + for i: idx, arr.count - 1 { + arr.data[i] = arr.data[i + 1]; + } + + arr.count -= 1; +} + +array_contains :: proc (arr: ^[..] $T, x: T) -> bool { + for i: 0, arr.count do if arr.data[i] == x do return true; + return false; +} + +array_pop :: proc (arr: ^[..] $T) -> T { + arr.count -= 1; + return arr.data[arr.count]; +} + +array_average :: proc (arr: ^[..] $T) -> T { + sum := cast(T) 0; + for i: 0, arr.count { + sum += arr.data[i]; + } + + return sum / cast(T) arr.count; +} + +array_to_slice :: proc (arr: ^[..] $T) -> [] T { + return arr.data[0 : arr.count]; +} + +/* +** Simple insertion sort +** cmp should return >0 if left > right +*/ +array_sort :: proc (arr: ^[..] $T, cmp: proc (T, T) -> i32) { + for i: 1, arr.count { + x := arr.data[i]; + j := i - 1; + + while j >= 0 && cmp(arr.data[j], x) > 0 { + arr.data[j + 1] = arr.data[j]; + j -= 1; + } + + arr.data[j + 1] = x; + } +} diff --git a/core/builtin.onyx b/core/builtin.onyx index d7406441..f8b1d2dc 100644 --- a/core/builtin.onyx +++ b/core/builtin.onyx @@ -41,116 +41,7 @@ calloc :: proc (size: u32) -> rawptr do return alloc(context.allocator, size); cresize :: proc (ptr: rawptr, size: u32) -> rawptr do return resize(context.allocator, ptr, size); cfree :: proc (ptr: rawptr) do free(context.allocator, ptr); - - -// --------------------------------- -// Dynamic Arrays -// --------------------------------- -array_init :: proc (arr: ^[..] $T, initial_cap := 4) { - arr.count = 0; - arr.capacity = initial_cap; - arr.data = calloc(sizeof T * arr.capacity); -} - -array_free :: proc (arr: ^[..] $T) { - arr.count = 0; - arr.capacity = 0; - - cfree(arr.data); - arr.data = null; -} - -array_clear :: proc (arr: ^[..] $T) { - arr.count = 0; -} - -array_ensure_capacity :: proc (arr: ^[..] $T, cap: u32) { - if arr.capacity >= cap do return; - - while cap > arr.capacity do arr.capacity <<= 1; - arr.data = cresize(arr.data, sizeof T * arr.capacity); -} - -array_push :: proc (arr: ^[..] $T, x: T) { - array_ensure_capacity(arr, arr.count + 1); - arr.data[arr.count] = x; - arr.count += 1; -} - -array_insert :: proc (arr: ^[..] $T, idx: u32, x: T) { - array_ensure_capacity(arr, arr.count + 1); - - arr.count += 1; - while i := arr.count; i > idx { - arr.data[i] = arr.data[i - 1]; - i -= 1; - } - - arr.data[idx] = x; -} - -array_remove :: proc (arr: ^[..] $T, elem: T) { - move := 0; - - for i: 0, arr.count - move { - if arr.data[i + move] == elem do move += 1; - if move != 0 do arr.data[i] = arr.data[i + move]; - } - - arr.count -= move; -} - -array_delete :: proc (arr: ^[..] $T, idx: u32) { - if idx >= arr.count do return; - - for i: idx, arr.count - 1 { - arr.data[i] = arr.data[i + 1]; - } - - arr.count -= 1; -} - -array_contains :: proc (arr: ^[..] $T, x: T) -> bool { - for i: 0, arr.count do if arr.data[i] == x do return true; - return false; -} - -array_pop :: proc (arr: ^[..] $T) -> T { - arr.count -= 1; - return arr.data[arr.count]; -} - -array_average :: proc (arr: ^[..] $T) -> T { - sum := cast(T) 0; - for i: 0, arr.count { - sum += arr.data[i]; - } - - return sum / cast(T) arr.count; -} - -array_to_slice :: proc (arr: ^[..] $T) -> [] T { - return arr.data[0 : arr.count]; -} - -// -// Simple insertion sort -// cmp should return >0 if left > right -// -array_sort :: proc (arr: ^[..] $T, cmp: proc (T, T) -> i32) { - for i: 1, arr.count { - x := arr.data[i]; - j := i - 1; - - while j >= 0 && cmp(arr.data[j], x) > 0 { - arr.data[j + 1] = arr.data[j]; - j -= 1; - } - - arr.data[j + 1] = x; - } -} - +// @CLEANUP: These need to move to somewhere else eventually cmp_asc :: proc (a: $T, b: T) -> i32 do return cast(i32) (a - b); cmp_dec :: proc (a: $T, b: T) -> i32 do return cast(i32) (b - a); diff --git a/core/std/js.onyx b/core/std/js.onyx index df151685..8650a2a4 100644 --- a/core/std/js.onyx +++ b/core/std/js.onyx @@ -3,6 +3,7 @@ package core use package builtin #include_file "core/alloc" +#include_file "core/array" #include_file "core/intrinsics" #include_file "core/math" #include_file "core/memory" diff --git a/core/std/wasi.onyx b/core/std/wasi.onyx index 13c24ffb..518befb8 100644 --- a/core/std/wasi.onyx +++ b/core/std/wasi.onyx @@ -3,6 +3,7 @@ package core use package builtin #include_file "core/alloc" +#include_file "core/array" #include_file "core/file" #include_file "core/intrinsics" #include_file "core/math" diff --git a/docs/plan b/docs/plan index 32e05738..4d0d53ce 100644 --- a/docs/plan +++ b/docs/plan @@ -226,19 +226,27 @@ HOW: [X] #file and #line directives - string and u32 respectively that represent the current file and line number where the directive is - [ ] transmute - - [ ] explicit memory controls at top level - - [ ] Put type info in data section so it is runtime accessible + [ ] ** Put type info in data section so it is runtime accessible - type name - size - alignment - struct member names - array length + [ ] Type parameterized structs + + [ ] Array literals + + [ ] transmute + + [ ] explicit memory controls at top level + [ ] 'use' enums and packages at an arbitrary scope + [ ] look into creating a source map + - first-look looks really gross + - whoever came up with the source map spec should be fired... why are people so afraid of binary files?? + [ ] convert to using an 'atom' like table - All identifier tokens are given a unique atom ptr, up to string equality. - This means identifiers can be compared using ptr comparison, instead of string comparison @@ -255,8 +263,6 @@ HOW: - Compile time conditions - Only evalutate code blocks that evaluate to be true - [ ] Array literals - [ ] Top level variable initialization - Works for numeric literals @@ -267,8 +273,6 @@ HOW: [ ] All code paths return correct value - [ ] Type parameterized structs - [ ] Arrays need to be much better - Currently, they are basically just a pointer. - The length should be stored with the pointer diff --git a/onyx b/onyx index 59cbb27a1016132ac78f5036ebf4353b3347dc7c..8f0b89377acc2682f23f7a5cbd81ac7ea1e815d2 100755 GIT binary patch delta 35164 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 diff --git a/progs/poly_test.onyx b/progs/poly_test.onyx index b8b9ba62..de6a34f6 100644 --- a/progs/poly_test.onyx +++ b/progs/poly_test.onyx @@ -42,13 +42,12 @@ Dummy :: struct { /* TODO: Make this work at some point - compose :: proc (a: $A, f: proc (A) -> $B, g: proc (B) -> $C) -> C { - return a |> f() |> g(); - } +compose :: proc (a: $A, f: proc (A) -> $B, g: proc (B) -> $C) -> C { + return a |> f() |> g(); +} */ - SOA :: struct { b : [..] i64; a : [..] i32; diff --git a/progs/stack_based.onyx b/progs/stack_based.onyx deleted file mode 100644 index 4291c9f2..00000000 --- a/progs/stack_based.onyx +++ /dev/null @@ -1,200 +0,0 @@ -package main - -#include_folder "/usr/share/onyx/core" - -#include_file "printing" -#include_file "alloc" -#include_file "string" -#include_file "wasi" - -use package printing -use package memory -use package core -use package wasi - -sort :: proc (arr: [N]i32, cmp: proc (i32, i32) -> i32) -> [N] i32 { - for i: 0, N { - smallest_idx := i; - - for j: i, N do if cmp(arr[j], arr[smallest_idx]) < 0 do smallest_idx = j; - - tmp :: arr[i]; - arr[i] = arr[smallest_idx]; - arr[smallest_idx] = tmp; - } - - return arr; -} - -ret_val :: proc (x: i32, y: i32) -> i32 { - big_arr : [128] i32; - big_arr[0] = 1234; - big_arr[1] = 1234; - big_arr[127] = 1234; - return big_arr[127] + x + y; -} - -N :: 10 - -sumN :: proc (x: [N] i32) -> i32 { - s := 0; - for i: 0, N do s += x[i]; - return s; -} - -summing :: proc (x: ^i32) -> i32 { - s := 0; - for i: 0, N do s += x[i]; - return s; -} - -get_value :: proc (x: i32, y: i32) -> i32 { - return x + 2 * y; -} - -Vec3 :: struct { - x: i32 = get_value(10, 20); - y: i32 = 0; - z: i32 = 0; -} - -SomeBigThing :: struct { - name: string; - pos: Vec3; -} - -mag_squared :: proc (use v: Vec3) -> i32 { - return x * x + y * y + z * z; -} - -clamp :: proc (v: i32, lo: i32, hi: i32) -> i32 { - if v < lo do return lo; - if v > hi do return hi; - return v; -} - -// NOTE: Anonymous functions do NOT have closure, -// so in either of these function scopes, the -// parameter 'n' is not accessible. -// -// This is intended behavior since creating new -// procs at runtime is very difficult with WASM -stupid_idea :: proc (n: i32) -> proc (i32) -> i32 { - if n == 1234 { - return proc (a: i32) -> i32 { return 5678 + a; }; - } - - return proc (a: i32) -> i32 { return -1 + a; }; -} - -some_value := 20 + 30 * 4 + 15 / 5; - -start :: proc #export { - memory_init(); - - print("Hello, World!"); - print_hex(cast(u64) some_value); - print("Hello, World!"); - print_bin(42l); - print_hex(42l); - - print(cast(u32) (#char "a" + #char "0")); - - for i: #char "a", #char "f" do print_hex(cast(u64) i); - - a := 12345; - - arr: [N][N] i32; - arr[1][0] = 10; - arr[1][1] = 20; - arr[1][2] = 30; - arr[1][3] = 40; - arr[1][4] = 50; - arr[1][9] = 123; - print(arr[1]|>sumN()); - print(summing(cast(^i32) arr[1])); - - print(10 |> ret_val(4)); - print(11 |> ret_val(5)); - - for i: 0, N do print(arr[1][i]); - - soa: struct { x: [5] i32; y: [5] i32; }; - for i: 0, 5 { - soa.x[i] = i; - soa.y[i] = i * i; - } - print(soa.y[3]); - print_ptr(^soa.y[3]); - - fancy : [5 + 3 * 4] i32; - fancy[2] = 123; - print(fancy[2]); - - - something : [N] i32; - for i: 0, N do something[i] = N - i; - for i: 0, N do print(something[i]); - - something - |> sort(proc (a: i32, b: i32) -> i32 { return a - b; }) - |> sumN() - |> clamp(30, 100) - |> print(); - - for i: 0, N do - something[i] - |> clamp(3, 6) - |> print(); - - stupid_idea(1234)(1234) |> print(); - - varr : [5] Vec3; - varr[2] = Vec3.{4, 5, 6}; - - mag_squared(varr[2]) |> print(); - - v1 := Vec3.{}; - v2 := vmul(vadd(v1, Vec3.{ 1, 2, 3 }), 3); - - print(v2.x); - print(v2.y); - print(v2.z); - - un : UnionTest; - un.f = 1.25f; - print_hex(cast(u64) un.i); - - s1 :: string_make("Hello, "); - s2 :: string_make("World!"); - s3 :: string_concat(heap_allocator, s1, s2); - defer string_free(heap_allocator, s3); - string_print(s3); - - sbt : SomeBigThing; - sbt.name = s3; - sbt.pos = Vec3.{ 2, 3, 4 }; - string_print(sbt.name); - - v := vmul(vadd(sbt.pos, Vec3.{ 1, 2, 3 }), 3); - print(v.x); - print(v.y); - print(v.z); -} - -vadd :: proc (v1: Vec3, v2: Vec3) -> Vec3 { - return Vec3.{ - v1.x + v2.x, - v1.y + v2.y, - v1.z + v2.z, - }; -} - -vmul :: proc (use v: Vec3, s: i32) -> Vec3 { - return Vec3.{ x * s, y * s, z * s }; -} - -UnionTest :: struct #union { - i : i32; - f : f32; -} diff --git a/src/onyxparser.c b/src/onyxparser.c index cd8601bb..3d7262f4 100644 --- a/src/onyxparser.c +++ b/src/onyxparser.c @@ -1238,7 +1238,7 @@ static AstType* parse_type(OnyxParser* parser, bh_arr(AstPolyParam)* poly_vars) while (parser->curr->type != ')') { if (parser->hit_unexpected_token) return root; - AstType* param_type = parse_type(parser, NULL); + AstType* param_type = parse_type(parser, poly_vars); bh_arr_push(params, param_type); if (parser->curr->type != ')') @@ -1249,7 +1249,7 @@ static AstType* parse_type(OnyxParser* parser, bh_arr(AstPolyParam)* poly_vars) AstType* return_type = (AstType *) &basic_type_void; if (parser->curr->type == Token_Type_Right_Arrow) { consume_token(parser); - return_type = parse_type(parser, NULL); + return_type = parse_type(parser, poly_vars); } u64 param_count = bh_arr_length(params); -- 2.25.1