added implicit '.data' to slices so they behave like arrays
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Fri, 28 Aug 2020 16:29:04 +0000 (11:29 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Fri, 28 Aug 2020 16:29:04 +0000 (11:29 -0500)
core/alloc.onyx
core/builtin.onyx
core/string.onyx
core/wasi.onyx
include/onyxastnodes.h
include/onyxtypes.h
onyx
progs/wasi_test.onyx
src/onyxchecker.c
src/onyxtypes.c
src/onyxwasm.c

index 0f5694dabb510984c4c53c661b7f30a81e1bf531..7372b0755472fee51eeae1caedf03637ad028f94 100644 (file)
@@ -125,11 +125,6 @@ heap_alloc_proc :: proc (data: rawptr, aa: AllocAction, size: u32, align: u32, o
     return null;
 }
 
-malloc  :: proc (size: u32) -> rawptr do return alloc(heap_allocator, size);
-mfree   :: proc (ptr: rawptr) do free(heap_allocator, ptr);
-mresize :: proc (ptr: rawptr, size: u32) -> rawptr do return resize(heap_allocator, ptr, size);
-
-
 
 #private
 ScratchState :: struct {
index f8e269e59d8dcceb90b0677939b3f6f8e820fe7e..13df04fc13023c46f6e76bc149551b286a7b5593 100644 (file)
@@ -7,6 +7,8 @@ Buffer :: #type []void;
 
 null :: cast(rawptr) 0;
 
+DEFAULT_ALLOCATION_ALIGNMENT :: 16
+
 AllocAction :: enum {
     Alloc;
     Free;
@@ -21,11 +23,11 @@ Allocator :: struct {
 }
 
 alloc :: proc (use a: Allocator, size: u32) -> rawptr {
-    return func(data, AllocAction.Alloc, size, 16, null);
+    return func(data, AllocAction.Alloc, size, DEFAULT_ALLOCATION_ALIGNMENT, null);
 }
 
 resize :: proc (use a: Allocator, ptr: rawptr, size: u32) -> rawptr {
-    return func(data, AllocAction.Resize, size, 16, ptr);
+    return func(data, AllocAction.Resize, size, DEFAULT_ALLOCATION_ALIGNMENT, ptr);
 }
 
 free :: proc (use a: Allocator, ptr: rawptr) {
index 933c8b0c4d986b6a0a5dd5c5433cc417dd9af792..ac7ab375ee95d18ecb49bb5b404a0f3e999e304b 100644 (file)
@@ -38,8 +38,8 @@ string_concat :: proc (s1: string, s2: string) -> string {
     len2 :: string_length(s2);
 
     data := cast(^u8) calloc(len1 + len2);
-    for i: 0, len1 do data[i]        = s1.data[i];
-    for i: 0, len2 do data[i + len1] = s2.data[i];
+    for i: 0, len1 do data[i]        = s1[i];
+    for i: 0, len2 do data[i + len1] = s2[i];
 
     return string.{ data, len1 + len2 };
 }
@@ -51,7 +51,7 @@ string_free :: proc (s: string) do cfree(s.data);
 // It documents the string_split function
 string_split :: proc (str: string, delim: u8) -> []string {
     delim_count := 0;
-    for i: 0, str.count do if str.data[i] == delim do delim_count += 1;
+    for i: 0, str.count do if str[i] == delim do delim_count += 1;
 
     strarr := cast(^string) calloc(sizeof string * (delim_count + 1));
 
@@ -59,7 +59,7 @@ string_split :: proc (str: string, delim: u8) -> []string {
     begin := 0;
 
     for i: 0, str.count {
-        if str.data[i] == delim {
+        if str[i] == delim {
             strarr[curr_str] = str.data[begin : i];
             begin = i + 1;
             curr_str += 1;
@@ -73,7 +73,7 @@ string_split :: proc (str: string, delim: u8) -> []string {
 
 string_substr :: proc (str: string, sub: string) -> string {
     for i: 0, str.count {
-        while j := 0; j < sub.count && str.data[i + j] == sub.data[j] {
+        while j := 0; j < sub.count && str[i + j] == sub[j] {
             j += 1;
 
             if j == sub.count do return str.data[i : i + j];
@@ -84,7 +84,7 @@ string_substr :: proc (str: string, sub: string) -> string {
 }
 
 string_contains :: proc (str: string, c: u8) -> bool {
-    for i: 0, str.count do if str.data[i] == c do return true;
+    for i: 0, str.count do if str[i] == c do return true;
     return false;
 }
 
@@ -114,7 +114,7 @@ string_builder_add_string :: proc (use sb: ^StringBuilder, str: string) -> ^Stri
     len_total :: len + str.count;
 
     if cap >= len_total {
-        for i: 0, str.count do data[len + i] = str.data[i];
+        for i: 0, str.count do data[len + i] = str[i];
         len += str.count;
         return sb;
     }
@@ -128,7 +128,7 @@ string_builder_add_string :: proc (use sb: ^StringBuilder, str: string) -> ^Stri
     data = new_data;
     cap = new_cap;
 
-    for i: 0, str.count do data[len + i] = str.data[i];
+    for i: 0, str.count do data[len + i] = str[i];
     len += str.count;
     return sb;
 }
@@ -152,7 +152,7 @@ u64_to_string :: proc (n_: u64, base: u64, buf: Buffer) -> string {
     while n > 0l {
         m :: n % base;
 
-        *c = s.data[cast(u32) m];
+        *c = s[cast(u32) m];
         len += 1;
         c -= 1;
 
index f2af84defe41105828183197608e6ca22dc74d39..0f7a3a6bb86f9e0d6d3dc451e0727884bf4806ea 100644 (file)
@@ -476,8 +476,8 @@ proc #export "_start" {
 
        args_sizes_get(^argc, ^argv_buf_size);
 
-       argv := cast(^^u8) malloc(sizeof ^u8 * argc);
-       argv_buf := cast(^u8) malloc(argv_buf_size);
+       argv := cast(^^u8) calloc(sizeof ^u8 * argc);
+       argv_buf := cast(^u8) calloc(argv_buf_size);
 
        args_get(argv, argv_buf);
 
index b18db701fb38e663c5294b2bce9f15e10ef4622d..6e8cd47d0014753fa660c8b6cf7a808ae21aeab3 100644 (file)
@@ -299,7 +299,7 @@ struct AstAddressOf     { AstTyped_base; AstTyped *expr; };
 struct AstDereference   { AstTyped_base; AstTyped *expr; };
 struct AstArrayAccess   { AstTyped_base; AstTyped *addr; AstTyped *expr; u64 elem_size; };
 struct AstSlice         { AstTyped_base; AstTyped *addr; AstTyped *lo, *hi; u64 elem_size; };
-struct AstFieldAccess   { AstTyped_base; AstTyped *expr; u64 offset; };
+struct AstFieldAccess   { AstTyped_base; AstTyped *expr; u32 offset; u32 idx; };
 struct AstSizeOf        { AstTyped_base; AstType *so_type; u64 size; };
 struct AstAlignOf       { AstTyped_base; AstType *ao_type; u64 alignment; };
 struct AstFileContents  { AstTyped_base; OnyxToken *filename; };
@@ -465,6 +465,13 @@ struct AstFunction      {
         };
     };
 };
+struct AstPolyProc {
+    AstNode_base;
+
+    Scope *poly_scope;
+
+    AstFunction* func;
+};
 struct AstOverloadedFunction {
     AstTyped_base;
 
index 7c15348c3e33e69b8d21db4c9a6757530745dc98..dd4a209e0a0c290e7b4bd1c9f34fa52f7ed9943e 100644 (file)
@@ -134,6 +134,7 @@ b32 type_is_integer(Type* type);
 b32 type_is_numeric(Type* type);
 b32 type_is_compound(Type* type);
 b32 type_results_in_void(Type* type);
+b32 type_is_array_accessible(Type* type);
 b32 type_is_structlike(Type* type);
 b32 type_is_structlike_strict(Type* type);
 u32 type_structlike_mem_count(Type* type);
diff --git a/onyx b/onyx
index d2dcc382e547f0ea9b6db18bdb999e51ddecde85..74d31f3930a03e03b390397a086f2c907692aeb0 100755 (executable)
Binary files a/onyx and b/onyx differ
index 8c9d72b1a0183fa37d310c1bc4fba89478d0d295..aacdbb4807cbe22262a6a39f1e25f8db8d961695 100644 (file)
@@ -140,16 +140,14 @@ output_s :: proc (sb: ^StringBuilder, s: ^S) -> ^StringBuilder {
 print_arr :: proc (sb: ^StringBuilder, arr: []i32) {
     sb  |> string_builder_clear();
 
-    a := arr.data;
-
     for i: 0, arr.count {
-        sb |> sba(cast(u64) a[i]) |> sba(" ");
+        sb |> sba(cast(u64) arr[i]) |> sba(" ");
     }
 
     sb |> sba("\n") |> string_builder_to_string() |> print();
 }
 
-make_i32_arr :: proc (a := heap_allocator, len := 10) -> [] i32 {
+make_i32_arr :: proc (a := context.allocator, len := 10) -> [] i32 {
     arr := cast(^i32) alloc(a, sizeof i32 * len);
     return arr[0 : len];
 }
@@ -176,12 +174,12 @@ main :: proc (args: []cstring) {
         |> sba(cast(u64) args.count)
         |> sba(" arguments.\n");
 
-    for i: 0, args.count do ^sb |> sba(args.data[i]) |> sba(" ");
+    for i: 0, args.count do ^sb |> sba(args[i]) |> sba(" ");
     ^sb |> sba("\n")
         |> string_builder_to_string()
         |> print();
 
-    cont := file_get_contents(string_make(args.data[1]));
+    cont := file_get_contents(string_make(args[1]));
     defer cfree(cont.data);
     print(cont);
 
@@ -196,7 +194,7 @@ main :: proc (args: []cstring) {
 
     string_builder_clear(^sb);
     for i: 0, matches.count {
-        ^sb |> sba(matches.data[i])
+        ^sb |> sba(matches[i])
             |> sba("\n");
     }
 
@@ -208,7 +206,7 @@ main :: proc (args: []cstring) {
 
     acc := 0;
     for i: 0, tokens.count {
-        switch tokens.data[i].data[0] {
+        switch tokens[i][0] {
             case #char "+" do acc += 1;
             case #char "-" do acc -= 1;
             case #char "*" do acc *= 2;
@@ -217,7 +215,7 @@ main :: proc (args: []cstring) {
 
             case #default {
                 print("Unexpected token: ");
-                print_u64(cast(u64) tokens.data[i].data[0], 16l);
+                print_u64(cast(u64) tokens[i][0], 16l);
                 print("\n");
 
                 // This breaks out of the for loop
@@ -303,6 +301,6 @@ fib :: proc (n: i32) -> i32 {
     return 0;
 }
 
-//make_slice :: proc (ptr: ^$T, count: u32) -> [] T {
-//    return ptr[0 : count];
-//}
\ No newline at end of file
+// make_slice :: proc (ptr: ^$T, count: u32) -> [] T {
+//     return ptr[0 : count];
+// }
\ No newline at end of file
index b4ac6fc442ce84413087a06782659d094f341ae1..4f159ec9954ef05003c9e521d7a0f909e792b928 100644 (file)
@@ -810,7 +810,7 @@ b32 check_array_access(AstArrayAccess* aa) {
     if (check_expression(&aa->addr)) return 1;
     if (check_expression(&aa->expr)) return 1;
 
-    if (!type_is_pointer(aa->addr->type)) {
+    if (!type_is_array_accessible(aa->addr->type)) {
         onyx_message_add(Msg_Type_Literal,
                 aa->token->pos,
                 "expected pointer or array type for left of array access");
@@ -829,6 +829,22 @@ b32 check_array_access(AstArrayAccess* aa) {
         aa->type = aa->addr->type->Pointer.elem;
     else if (aa->addr->type->kind == Type_Kind_Array)
         aa->type = aa->addr->type->Array.elem;
+    else if (aa->addr->type->kind == Type_Kind_Slice) {
+        // If we are accessing on a slice, implicitly add a field access for the data member
+
+        StructMember smem;
+        type_lookup_member(aa->addr->type, "data", &smem);
+
+        AstFieldAccess* fa = onyx_ast_node_new(semstate.node_allocator, sizeof(AstFieldAccess), Ast_Kind_Field_Access);
+        fa->token = aa->addr->token;
+        fa->type = smem.type;
+        fa->offset = smem.offset;
+        fa->idx = smem.idx;
+        fa->expr = aa->addr;
+
+        aa->addr = (AstTyped *) fa;
+        aa->type = aa->addr->type->Pointer.elem;
+    }
     else {
         onyx_message_add(Msg_Type_Literal,
                 aa->token->pos,
@@ -910,6 +926,7 @@ b32 check_field_access(AstFieldAccess** pfield) {
     }
 
     field->offset = smem.offset;
+    field->idx = smem.idx;
     field->type = smem.type;
 
     token_toggle_end(field->token);
index 762f997567e7c17ea693cf9b7adb6e988ee67372..275f6d9c5e34beb701052c9496d19d41fdca0d92 100644 (file)
@@ -441,6 +441,7 @@ const char* type_get_name(Type* type) {
                 return "<anonymous enum>";
 
         case Type_Kind_Function: return bh_aprintf(global_scratch_allocator, "proc (...) -> %s", type_get_name(type->Function.return_type));
+        case Type_Kind_Slice: return bh_aprintf(global_scratch_allocator, "[] %s", type_get_name(type->Slice.ptr_to_data->Pointer.elem));
 
         default: return "unknown";
     }
@@ -593,6 +594,12 @@ b32 type_results_in_void(Type* type) {
             && (type->Function.return_type->Basic.kind == Basic_Kind_Void));
 }
 
+b32 type_is_array_accessible(Type* type) {
+    if (type_is_pointer(type)) return 1;
+    if (type->kind == Type_Kind_Slice) return 1;
+    return 0;
+}
+
 b32 type_is_structlike(Type* type) {
     if (type->kind == Type_Kind_Struct) return 1;
     if (type->kind == Type_Kind_Slice)  return 1;
index e1ca422a030626d7729a5c89bc52e54fd4d43f42..2adcbfb0914a3532258837f5bc83364bcca3e07a 100644 (file)
@@ -1406,13 +1406,7 @@ COMPILE_FUNC(location, AstTyped* expr) {
             AstFieldAccess* field = (AstFieldAccess *) expr;
 
             if (field->expr->kind == Ast_Kind_Param && type_is_structlike_strict(field->expr->type)) {
-                StructMember smem;
-
-                token_toggle_end(field->token);
-                type_lookup_member(field->expr->type, field->token->text, &smem);
-                token_toggle_end(field->token);
-
-                u64 localidx = bh_imap_get(&mod->local_map, (u64) field->expr) + smem.idx;
+                u64 localidx = bh_imap_get(&mod->local_map, (u64) field->expr) + field->idx;
 
                 WIL(WI_LOCAL_GET, localidx);
                 break;
@@ -1568,13 +1562,7 @@ COMPILE_FUNC(expression, AstTyped* expr) {
             AstFieldAccess* field = (AstFieldAccess* ) expr;
 
             if (field->expr->kind == Ast_Kind_Param && type_is_structlike_strict(field->expr->type)) {
-                StructMember smem;
-
-                token_toggle_end(field->token);
-                type_lookup_member(field->expr->type, field->token->text, &smem);
-                token_toggle_end(field->token);
-
-                u64 localidx = bh_imap_get(&mod->local_map, (u64) field->expr) + smem.idx;
+                u64 localidx = bh_imap_get(&mod->local_map, (u64) field->expr) + field->idx;
 
                 WIL(WI_LOCAL_GET, localidx);
                 break;