From: Brendan Hansen Date: Fri, 15 Apr 2022 01:30:19 +0000 (-0500) Subject: bugfixes with array type duplication and comparing types at compile-time X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=34a5aeeaf282a6319e516b4dc6428467e9f89068;p=onyx.git bugfixes with array type duplication and comparing types at compile-time --- diff --git a/core/runtime/js.onyx b/core/runtime/js.onyx index 3be87279..7dc981da 100644 --- a/core/runtime/js.onyx +++ b/core/runtime/js.onyx @@ -14,8 +14,13 @@ __read_from_input :: (buf: [] u8) -> u32 do return 0; __runtime_initialize(); context.thread_id = 0; - args: [] cstr = .{ null, 0 }; - (package main).main(args); + #if (typeof (package main).main) == #type () -> void { + (package main).main(); + + } else { + args: [] cstr = .{ null, 0 }; + (package main).main(args); + } __flush_stdio(); } diff --git a/core/runtime/onyx_run.onyx b/core/runtime/onyx_run.onyx index d5f49619..2efe9526 100644 --- a/core/runtime/onyx_run.onyx +++ b/core/runtime/onyx_run.onyx @@ -54,15 +54,20 @@ __read_from_input :: (buffer: [] u8) -> i32 { __runtime_initialize(); context.thread_id = 0; - args : [] cstr; - argv_buf_size : i32; - __args_sizes_get(^args.count, ^argv_buf_size); + #if (typeof (package main).main) == #type () -> void { + (package main).main(); - args = memory.make_slice(cstr, args.count); - argv_buf := cast(cstr) calloc(argv_buf_size); - __args_get(args.data, argv_buf); + } else { + args : [] cstr; + argv_buf_size : i32; + __args_sizes_get(^args.count, ^argv_buf_size); - (package main).main(args); + args = memory.make_slice(cstr, args.count); + argv_buf := cast(cstr) calloc(argv_buf_size); + __args_get(args.data, argv_buf); + + (package main).main(args); + } __flush_stdio(); } diff --git a/core/runtime/wasi.onyx b/core/runtime/wasi.onyx index eba29f7b..a4338d4e 100644 --- a/core/runtime/wasi.onyx +++ b/core/runtime/wasi.onyx @@ -57,29 +57,34 @@ __sleep :: (milliseconds: u32) { __runtime_initialize(); context.thread_id = 0; - args : [] cstr; - argv_buf_size : Size; - args_sizes_get(^args.count, ^argv_buf_size); - - args = memory.make_slice(cstr, args.count); - argv_buf := cast(cstr) calloc(argv_buf_size); - args_get(args.data, argv_buf); - - - // This post processing of the argv array needs to happen if the target is using - // 32-bit pointers, instead of 64-bits. Right now, Onyx pointers take up 64-bits, - // but in most circumstances, only the lower 32-bits are used. When webassembly - // standardizes the 64-bit address space, it will be an easy conversion over. - // But for right now, WASI will give the argv array 32-bit pointers, instead of - // 64-bit pointers. This loops expands the 32-bit pointers into 64-bit pointers - // while not clobbering any of them. - while i := cast(i32) (args.count - 1); i >= 0 { - defer i -= 1; - - args[i] = cast(cstr) (cast(^u32) args.data)[i]; - } + #if (typeof (package main).main) == #type () -> void { + (package main).main(); + + } else { + args : [] cstr; + argv_buf_size : Size; + args_sizes_get(^args.count, ^argv_buf_size); + + args = memory.make_slice(cstr, args.count); + argv_buf := cast(cstr) calloc(argv_buf_size); + args_get(args.data, argv_buf); + - (package main).main(args); + // This post processing of the argv array needs to happen if the target is using + // 32-bit pointers, instead of 64-bits. Right now, Onyx pointers take up 64-bits, + // but in most circumstances, only the lower 32-bits are used. When webassembly + // standardizes the 64-bit address space, it will be an easy conversion over. + // But for right now, WASI will give the argv array 32-bit pointers, instead of + // 64-bit pointers. This loops expands the 32-bit pointers into 64-bit pointers + // while not clobbering any of them. + while i := cast(i32) (args.count - 1); i >= 0 { + defer i -= 1; + + args[i] = cast(cstr) (cast(^u32) args.data)[i]; + } + + (package main).main(args); + } __flush_stdio(); } diff --git a/include/astnodes.h b/include/astnodes.h index a38da2c0..0974be01 100644 --- a/include/astnodes.h +++ b/include/astnodes.h @@ -1764,6 +1764,7 @@ static inline void convert_polyproc_to_function(AstFunction *func) { func->active_queries.entries = NULL; func->poly_scope = NULL; func->entity = NULL; + func->type = NULL; } static inline void convert_function_to_polyproc(AstFunction *func) { diff --git a/src/astnodes.c b/src/astnodes.c index 5a33acc6..ec2386f9 100644 --- a/src/astnodes.c +++ b/src/astnodes.c @@ -178,6 +178,30 @@ const char* entity_type_strings[Entity_Type_Count] = { "Function", }; +AstNumLit* ast_reduce_type_compare(bh_allocator a, AstBinaryOp* node) { + AstType* left = (AstType *) ast_reduce(a, node->left); + AstType* right = (AstType *) ast_reduce(a, node->right); + + Type* left_type = type_build_from_ast(context.ast_alloc, left); + Type* right_type = type_build_from_ast(context.ast_alloc, right); + + AstNumLit* res = onyx_ast_node_new(a, sizeof(AstNumLit), Ast_Kind_NumLit); + res->token = node->token; + res->flags |= node->flags; + res->flags |= Ast_Flag_Comptime; + res->type_node = (AstType *) &basic_type_bool; + res->type = &basic_types[Basic_Kind_Bool]; + res->next = node->next; + + switch (node->operation) { + case Binary_Op_Equal: res->value.l = left_type->id == right_type->id; break; + case Binary_Op_Not_Equal: res->value.l = left_type->id != right_type->id; break; + default: assert(("Bad case in ast_reduce_type_compare", 0)); + } + + return res; +} + #define REDUCE_BINOP_ALL(op) \ if (type_is_small_integer(res->type) || type_is_bool(res->type)) { \ res->value.i = left->value.i op right->value.i; \ @@ -212,6 +236,12 @@ AstNumLit* ast_reduce_binop(bh_allocator a, AstBinaryOp* node) { AstNumLit* left = (AstNumLit *) ast_reduce(a, node->left); AstNumLit* right = (AstNumLit *) ast_reduce(a, node->right); + if (node_is_type((AstNode *) left) && node_is_type((AstNode *) right)) { + if (node->operation == Binary_Op_Equal || node->operation == Binary_Op_Not_Equal) { + return (AstNumLit *) ast_reduce_type_compare(a, node); + } + } + if (left->kind != Ast_Kind_NumLit || right->kind != Ast_Kind_NumLit) { node->left = (AstTyped *) left; node->right = (AstTyped *) right; @@ -802,6 +832,14 @@ Type* resolve_expression_type(AstTyped* node) { } } + // If polymorphic procedures HAVE to have a type, most likely + // because they are part of a `typeof` expression, they are + // assigned a void type. This is cleared before the procedure + // is solidified. + if (node->kind == Ast_Kind_Polymorphic_Proc) { + node->type = &basic_types[Basic_Kind_Void]; + } + if (node->type == NULL) node->type = type_build_from_ast(context.ast_alloc, node->type_node); diff --git a/src/checker.c b/src/checker.c index 611f6537..6e6cdc9c 100644 --- a/src/checker.c +++ b/src/checker.c @@ -2521,6 +2521,7 @@ CheckStatus check_type(AstType** ptype) { } type = original_type; + type->flags |= Ast_Flag_Comptime; while (type->kind == Ast_Kind_Type_Alias) { type->flags |= Ast_Flag_Comptime; type = ((AstTypeAlias *) type)->to; diff --git a/src/onyx.c b/src/onyx.c index 4b94e582..09ed47bc 100644 --- a/src/onyx.c +++ b/src/onyx.c @@ -43,7 +43,7 @@ static const char* docstring = "Onyx compiler version " VERSION "\n" "Flags:\n" "\t List of initial files\n" "\t-o Specify the target file (default: out.wasm).\n" - "\t--runtime, -r Specifies a runtime. Can be: wasi, js, custom.\n" + "\t--runtime, -r Specifies the runtime. Can be: onyx, wasi, js, custom.\n" "\t--verbose, -V Verbose output.\n" "\t -VV Very verbose output.\n" "\t -VVV Very very verbose output (to be used by compiler developers).\n" diff --git a/src/types.c b/src/types.c index 981d5eb7..e408b692 100644 --- a/src/types.c +++ b/src/types.c @@ -41,6 +41,7 @@ Type basic_types[] = { // TODO: Document this!! bh_imap type_map; static bh_imap type_pointer_map; +static bh_imap type_array_map; static bh_imap type_slice_map; static bh_imap type_dynarr_map; static bh_imap type_vararg_map; @@ -64,6 +65,7 @@ static void type_register(Type* type) { void types_init() { bh_imap_init(&type_map, global_heap_allocator, 255); bh_imap_init(&type_pointer_map, global_heap_allocator, 255); + bh_imap_init(&type_array_map, global_heap_allocator, 255); bh_imap_init(&type_slice_map, global_heap_allocator, 255); bh_imap_init(&type_dynarr_map, global_heap_allocator, 255); bh_imap_init(&type_vararg_map, global_heap_allocator, 255); @@ -303,9 +305,6 @@ Type* type_build_from_ast(bh_allocator alloc, AstType* type_node) { Type *elem_type = type_build_from_ast(alloc, a_node->elem); if (elem_type == NULL) return NULL; - Type* a_type = type_create(Type_Kind_Array, alloc, 0); - a_type->Array.elem = elem_type; - u32 count = 0; if (a_node->count_expr) { if (a_node->count_expr->type == NULL) @@ -328,11 +327,9 @@ Type* type_build_from_ast(bh_allocator alloc, AstType* type_node) { count = get_expression_integer_value(a_node->count_expr, NULL); } - a_type->Array.count = count; - a_type->Array.size = type_size_of(a_type->Array.elem) * count; - - type_register(a_type); - return a_type; + Type* array_type = type_make_array(alloc, elem_type, count); + if (array_type) array_type->ast_type = type_node; + return array_type; } case Ast_Kind_Struct_Type: { @@ -723,14 +720,24 @@ Type* type_make_pointer(bh_allocator alloc, Type* to) { Type* type_make_array(bh_allocator alloc, Type* to, u32 count) { if (to == NULL) return NULL; - Type* arr_type = type_create(Type_Kind_Array, alloc, 0); - arr_type->Array.count = count; - arr_type->Array.elem = to; - arr_type->Array.size = count * type_size_of(to); + assert(to->id > 0); + u64 key = ((((u64) to->id) << 32) | (u64) count); + u64 array_id = bh_imap_get(&type_array_map, key); + if (array_id > 0) { + Type* array_type = (Type *) bh_imap_get(&type_map, array_id); + return array_type; - // :TypeCanBeDuplicated - type_register(arr_type); - return arr_type; + } else { + Type* arr_type = type_create(Type_Kind_Array, alloc, 0); + arr_type->Array.count = count; + arr_type->Array.elem = to; + arr_type->Array.size = count * type_size_of(to); + + type_register(arr_type); + bh_imap_put(&type_array_map, key, arr_type->id); + + return arr_type; + } } Type* type_make_slice(bh_allocator alloc, Type* of) {