bugfixes with array type duplication and comparing types at compile-time
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Fri, 15 Apr 2022 01:30:19 +0000 (20:30 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Fri, 15 Apr 2022 01:30:19 +0000 (20:30 -0500)
core/runtime/js.onyx
core/runtime/onyx_run.onyx
core/runtime/wasi.onyx
include/astnodes.h
src/astnodes.c
src/checker.c
src/onyx.c
src/types.c

index 3be872791aaf76924f677870d60b5b3e4dd23628..7dc981dafdafae2245f7e7c53e10572478eb7343 100644 (file)
@@ -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();
 }
index d5f4961995245f4f820685f5d0ef35a267fdef9f..2efe952600a317fd2004cbe6845386a550b5ad13 100644 (file)
@@ -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();
 }
index eba29f7ba045215ba9fc0972d867ccd335de4593..a4338d4ee3bcd6fb0156b35a7d6bd422d32ce0a5 100644 (file)
@@ -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();
 }
index a38da2c0757a879e6ca0d0ffd3a399bf5f90f30c..0974be0116cd62fce4aeb31a897b23cc0b0543cc 100644 (file)
@@ -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) {
index 5a33acc6cae814561c8f658d46a39ad62585eb7e..ec2386f980a5084103456cdd174f859a31731ac2 100644 (file)
@@ -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);
 
index 611f6537d49781f60d634d611eecdc1471a88344..6e6cdc9c7db8eff057e36c8ca15096e7f0fc95ab 100644 (file)
@@ -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;
index 4b94e5820562e6cba59b4531f2a1adb1861182b7..09ed47bccd74d5d59c61fe202bde3d356bac598f 100644 (file)
@@ -43,7 +43,7 @@ static const char* docstring = "Onyx compiler version " VERSION "\n"
     "Flags:\n"
     "\t<input files>           List of initial files\n"
     "\t-o <target_file>        Specify the target file (default: out.wasm).\n"
-    "\t--runtime, -r <runtime> Specifies a runtime. Can be: wasi, js, custom.\n"
+    "\t--runtime, -r <runtime> 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"
index 981d5eb70d63624a6193cee5594ab58020836bc8..e408b6927aef8f73f4bb9cc0647a36a59a415148 100644 (file)
@@ -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) {