Fixed many bugs with type system; Ready to start pointers
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Mon, 13 Jul 2020 03:21:54 +0000 (22:21 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Mon, 13 Jul 2020 03:21:54 +0000 (22:21 -0500)
include/onyxtypes.h
onyx
progs/basic.onyx
src/onyxchecker.c
src/onyxparser.c
src/onyxsymres.c
src/onyxtypes.c

index 5954d375c4db3de328316fcd05d5124e39ba8bde..3f9a1094f8d268b2896e8dc6f075200e9cf59f2e 100644 (file)
@@ -48,7 +48,7 @@ typedef struct Type Type;
 
 #define TYPE_KINDS \
     TYPE_KIND(Basic, TypeBasic)                       \
-    TYPE_KIND(Pointer, struct { TypeBasic base; Type *elem; })
+    TYPE_KIND(Pointer, struct { TypeBasic base; Type *elem; })  // TypePointer utilizes the elements of TypeBasic
 
 typedef enum TypeKind {
     Type_Kind_Invalid,
@@ -85,5 +85,6 @@ extern Type basic_types[];
 struct AstType;
 b32 types_are_compatible(Type* t1, Type* t2);
 Type* type_build_from_ast(bh_allocator alloc, struct AstType* type_node);
+const char* type_get_name(Type* type);
 
 #endif // #ifndef ONYX_TYPES
diff --git a/onyx b/onyx
index 25b0e01d5c1b2fbdd99e8007198a5774e4adb6c1..81422df31ffb49944d9171dd63d9fb1c0b3413c4 100755 (executable)
Binary files a/onyx and b/onyx differ
index 3d3f15844f5885040a46f2bcc3c5934fffed9a1c..2ce18950bd1fb0cf5d0074e8926489b1e74b227a 100644 (file)
@@ -1,9 +1,17 @@
 use "progs/intrinsics"
 
+pointer_test :: proc {
+    p : ^i32 = 0 as ^i32;
+}
+
+print :: foreign "host" "print" proc (val: i32) ---
+
 test :: proc (a: bool) -> i32 {
     return 0;
 }
 
 export main :: proc {
     a : i32 = 0;
+
+    print(a);
 }
index 38b9bac4c4fd26e01c0fcf8ae7653634377ee2f9..5b14f880c42c533ebc7e8399dd61e7fe037e97ae 100644 (file)
@@ -52,7 +52,8 @@ static void check_assignment(OnyxSemPassState* state, AstAssign* assign) {
             onyx_message_add(state->msgs,
                     ONYX_MESSAGE_TYPE_ASSIGNMENT_TYPE_MISMATCH,
                     assign->base.token->pos,
-                    "TEMP", "TEMP");
+                    type_get_name(assign->lval->type),
+                    type_get_name(assign->expr->type));
             return;
         }
     }
@@ -66,7 +67,8 @@ static void check_return(OnyxSemPassState* state, AstReturn* retnode) {
             onyx_message_add(state->msgs,
                     ONYX_MESSAGE_TYPE_FUNCTION_RETURN_MISMATCH,
                     retnode->expr->token->pos,
-                    "TEMP", "TEMP");
+                    type_get_name(retnode->expr->type),
+                    type_get_name(state->expected_return_type));
         }
     } else {
         if (state->expected_return_type->Basic.size > 0) {
@@ -81,7 +83,8 @@ static void check_return(OnyxSemPassState* state, AstReturn* retnode) {
 static void check_if(OnyxSemPassState* state, AstIf* ifnode) {
     check_expression(state, ifnode->cond);
 
-    if (ifnode->cond->type->kind != Type_Kind_Basic
+    if (ifnode->cond->type == NULL
+            || ifnode->cond->type->kind != Type_Kind_Basic
             || ifnode->cond->type->Basic.kind != Basic_Kind_Bool) {
 
         onyx_message_add(state->msgs,
@@ -98,7 +101,8 @@ static void check_if(OnyxSemPassState* state, AstIf* ifnode) {
 static void check_while(OnyxSemPassState* state, AstWhile* whilenode) {
     check_expression(state, whilenode->cond);
 
-    if (whilenode->cond->type->kind != Type_Kind_Basic
+    if (whilenode->cond->type == NULL
+            || whilenode->cond->type->kind != Type_Kind_Basic
             || whilenode->cond->type->Basic.kind != Basic_Kind_Bool) {
 
         onyx_message_add(state->msgs,
@@ -214,8 +218,9 @@ static void check_call(OnyxSemPassState* state, AstCall* call) {
                     ONYX_MESSAGE_TYPE_FUNCTION_PARAM_TYPE_MISMATCH,
                     actual_param->value->token->pos,
                     callee->base.token->text, callee->base.token->length,
-                    "TEMP", arg_pos,
-                    "TEMP");
+                    type_get_name(formal_param->base.type),
+                    arg_pos,
+                    type_get_name(actual_param->base.type));
             return;
         }
 
@@ -262,7 +267,9 @@ static void check_binaryop(OnyxSemPassState* state, AstBinaryOp* binop) {
     }
 
     if (binop->left->type->kind == Type_Kind_Pointer
-            || binop->right->type->kind == Type_Kind_Pointer) {
+            || binop->right->type->kind == Type_Kind_Pointer
+            || (binop->left->type->Basic.flags & Basic_Flag_Pointer)
+            || (binop->right->type->Basic.flags & Basic_Flag_Pointer)) {
         onyx_message_add(state->msgs,
                 ONYX_MESSAGE_TYPE_LITERAL,
                 binop->base.token->pos,
@@ -274,7 +281,8 @@ static void check_binaryop(OnyxSemPassState* state, AstBinaryOp* binop) {
         onyx_message_add(state->msgs,
                 ONYX_MESSAGE_TYPE_BINOP_MISMATCH_TYPE,
                 binop->base.token->pos,
-                "TEMP", "TEMP");
+                type_get_name(binop->left->type),
+                type_get_name(binop->right->type));
         return;
     }
 
@@ -297,9 +305,12 @@ static void check_expression(OnyxSemPassState* state, AstTyped* expr) {
             break;
 
         case Ast_Kind_Unary_Op:
+            check_expression(state, ((AstUnaryOp *) expr)->expr);
+
             if (((AstUnaryOp *) expr)->operation != Unary_Op_Cast) {
-                check_expression(state, ((AstUnaryOp *) expr)->expr);
                 expr->type = ((AstUnaryOp *) expr)->expr->type;
+            } else {
+                expr->type = type_build_from_ast(state->node_allocator, expr->type_node);
             }
             break;
 
@@ -368,21 +379,21 @@ static void check_global(OnyxSemPassState* state, AstGlobal* global) {
                         ONYX_MESSAGE_TYPE_GLOBAL_TYPE_MISMATCH,
                         global->base.token->pos,
                         global->base.token->text, global->base.token->length,
-                        "TEMP", "TEMP");
+                        type_get_name(global->base.type),
+                        type_get_name(global->initial_value->type));
                 return;
             }
         } else {
             if (global->initial_value->type)
                 global->base.type = global->initial_value->type;
         }
+    }
 
-    } else {
-        if (global->base.type == NULL) {
-            onyx_message_add(state->msgs,
-                    ONYX_MESSAGE_TYPE_LITERAL,
-                    global->base.token->pos,
-                    "global variable with unknown type");
-        }
+    if (global->base.type == NULL) {
+        onyx_message_add(state->msgs,
+                ONYX_MESSAGE_TYPE_LITERAL,
+                global->base.token->pos,
+                "global variable with unknown type");
     }
 }
 
@@ -455,6 +466,10 @@ static void check_function(OnyxSemPassState* state, AstFunction* func) {
 
 void onyx_type_check(OnyxSemPassState* state, OnyxProgram* program) {
 
+    bh_arr_each(AstForeign *, foreign, program->foreigns)
+        if ((*foreign)->import->kind == Ast_Kind_Function)
+            check_function(state, (AstFunction *) (*foreign)->import);
+
     bh_arr_each(AstGlobal *, global, program->globals)
         check_global(state, *global);
 
index 3356c981eed69f19a8360f55216eae018ac86aae..1659875015f1f26f2c2911c024405a2f6e4efc5e 100644 (file)
@@ -395,7 +395,8 @@ static b32 parse_symbol_statement(OnyxParser* parser, AstNode** ret) {
                 AstType* type_node = NULL;
 
                 // NOTE: var: type
-                if (parser->curr_token->type == Token_Type_Symbol) {
+                if (parser->curr_token->type != ':'
+                        && parser->curr_token->type != '=') {
                     type_node = parse_type(parser);
                 }
 
@@ -621,6 +622,7 @@ static AstType* parse_type(OnyxParser* parser) {
 
     while (1) {
         if (parser->curr_token->type == '^') {
+            parser_next_token(parser);
             AstPointerType* new = make_node(AstPointerType, Ast_Kind_Pointer_Type);
             *next_insertion = (AstType *) new;
             next_insertion = &new->elem;
index 06e430443a65e2178a04758a60a74e55456b77ad..fa72c3488370b19f45261c9ee591cc97e0be0386 100644 (file)
@@ -324,6 +324,12 @@ void onyx_resolve_symbols(OnyxSemPassState* state, OnyxProgram* program) {
             if (!symbol_unique_introduce(state, (*foreign)->import)) return;
     }
 
+    bh_arr_each(AstForeign *, foreign, program->foreigns) {
+        if ((*foreign)->import->kind == Ast_Kind_Function) {
+            symres_function(state, (AstFunction *) (*foreign)->import);
+        }
+    }
+
 
     // NOTE: Then, resolve all symbols in all functions
     bh_arr_each(AstFunction *, function, program->functions)
index f70a271087cf2daf40c3be2930646ad73f3a051d..1960b76737b7348fc535ecd3d1e12bd448277ba1 100644 (file)
@@ -1,20 +1,20 @@
 #include "onyxtypes.h"
 #include "onyxastnodes.h"
+#include "onyxutils.h"
 
-// NOTE: These have to be in the same order as Basiuc
+// NOTE: These have to be in the same order as Basic
 Type basic_types[] = {
     { Type_Kind_Basic, { Basic_Kind_Void,                    0,                       0, "void"   } },
 
     { Type_Kind_Basic, { Basic_Kind_Bool,   Basic_Flag_Boolean,                       1, "bool"   } },
 
     { Type_Kind_Basic, { Basic_Kind_I8,     Basic_Flag_Integer,                       1, "i8"     } },
-    { Type_Kind_Basic, { Basic_Kind_I16,    Basic_Flag_Integer,                       2, "i16"    } },
-    { Type_Kind_Basic, { Basic_Kind_I32,    Basic_Flag_Integer,                       4, "i32"    } },
-    { Type_Kind_Basic, { Basic_Kind_I64,    Basic_Flag_Integer,                       8, "i64"    } },
-
     { Type_Kind_Basic, { Basic_Kind_U8,     Basic_Flag_Integer | Basic_Flag_Unsigned, 1, "u8"     } },
+    { Type_Kind_Basic, { Basic_Kind_I16,    Basic_Flag_Integer,                       2, "i16"    } },
     { Type_Kind_Basic, { Basic_Kind_U16,    Basic_Flag_Integer | Basic_Flag_Unsigned, 2, "u16"    } },
+    { Type_Kind_Basic, { Basic_Kind_I32,    Basic_Flag_Integer,                       4, "i32"    } },
     { Type_Kind_Basic, { Basic_Kind_U32,    Basic_Flag_Integer | Basic_Flag_Unsigned, 4, "u32"    } },
+    { Type_Kind_Basic, { Basic_Kind_I64,    Basic_Flag_Integer,                       8, "i64"    } },
     { Type_Kind_Basic, { Basic_Kind_U64,    Basic_Flag_Integer | Basic_Flag_Unsigned, 8, "u64"    } },
 
     { Type_Kind_Basic, { Basic_Kind_F32,    Basic_Flag_Float,                         4, "f32"    } },
@@ -27,6 +27,7 @@ b32 types_are_compatible(Type* t1, Type* t2) {
     // NOTE: If they are pointing to the same thing,
     // it is safe to assume they are the same type
     if (t1 == t2) return 1;
+    if (t1 == NULL || t2 == NULL) return 0;
 
     switch (t1->kind) {
         case Type_Kind_Basic:
@@ -55,11 +56,12 @@ Type* type_build_from_ast(bh_allocator alloc, AstType* type_node) {
 
     switch (type_node->kind) {
         case Ast_Kind_Pointer_Type: {
-            TypePointer* ptr_type = bh_alloc_item(alloc, TypePointer);
+            Type* ptr_type = bh_alloc_item(alloc, Type);
 
-            ptr_type->base.flags |= Basic_Flag_Pointer;
-            ptr_type->base.size = 4;
-            ptr_type->elem = type_build_from_ast(alloc, ((AstPointerType *) type_node)->elem);
+            ptr_type->kind = Type_Kind_Pointer;
+            ptr_type->Pointer.base.flags |= Basic_Flag_Pointer;
+            ptr_type->Pointer.base.size = 4;
+            ptr_type->Pointer.elem = type_build_from_ast(alloc, ((AstPointerType *) type_node)->elem);
 
             return (Type *) ptr_type;
         }
@@ -72,3 +74,13 @@ Type* type_build_from_ast(bh_allocator alloc, AstType* type_node) {
             return NULL;
     }
 }
+
+const char* type_get_name(Type* type) {
+    if (type == NULL) return "unknown";
+
+    switch (type->kind) {
+        case Type_Kind_Basic: return type->Basic.name;
+        case Type_Kind_Pointer: return bh_aprintf(global_scratch_allocator, "^%s", type_get_name(type->Pointer.elem));
+        default: return "unknown";
+    }
+}