Various improvements and bug fixes
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Tue, 23 Jun 2020 03:20:05 +0000 (22:20 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Tue, 23 Jun 2020 03:20:05 +0000 (22:20 -0500)
include/onyxmsgs.h
misc/onyx.vim
onyx
progs/game.onyx
src/onyx.c
src/onyxmsgs.c
src/onyxparser.c
src/onyxsempass.c
src/onyxtypecheck.c

index b6e0a8fb45f85fa5646b7703e0bb8e41ed462e74..c2919ea91880711182d83bfc858c3c17d8054ddc 100644 (file)
@@ -20,6 +20,7 @@ typedef enum OnyxMessageType {
        ONYX_MESSAGE_TYPE_BINOP_MISMATCH_TYPE,
        ONYX_MESSAGE_TYPE_ASSIGNMENT_TYPE_MISMATCH,
        ONYX_MESSAGE_TYPE_EXPECTED_EXPRESSION,
+    ONYX_MESSAGE_TYPE_CALL_NON_FUNCTION,
 
     ONYX_MESSAGE_TYPE_FUNCTION_RETURN_MISMATCH,
     ONYX_MESSAGE_TYPE_FUNCTION_PARAM_TYPE_MISMATCH,
index 5b008a9714b8cd91dae05fa37cf07f1f0bca8078..4e85c1599071303e1bb0bab9b44e2fb29befb72a 100644 (file)
@@ -12,7 +12,7 @@ set cpo&vim
 
 syn keyword onyxKeyword struct proc use export foreign global
 syn keyword onyxKeyword if elseif else
-syn keyword onyxKeyword for return do
+syn keyword onyxKeyword for while loop return do
 syn keyword onyxKeyword return
 syn keyword onyxKeyword as
 
@@ -21,14 +21,17 @@ syn keyword onyxType i64
 syn keyword onyxType f32
 syn keyword onyxType f64
 
+syn keyword onyxConstant        true false
+
 syn keyword onyxCommentStart   contained TODO NOTE BUG HACK
 
 syn region onyxComment start="//" end="$" keepend contains=onyxCommentStart
 
-hi def link onyxKeyword                Statement
-hi def link onyxType           Type
-hi def link onyxComment                Comment
+hi def link onyxKeyword                    Statement
+hi def link onyxType               Type
+hi def link onyxComment                    Comment
 hi def link onyxCommentStart   Todo
+hi def link onyxConstant        Constant
 
 let b:current_syntax = "onyx"
 let &cpo = s:cpo_save
diff --git a/onyx b/onyx
index 06ca04055b3312b7c0578b066db555927aca8fec..8c6c53a73be7048de096302eae3d6e624f3730f8 100755 (executable)
Binary files a/onyx and b/onyx differ
index 85ac24dafc8121f061afe9a12328fb221d9d0b60..5f90fd7261028db0170893a6790b811048a518f9 100644 (file)
@@ -1,16 +1,12 @@
 
 gfx_draw_rect :: foreign "gfx" "draw_rect" proc (x i32, y i32, w i32, h i32) ---
 
-update :: proc ---
-
-draw :: proc {
-    draw_rect(0, 0, 100, 100);
+export main :: proc {
 }
 
-export main :: proc {
+update :: proc {}
 
-    while true {
-        update();
-        draw();
-    }
+draw :: proc {
+    gfx_draw_rect(0, 0, 100, 100);
 }
+
index f86095d680d0a3d7a356c56a902a753a69994f7f..4699a7e69abcac7116cef22b08f85b51f32209b9 100644 (file)
@@ -50,9 +50,6 @@ int main(int argc, char *argv[]) {
        OnyxParser parser = onyx_parser_create(ast_alloc, &tokenizer, &msgs);
        OnyxAstNode* program = onyx_parse(&parser);
 
-    bh_printf("BEFORE SYMBOL_RESOLUTION: ");
-    onyx_ast_print(program, 1);
-
     bh_arena sp_arena;
     bh_arena_init(&sp_arena, alloc, 16 * 1024);
     bh_allocator sp_alloc = bh_arena_allocator(&sp_arena);
@@ -63,12 +60,10 @@ int main(int argc, char *argv[]) {
        // NOTE: if there are errors, assume the parse tree was generated wrong,
        // even if it may have still been generated correctly.
        if (onyx_message_has_errors(&msgs)) {
-        bh_printf("\n\n");
                onyx_message_print(&msgs);
                goto main_exit;
        } else {
-        bh_printf("\n\nAFTER SYMBOL RESOLUTION: ");
-               onyx_ast_print(program, 1);
+               // onyx_ast_print(program, 1);
            bh_printf("\nNo errors.\n");
     }
 
index 3f87b8743a1454fc63df48ce2df5175156efbcda..3c6018a28117b994beb5776d6926fdb139b68726 100644 (file)
@@ -6,13 +6,14 @@ static const char* msg_formats[] = {
        "expected token '%s', got '%s'",
        "unexpected token '%s'",
        "unknown type '%s'",
-       "expected lval '%s'",
-       "attempt to assign to constant '%s'",
+       "expected lval '%b'",
+       "attempt to assign to constant '%b'",
        "unknown symbol '%s'",
        "redefinition of function '%s'",
        "mismatched types for binary operator, '%s', '%s'",
        "mismatched types on assignment, expected '%s', got '%s'",
        "expected expression, got '%s'",
+    "attempt to call non-function, '%b'",
 
     "returning '%s' from function that returns '%s'",
     "function '%b' expected type '%s' in position '%d', got '%s'",
index 6286e4ce0ca782a5d898adb1844dfac591646e19..a0edfa656644413220bf9095634bbd39ed1ea712 100644 (file)
@@ -448,13 +448,14 @@ static b32 parse_symbol_statement(OnyxParser* parser, OnyxAstNode** ret) {
                        // NOTE: Assignment
                case TOKEN_TYPE_SYM_EQUALS:
                        {
+                OnyxAstNode* assignment = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_ASSIGNMENT);
+                assignment->token = parser->curr_token;
                                parser_next_token(parser);
 
                                OnyxAstNode* lval = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_SYMBOL);
                 lval->token = symbol;
 
                 OnyxAstNode* rval = parse_expression(parser);
-                OnyxAstNode* assignment = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_ASSIGNMENT);
                 assignment->right = rval;
                 assignment->left = lval;
                 *ret = assignment;
@@ -540,20 +541,20 @@ static OnyxAstNode* parse_statement(OnyxParser* parser) {
 }
 
 static OnyxAstNodeBlock* parse_block(OnyxParser* parser) {
+       OnyxAstNodeBlock* block = (OnyxAstNodeBlock *) onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_BLOCK);
+    OnyxAstNodeScope* scope = (OnyxAstNodeScope *) onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_SCOPE);
+    block->scope = scope;
+
        // --- is for an empty block
        if (parser->curr_token->type == TOKEN_TYPE_SYM_MINUS) {
                expect(parser, TOKEN_TYPE_SYM_MINUS);
                expect(parser, TOKEN_TYPE_SYM_MINUS);
                expect(parser, TOKEN_TYPE_SYM_MINUS);
-               return NULL;
+               return block;
        }
 
        expect(parser, TOKEN_TYPE_OPEN_BRACE);
 
-       OnyxAstNodeBlock* block = (OnyxAstNodeBlock *) onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_BLOCK);
-    OnyxAstNodeScope* scope = (OnyxAstNodeScope *) onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_SCOPE);
-    block->scope = scope;
-
        OnyxAstNode** next = &block->body;
        OnyxAstNode* stmt = NULL;
        while (parser->curr_token->type != TOKEN_TYPE_CLOSE_BRACE) {
index d593cb30508749ea70b75f61680bb683e73eb323..0426789b44b01509403f69e72c2777eaf457b484 100644 (file)
@@ -17,7 +17,12 @@ OnyxSemPassState onyx_sempass_create(bh_allocator alloc, bh_allocator node_alloc
     return state;
 }
 
+static void collapse_scopes(OnyxAstNode* root_node, OnyxAstNodeScope* prev_scope) {
+
+}
+
 void onyx_sempass(OnyxSemPassState* state, OnyxAstNode* root_node) {
     onyx_resolve_symbols(state, root_node);
     onyx_type_check(state, root_node);
+    collapse_scopes(root_node, NULL);
 }
index 28b1f72e46b0de91173e9c2ba4ada844478239b0..9a620468fcf423a485e1907f68d67f0503de4fc4 100644 (file)
@@ -20,6 +20,22 @@ static void typecheck_assignment(OnyxSemPassState* state, OnyxAstNode* assign) {
         return;
     }
 
+    if ((assign->left->flags & ONYX_AST_FLAG_LVAL) == 0) {
+        onyx_message_add(state->msgs,
+                ONYX_MESSAGE_TYPE_NOT_LVAL,
+                assign->token->pos,
+                assign->left->token->token, assign->left->token->length);
+        return;
+    }
+
+    if ((assign->left->flags & ONYX_AST_FLAG_CONST) != 0 && assign->left->type->is_known) {
+        onyx_message_add(state->msgs,
+                ONYX_MESSAGE_TYPE_ASSIGN_CONST,
+                assign->token->pos,
+                assign->left->token->token, assign->left->token->length);
+        return;
+    }
+
     typecheck_expression(state, assign->right);
 
     if (!assign->left->type->is_known) {
@@ -72,6 +88,14 @@ static void typecheck_call(OnyxSemPassState* state, OnyxAstNodeCall* call) {
         return;
     }
 
+    if (callee->kind != ONYX_AST_NODE_KIND_FUNCDEF) {
+        onyx_message_add(state->msgs,
+                ONYX_MESSAGE_TYPE_CALL_NON_FUNCTION,
+                call->token->pos,
+                callee->token->token, callee->token->length);
+        return;
+    }
+
     call->type = callee->return_type;
 
     OnyxAstNodeParam* formal_param = callee->params;