From: Brendan Hansen Date: Fri, 28 Aug 2020 16:29:04 +0000 (-0500) Subject: added implicit '.data' to slices so they behave like arrays X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=ffff8e4cf414e5caf0cb03f63b5c7967a08f8a7c;p=onyx.git added implicit '.data' to slices so they behave like arrays --- diff --git a/core/alloc.onyx b/core/alloc.onyx index 0f5694da..7372b075 100644 --- a/core/alloc.onyx +++ b/core/alloc.onyx @@ -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 { diff --git a/core/builtin.onyx b/core/builtin.onyx index f8e269e5..13df04fc 100644 --- a/core/builtin.onyx +++ b/core/builtin.onyx @@ -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) { diff --git a/core/string.onyx b/core/string.onyx index 933c8b0c..ac7ab375 100644 --- a/core/string.onyx +++ b/core/string.onyx @@ -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; diff --git a/core/wasi.onyx b/core/wasi.onyx index f2af84de..0f7a3a6b 100644 --- a/core/wasi.onyx +++ b/core/wasi.onyx @@ -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); diff --git a/include/onyxastnodes.h b/include/onyxastnodes.h index b18db701..6e8cd47d 100644 --- a/include/onyxastnodes.h +++ b/include/onyxastnodes.h @@ -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; diff --git a/include/onyxtypes.h b/include/onyxtypes.h index 7c15348c..dd4a209e 100644 --- a/include/onyxtypes.h +++ b/include/onyxtypes.h @@ -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 d2dcc382..74d31f39 100755 Binary files a/onyx and b/onyx differ diff --git a/progs/wasi_test.onyx b/progs/wasi_test.onyx index 8c9d72b1..aacdbb48 100644 --- a/progs/wasi_test.onyx +++ b/progs/wasi_test.onyx @@ -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 diff --git a/src/onyxchecker.c b/src/onyxchecker.c index b4ac6fc4..4f159ec9 100644 --- a/src/onyxchecker.c +++ b/src/onyxchecker.c @@ -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); diff --git a/src/onyxtypes.c b/src/onyxtypes.c index 762f9975..275f6d9c 100644 --- a/src/onyxtypes.c +++ b/src/onyxtypes.c @@ -441,6 +441,7 @@ const char* type_get_name(Type* type) { return ""; 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; diff --git a/src/onyxwasm.c b/src/onyxwasm.c index e1ca422a..2adcbfb0 100644 --- a/src/onyxwasm.c +++ b/src/onyxwasm.c @@ -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;