moved some logic from symbol resolution to type checking
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Wed, 6 Jan 2021 03:19:52 +0000 (21:19 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Wed, 6 Jan 2021 03:19:52 +0000 (21:19 -0600)
bin/onyx
include/onyxtypes.h
onyx.exe
src/onyx.c
src/onyxchecker.c
src/onyxsymres.c
src/onyxtypes.c

index f7892b47ceea87cd34349535852b227e9b8063a6..ab00105d1cfee8b69460970059c457e999420d9f 100755 (executable)
Binary files a/bin/onyx and b/bin/onyx differ
index cec94fa55ac3975c3d34ad2a07c08a5654533079..526eddcba536582dd9d1412da67314fa12ab5909 100644 (file)
@@ -68,7 +68,7 @@ typedef struct StructMember {
     // easier and less costly.                  - brendanfh 2020/09/17
     char *name;
 
-    struct AstTyped* initial_value;
+    struct AstTyped** initial_value;
     b32 included_through_use : 1;
 } StructMember;
 
index 192f9e4f42f37470c7af4871b7de72b946607d20..0ea5726e2a689e5a13fb240d4d25ca461a5153d9 100644 (file)
Binary files a/onyx.exe and b/onyx.exe differ
index defec5e248d15ceb5333ea578fe78d64ce6450ab..204130b56d3ecca81fb98719dd03dedd1b7a130c 100644 (file)
@@ -469,8 +469,9 @@ static b32 process_entity(CompilerState* compiler_state, Entity* ent) {
 
     if (compiler_state->options->verbose_output == 2) {
         if (ent->expr && ent->expr->token)
-            printf("%s | %s:%i:%i\n",
+            printf("%s | %s | %s:%i:%i\n",
                 entity_state_strings[ent->state],
+                entity_type_strings[ent->type],
                 ent->expr->token->pos.filename,
                 ent->expr->token->pos.line,
                 ent->expr->token->pos.column);
index d3d7d4724e6339fba2bbbaf5363b7abde11a2fbf..ab6b8aba2b8404dffc2549726759b0a38058c4b9 100644 (file)
@@ -925,7 +925,63 @@ CheckStatus check_unaryop(AstUnaryOp** punop) {
 }
 
 CheckStatus check_struct_literal(AstStructLiteral* sl) {
+    if (!node_is_type((AstNode *) sl->stnode)) {
+        onyx_report_error(sl->token->pos, "Struct type is not a type.");
+        return Check_Error;
+    }
+
     fill_in_type((AstTyped *) sl);
+    if (sl->type == NULL) return Check_Error;
+
+    if (!type_is_structlike_strict(sl->type)) {
+        onyx_report_error(sl->token->pos, "Type is not a constructable using a struct literal.");
+        return Check_Error;
+    }
+
+    if (bh_arr_length(sl->values) == 0) {
+        bh_arr_new(global_heap_allocator, sl->values, type_structlike_mem_count(sl->type));
+        bh_arr_set_length(sl->values, type_structlike_mem_count(sl->type));
+        bh_arr_zero(sl->values);
+
+        StructMember s;
+        bh_arr_each(AstStructMember *, smem, sl->named_values) {
+            token_toggle_end((*smem)->token);
+            if (!type_lookup_member(sl->type, (*smem)->token->text, &s)) {
+                onyx_report_error((*smem)->token->pos,
+                    "The field '%s' does not exist on type '%s'.", (*smem)->token->text, type_get_name(sl->type));
+                token_toggle_end((*smem)->token);
+                return Check_Error;
+            }
+            token_toggle_end((*smem)->token);
+
+            if (s.included_through_use) {
+                onyx_report_error((*smem)->token->pos, "Cannot specify value for member '%s', whic was included through a 'use' statement.", s.name);
+                return Check_Error;
+            }
+
+            if (sl->values[s.idx] != NULL) {
+                onyx_report_error((*smem)->token->pos, "Multiple values given for '%b'.", (*smem)->token->text, (*smem)->token->length);
+                return Check_Error;
+            }
+
+            sl->values[s.idx] = (*smem)->initial_value;
+        }
+
+        if (sl->type->kind == Type_Kind_Struct) {
+            bh_arr_each(StructMember*, smem, sl->type->Struct.memarr) {
+                u32 idx = (*smem)->idx;
+
+                if (sl->values[idx] == NULL) {
+                    if ((*smem)->initial_value == NULL) {
+                        onyx_report_error(sl->token->pos, "No value was given for the field '%s'.", (*smem)->name);
+                        return Check_Error;
+                    }
+
+                    sl->values[idx] = *(*smem)->initial_value;
+                }
+            }
+        }
+    }
 
     i32 mem_count = type_structlike_mem_count(sl->type);
 
@@ -975,9 +1031,18 @@ CheckStatus check_struct_literal(AstStructLiteral* sl) {
 }
 
 CheckStatus check_array_literal(AstArrayLiteral* al) {
+    if (!node_is_type((AstNode *) al->atnode)) {
+        onyx_report_error(al->token->pos, "Array type is not a type.");
+        return Check_Error;
+    }
+
     fill_in_type((AstTyped *) al);
 
-    assert(al->type->kind == Type_Kind_Array);
+    al->type = type_make_array(semstate.allocator, al->type, bh_arr_length(al->values));
+    if (al->type == NULL || al->type->kind != Type_Kind_Array) {
+        onyx_report_error(al->token->pos, "Expected array type for array literal. This is a compiler bug.");
+        return Check_Error;
+    }
 
     if (al->type->Array.count != (u32) bh_arr_length(al->values)) {
         onyx_report_error(al->token->pos, "Wrong array size (%d) for number of values (%d).",
@@ -1031,9 +1096,9 @@ CheckStatus check_range_literal(AstRangeLiteral** prange) {
     if (range->step == NULL) {
         type_lookup_member(expected_range_type, "step", &smem);
         assert(smem.initial_value != NULL);
-        CHECK(expression, &smem.initial_value);
+        CHECK(expression, smem.initial_value);
 
-        range->step = smem.initial_value;
+        range->step = *smem.initial_value;
     }
 
     return Check_Success;
@@ -1244,7 +1309,7 @@ CheckStatus check_expression(AstTyped** pexpr) {
 
         case Ast_Kind_Symbol:
             onyx_report_error(expr->token->pos,
-                    "Unable to resolve symbol '%b'.",
+                    "Symbol was unresolved in symbol resolution phase, '%b'. This is definitely a compiler bug.",
                     expr->token->text, expr->token->length);
             retval = Check_Error;
             break;
index 0f9154c7c21695fc7af91213fd6c82b9ea7250e0..9773e6135785b28a2c5739c66e482d4b6c235ca6 100644 (file)
@@ -305,13 +305,7 @@ static void symres_unaryop(AstUnaryOp** unaryop) {
 }
 
 static void symres_struct_literal(AstStructLiteral* sl) {
-    // @CLEANUP
     if (sl->stnode != NULL) symres_expression(&sl->stnode);
-    if (!node_is_type((AstNode *) sl->stnode)) {
-        onyx_report_error(sl->token->pos, "Struct type is not a type.");
-        return;
-    }
-
     sl->stnode = (AstTyped *) symres_type((AstType *) sl->stnode);
     if (sl->stnode == NULL || sl->stnode->kind == Ast_Kind_Error || sl->stnode->kind == Ast_Kind_Symbol) return;
 
@@ -319,72 +313,23 @@ static void symres_struct_literal(AstStructLiteral* sl) {
     while (sl->type_node->kind == Ast_Kind_Type_Alias)
         sl->type_node = ((AstTypeAlias *) sl->type_node)->to;
 
-    sl->type = type_build_from_ast(semstate.allocator, sl->type_node);
-
-    if (sl->type == NULL) return;
-
-    if (!type_is_structlike_strict(sl->type)) {
-        onyx_report_error(sl->token->pos, "Type is not a constructable using a struct literal.");
-        return;
+    if (sl->values != NULL) {
+        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);
+        }
     }
 
-    if (bh_arr_length(sl->values) == 0) {
-        bh_arr_new(global_heap_allocator, sl->values, type_structlike_mem_count(sl->type));
-        bh_arr_set_length(sl->values, type_structlike_mem_count(sl->type));
-        bh_arr_zero(sl->values);
-
-        StructMember s;
+    if (sl->named_values != NULL) {
         bh_arr_each(AstStructMember *, smem, sl->named_values) {
-            token_toggle_end((*smem)->token);
-            if (!type_lookup_member(sl->type, (*smem)->token->text, &s)) {
-                onyx_report_error((*smem)->token->pos,
-                    "The field '%s' does not exist on type '%s'.", (*smem)->token->text, type_get_name(sl->type));
-                token_toggle_end((*smem)->token);
-                return;
-            }
-            token_toggle_end((*smem)->token);
-
-            if (s.included_through_use) {
-                onyx_report_error((*smem)->token->pos, "Cannot specify value for member '%s', whic was included through a 'use' statement.", s.name);
-                return;
-            }
-
-            if (sl->values[s.idx] != NULL) {
-                onyx_report_error((*smem)->token->pos, "Multiple values given for '%b'.", (*smem)->token->text, (*smem)->token->length);
-                return;
-            }
-
-            sl->values[s.idx] = (*smem)->initial_value;
-        }
-
-        if (sl->type->kind == Type_Kind_Struct) {
-            bh_arr_each(StructMember*, smem, sl->type->Struct.memarr) {
-                u32 idx = (*smem)->idx;
-
-                if (sl->values[idx] == NULL) {
-                    if ((*smem)->initial_value == NULL) {
-                        onyx_report_error(sl->token->pos, "No value was given for the field '%s'.", (*smem)->name);
-                        return;
-                    }
-
-                    sl->values[idx] = (*smem)->initial_value;
-                }
-            }
+            if ((*smem)->initial_value == NULL) onyx_report_error(sl->token->pos, "Some kind of error occured with this struct literal.");
+            else                                symres_expression(&(*smem)->initial_value);
         }
     }
-
-    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) {
     if (al->atnode != NULL) symres_expression(&al->atnode);
-    if (!node_is_type((AstNode *) al->atnode)) {
-        onyx_report_error(al->token->pos, "Array type is not a type.");
-        return;
-    }
 
     al->atnode = (AstTyped *) symres_type((AstType *) al->atnode);
     if (al->atnode == NULL || al->atnode->kind == Ast_Kind_Error || al->atnode->kind == Ast_Kind_Symbol) return;
@@ -393,12 +338,6 @@ static void symres_array_literal(AstArrayLiteral* al) {
     while (al->type_node->kind == Ast_Kind_Type_Alias)
         al->type_node = ((AstTypeAlias *) al->type_node)->to;
 
-    al->type = type_build_from_ast(semstate.allocator, al->type_node);
-    if (al->type == NULL) return;
-
-    al->type = type_make_array(semstate.allocator, al->type, bh_arr_length(al->values));
-    if (al->type == NULL) return;
-
     bh_arr_each(AstTyped *, expr, al->values)
         symres_expression(expr);
 
index 10765a199c72fb1e9766ce2bc1b20926e85a40d4..d346d960031bf0ff41ea2cc7c488fca79ef5ad73 100644 (file)
@@ -368,7 +368,7 @@ Type* type_build_from_ast(bh_allocator alloc, AstType* type_node) {
                     .type = (*member)->type,
                     .idx = idx,
                     .name = bh_strdup(alloc, (*member)->token->text),
-                    .initial_value = (*member)->initial_value,
+                    .initial_value = &(*member)->initial_value,
                     .included_through_use = 0,
                 };