better error reporting in many places
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Mon, 21 Dec 2020 02:16:57 +0000 (20:16 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Mon, 21 Dec 2020 02:16:57 +0000 (20:16 -0600)
13 files changed:
Makefile
core/alloc/heap.onyx
core/conv.onyx
core/map.onyx
docs/bugs
docs/todo
include/onyxastnodes.h
onyx
src/onyxchecker.c
src/onyxclone.c
src/onyxparser.c
src/onyxsymres.c
src/onyxtypes.c

index 36c211d14ab0781cc03247705dea713419964297..b923f94a98277beaa920c4ff3b87f2e70b34e721 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,5 @@
 RELEASE=1
+USE_GCC=1
 
 OBJ_FILES=\
        build/onyxlex.o \
@@ -22,7 +23,11 @@ else
 ifeq ($(RELEASE), 0)
        CC=gcc
 else
-       CC=tcc
+       ifeq ($(USE_GCC),1)
+               CC=gcc
+       else
+               CC=tcc
+       endif
 endif
 endif
 
index 24add47439a7ee568f48ff34915fb1361489f99a..94ff85b6d54d03de263e78dc01dbbdb6d0691b92 100644 (file)
@@ -90,6 +90,8 @@ heap_free :: proc (ptr: rawptr) {
 
 #private_file
 heap_resize :: proc (ptr: rawptr, new_size: u32, align: u32) -> rawptr {
+    if ptr == null do return null;
+    
     hb_ptr := cast(^heap_block) (cast(u32) ptr - sizeof heap_block);
     old_size := hb_ptr.size - sizeof heap_block;
 
index 3402baae66e98c42fae189ce048c5f4183fd62f7..9f5a3c8e9a8ef0da2b576dbaafb2381cabd2ef15 100644 (file)
@@ -180,6 +180,19 @@ str_format_va :: proc (format: str, buffer: [] u8, va: vararg) -> str {
                     buffer[len] = c;
                     len += 1;
                 }
+
+                case #char "b" {
+                    b : bool;
+                    if !vararg_get(va, ^b) do return;
+
+                    s := "false";
+                    if b do s = "true";
+
+                    for a: s {
+                        buffer[len] = a;
+                        len += 1;
+                    }
+                }
             }
 
             state = 0;
index 997c0aff256cd3011355e0a209096db357380419..15b3cbce74982d3bb110aa6919a259fa7c4272d5 100644 (file)
@@ -1,5 +1,6 @@
 package core.map
 
+use package core { printf }
 use package core.array as array
 use package core.string as string
 
index 23fd0eb4b3b2b42c3f26364900e61e669ac2f889..a0e9b3de414541721fd7bc8b1f0bdb56390f0df6 100644 (file)
--- a/docs/bugs
+++ b/docs/bugs
@@ -23,4 +23,35 @@ List of known bugs:
        and converted to a cast(f32). Then, when it doesn't match the first one
        and it tries the second, the parameter types are f32 and unsized int,
        which is doesn't match the second one, when the original parameters would
-       have matched correctly.
\ No newline at end of file
+       have matched correctly.
+
+[ ] `TileData :: [TILE_DATA_WIDTH * TILE_DATA_HEIGHT] bool;` results in a
+    segfault because it is an invalid top level node, but that is not checked
+    before it is tried to be used.
+[X] `TileData :: #type [TILE_DATA_WIDTH * TILE_DATA_HEIGHT] bool;` produces the
+       following error:
+       ```
+       (/home/brendan/dev/onyx/aoc/day20.onyx:25,19) Array type expects type 'i32' for size, got 'unsized int'.
+        25 | TileData :: #type [TILE_DATA_WIDTH * TILE_DATA_HEIGHT] bool;
+       ```
+
+       This because the expression for the array size is not reducing and getting
+       converted to the fixed size integer. I suspect this is because for sizeof
+       and alignof expression, `fill_in_type` is not used, and that function has
+       the logic to handle the array subscript reduction and type resolution.
+
+[X] The following struct is causing a seg fault in the compiler. I believe it
+       is because of the duplicate struct member names and failing to get the position
+       in the file to report the error.
+       ```
+       Tile :: struct {
+               id          : u32;
+               orientation : TileOrientation;
+               data        : [] bool;
+               edges       : [] u32;
+
+               pos_x       : u32 = 0;
+               pos_x       : u32 = 0;
+       }
+       ```
index 492dbe52397b9169cac09d8abf7435dcb831a730..cce4d307deccaef8923149f164ac3e11e327670f 100644 (file)
--- a/docs/todo
+++ b/docs/todo
@@ -99,6 +99,15 @@ Language Cohesion:
         thought to remember that ranges in for-loops and slices are NOT inclusive
         on the upper end.
 
+    [ ] Functions should be polymorphic on the size of array parameters. For example,
+            foo :: proc (arr: [$N] $T) { ... }
+        should be polymorphic on both the type of the array elements and the array
+        size. This would allow for better support for fixed size arrays, as well
+        as some needed built in functions such as:
+            array_to_slice :: proc (arr: [$N] $T) -> [] T {
+                return arr[0 .. N];
+            }
+
 API Expansion:
     There are many different places where the standard API for WASI and JS
     backends could be improved. Here are some of the target areas.
index 496890e0c1e4c201560cfb79688ebac69caec70e..ffb8c60dca7b8275236bf1afde885a8d45f411c1 100644 (file)
@@ -448,8 +448,8 @@ struct AstAddressOf     { AstTyped_base; AstTyped *expr; };
 struct AstDereference   { AstTyped_base; AstTyped *expr; };
 struct AstArrayAccess   { AstTyped_base; AstTyped *addr; AstTyped *expr; u64 elem_size; };
 struct AstFieldAccess   { AstTyped_base; AstTyped *expr; u32 offset; u32 idx; char* field; }; // If token is null, defer to field
-struct AstSizeOf        { AstTyped_base; AstType *so_type; u64 size; };
-struct AstAlignOf       { AstTyped_base; AstType *ao_type; u64 alignment; };
+struct AstSizeOf        { AstTyped_base; AstType *so_ast_type; Type *so_type; u64 size; };
+struct AstAlignOf       { AstTyped_base; AstType *ao_ast_type; Type *ao_type; u64 alignment; };
 struct AstFileContents  { AstTyped_base; OnyxToken *filename; u32 addr, size; };
 struct AstStructLiteral {
     AstTyped_base;
diff --git a/onyx b/onyx
index 7d215a93aaf6adf128477511b8aba99163740c30..c7d6c45aaa4694e90ee1875ecd3d406f1c9c7a47 100755 (executable)
Binary files a/onyx and b/onyx differ
index ba1324b4e8c161d19d555e84162979dba1cc112b..e27227418df984bcfb195a107bb6a6279023f946 100644 (file)
@@ -33,13 +33,23 @@ CHECK(struct, AstStructType* s_node);
 CHECK(function_header, AstFunction* func);
 CHECK(memres, AstMemRes* memres);
 
-static inline void fill_in_type(AstTyped* node) {
-    if (node->type_node && node->type_node->kind == Ast_Kind_Array_Type) {
-        if (((AstArrayType *) node->type_node)->count_expr) {
-            check_expression(&((AstArrayType *) node->type_node)->count_expr);
-            resolve_expression_type(((AstArrayType *) node->type_node)->count_expr);
+static inline void fill_in_array_count(AstType* type_node) {
+    if (type_node == NULL) return;
+
+    if (type_node->kind == Ast_Kind_Type_Alias) {
+        fill_in_array_count(((AstTypeAlias *) type_node)->to);
+    }
+
+    if (type_node->kind == Ast_Kind_Array_Type) {
+        if (((AstArrayType *) type_node)->count_expr) {
+            check_expression(&((AstArrayType *) type_node)->count_expr);
+            resolve_expression_type(((AstArrayType *) type_node)->count_expr);
         }
     }
+}
+
+static inline void fill_in_type(AstTyped* node) {
+    fill_in_array_count(node->type_node);
 
     if (node->type == NULL)
         node->type = type_build_from_ast(semstate.allocator, node->type_node);
@@ -1148,13 +1158,27 @@ b32 check_range_literal(AstBinaryOp** prange) {
 }
 
 b32 check_size_of(AstSizeOf* so) {
-    so->size = type_size_of(type_build_from_ast(semstate.allocator, so->so_type));
+    fill_in_array_count(so->so_ast_type);
+
+    so->so_type = type_build_from_ast(semstate.allocator, so->so_ast_type);
+    if (so->so_type == NULL) {
+        onyx_report_error(so->token->pos, "Error with type used here.");
+        return 1;
+    }
+    so->size = type_size_of(so->so_type);
 
     return 0;
 }
 
 b32 check_align_of(AstAlignOf* ao) {
-    ao->alignment = type_alignment_of(type_build_from_ast(semstate.allocator, ao->ao_type));
+    fill_in_array_count(ao->ao_ast_type);
+
+    ao->ao_type = type_build_from_ast(semstate.allocator, ao->ao_ast_type);
+    if (ao->ao_type == NULL) {
+        onyx_report_error(ao->token->pos, "Error with type used here.");
+        return 1;
+    }
+    ao->alignment = type_alignment_of(ao->ao_type);
 
     return 0;
 }
@@ -1356,27 +1380,6 @@ b32 check_overloaded_function(AstOverloadedFunction* func) {
 }
 
 b32 check_struct(AstStructType* s_node) {
-    bh_table(i32) mem_set;
-    bh_table_init(global_heap_allocator, mem_set, bh_arr_length(s_node->members));
-
-    bh_arr_each(AstStructMember *, member, s_node->members) {
-        token_toggle_end((*member)->token);
-
-        if (bh_table_has(i32, mem_set, (*member)->token->text)) {
-            onyx_report_error((*member)->token->pos,
-                    "Duplicate struct member '%s'.",
-                    (*member)->token->text);
-
-            token_toggle_end((*member)->token);
-            return 1;
-        }
-
-        bh_table_put(i32, mem_set, (*member)->token->text, 1);
-        token_toggle_end((*member)->token);
-    }
-
-    bh_table_free(mem_set);
-
     // NOTE: fills in the stcache
     type_build_from_ast(semstate.allocator, (AstType *) s_node);
 
index 3cb73c2050e0364762c02532a6761e6533184599..355af0e26f8979e8c44111db8a5cb5cb8769b9bd 100644 (file)
@@ -167,11 +167,11 @@ AstNode* ast_clone(bh_allocator a, void* n) {
                        break;
 
                case Ast_Kind_Size_Of:
-                       ((AstSizeOf *) nn)->so_type = (AstType *) ast_clone(a, ((AstSizeOf *) node)->so_type);
+                       ((AstSizeOf *) nn)->so_ast_type = (AstType *) ast_clone(a, ((AstSizeOf *) node)->so_ast_type);
                        break;
 
                case Ast_Kind_Align_Of:
-                       ((AstAlignOf *) nn)->ao_type = (AstType *) ast_clone(a, ((AstAlignOf *) node)->ao_type);
+                       ((AstAlignOf *) nn)->ao_ast_type = (AstType *) ast_clone(a, ((AstAlignOf *) node)->ao_ast_type);
                        break;
 
                case Ast_Kind_Struct_Literal: {
index 3edac59a64136a1c4edef942aaae0a24d9b22d52..bc890b6cfed71636fb1411430375f4a962e96545 100644 (file)
@@ -366,7 +366,7 @@ static AstTyped* parse_factor(OnyxParser* parser) {
         case Token_Type_Keyword_Sizeof: {
             AstSizeOf* so_node = make_node(AstSizeOf, Ast_Kind_Size_Of);
             so_node->token = expect_token(parser, Token_Type_Keyword_Sizeof);
-            so_node->so_type = (AstType *) parse_type(parser);
+            so_node->so_ast_type = (AstType *) parse_type(parser);
             so_node->type_node = (AstType *) &basic_type_i32;
 
             retval = (AstTyped *) so_node;
@@ -376,7 +376,7 @@ static AstTyped* parse_factor(OnyxParser* parser) {
         case Token_Type_Keyword_Alignof: {
             AstAlignOf* ao_node = make_node(AstAlignOf, Ast_Kind_Align_Of);
             ao_node->token = expect_token(parser, Token_Type_Keyword_Alignof);
-            ao_node->ao_type = (AstType *) parse_type(parser);
+            ao_node->ao_ast_type = (AstType *) parse_type(parser);
             ao_node->type_node = (AstType *) &basic_type_i32;
 
             retval = (AstTyped *) ao_node;
index 5003c71ad2234b544ea9f369ca44cb6dbd740c5b..873fa80ee9b32ef52c65ce0564a84e8f1527af7a 100644 (file)
@@ -97,6 +97,29 @@ AstType* symres_type(AstType* type) {
         if (s_node->flags & Ast_Flag_Type_Is_Resolved) return type;
 
         s_node->flags |= Ast_Flag_Type_Is_Resolved;
+        
+        {
+            bh_table(i32) mem_set;
+            bh_table_init(global_heap_allocator, mem_set, bh_arr_length(s_node->members));
+
+            bh_arr_each(AstStructMember *, member, s_node->members) {
+                token_toggle_end((*member)->token);
+
+                if (bh_table_has(i32, mem_set, (*member)->token->text)) {
+                    onyx_report_error((*member)->token->pos,
+                            "Duplicate struct member '%s'.",
+                            (*member)->token->text);
+
+                    token_toggle_end((*member)->token);
+                    return type;
+                }
+
+                bh_table_put(i32, mem_set, (*member)->token->text, 1);
+                token_toggle_end((*member)->token);
+            }
+
+            bh_table_free(mem_set);
+        }
 
         fori (i, 0, bh_arr_length(s_node->members)) {
             AstStructMember *member = s_node->members[i];
@@ -220,12 +243,12 @@ static void symres_call(AstCall* call) {
 
 static void symres_size_of(AstSizeOf* so) {
     so->type_node = symres_type(so->type_node);
-    so->so_type = symres_type(so->so_type);
+    so->so_ast_type = symres_type(so->so_ast_type);
 }
 
 static void symres_align_of(AstAlignOf* ao) {
     ao->type_node = symres_type(ao->type_node);
-    ao->ao_type = symres_type(ao->ao_type);
+    ao->ao_ast_type = symres_type(ao->ao_ast_type);
 }
 
 static void symres_field_access(AstFieldAccess** fa) {
@@ -353,7 +376,10 @@ static void symres_struct_literal(AstStructLiteral* sl) {
         }
     }
 
-    bh_arr_each(AstTyped *, expr, sl->values) symres_expression(expr);
+    bh_arr_each(AstTyped *, expr, sl->values) {
+        if (*expr == NULL) onyx_report_error(sl->token->pos, "Some kind of error occured with this struct literal.");
+        else               symres_expression(expr);
+    }
 }
 
 static void symres_array_literal(AstArrayLiteral* al) {
index 16eed850f6f2ddcd4dd84c244e350c93cbf04e87..0145f72ed6acb9caaa0a49b569d98bb89ce776e0 100644 (file)
@@ -313,6 +313,8 @@ Type* type_build_from_ast(bh_allocator alloc, AstType* type_node) {
                 if (a_node->count_expr->kind != Ast_Kind_NumLit
                     || a_node->count_expr->type->kind != Type_Kind_Basic
                     || a_node->count_expr->type->Basic.kind != Basic_Kind_I32) {
+                    onyx_report_error(type_node->token->pos, "Array type expects type 'i32' for size, got '%s'.",
+                        type_get_name(a_node->count_expr->type));
                     return NULL;
                 }