Many small changes; working on function calls
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Wed, 17 Jun 2020 03:37:07 +0000 (22:37 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Wed, 17 Jun 2020 03:37:07 +0000 (22:37 -0500)
This version does not work for the minimal.onyx.

docs/plan
include/onyxlex.h
include/onyxparser.h
onyx
progs/demo.onyx
progs/minimal.onyx
progs/mvp.onyx
src/onyxlex.c
src/onyxparser.c
src/onyxwasm.c

index d91c21b57d68b6e3ea651dac0fa279ac4b9c7a66..b297a650c668e24465109bdbddaefe8205e1b517 100644 (file)
--- a/docs/plan
+++ b/docs/plan
@@ -52,11 +52,12 @@ HOW:
 
                        casts X to type T
 
-               [ ] Numeric literals are parsed and minimum type detected
+               [X] Curly braces are required for all bodies of blocks
+               [ ] Numeric literals are parsed
+               [ ] Numeric literals have the minimum type detected (automatically upcasts)
                [ ] Comparison operators
                [ ] Proper boolean type
                [ ] Conditional branching works as expected
-               [ ] Curly braces are required for all bodies of blocks
                [ ] Simple while loop is functioning as expected
                [ ] break and continue semantics
                [ ] Function calling works for the builtin types
@@ -77,6 +78,10 @@ HOW:
                [ ] Devise and implement a simple set of implicit type casting rules.
                        - Numeric literals always type cast to whatever type is needed (very flexible).
 
+               [ ] Strings should work as pointers to data.
+                       - Literals should be placed in data section with pointers to the start.
+                       - Should strings be null-terminated or a length at the start of the string?
+
                [ ] Start work on evaluating compile time known values.
                        - An expression marked COMPTIME will be reduced to its value in the parse tree.
 
index b1b5eb064bdd41292f73c0fd596e07746ceecf52..366465ab91f62f93f3987a0f7ad91670a4840e3f 100644 (file)
@@ -17,7 +17,6 @@ typedef enum OnyxTokenType {
        TOKEN_TYPE_KEYWORD_FOR,
        TOKEN_TYPE_KEYWORD_DO,
        TOKEN_TYPE_KEYWORD_RETURN,
-       TOKEN_TYPE_KEYWORD_CONST,
        TOKEN_TYPE_KEYWORD_FOREIGN,
        TOKEN_TYPE_KEYWORD_PROC,
        TOKEN_TYPE_KEYWORD_GLOBAL,
@@ -31,8 +30,6 @@ typedef enum OnyxTokenType {
        TOKEN_TYPE_CLOSE_BRACE,
        TOKEN_TYPE_OPEN_BRACKET,
        TOKEN_TYPE_CLOSE_BRACKET,
-       TOKEN_TYPE_OPEN_ANGLE,
-       TOKEN_TYPE_CLOSE_ANGLE,
 
        TOKEN_TYPE_SYM_PLUS,
        TOKEN_TYPE_SYM_MINUS,
@@ -44,8 +41,11 @@ typedef enum OnyxTokenType {
        TOKEN_TYPE_SYM_COLON,
        TOKEN_TYPE_SYM_SEMICOLON,
        TOKEN_TYPE_SYM_COMMA,
+       TOKEN_TYPE_SYM_GREATER,
+       TOKEN_TYPE_SYM_GREATER_EQUAL,
+       TOKEN_TYPE_SYM_LESS,
+       TOKEN_TYPE_SYM_LESS_EQUAL,
        TOKEN_TYPE_SYM_EQUALS,
-       TOKEN_TYPE_SYM_GRAVE,
        TOKEN_TYPE_SYM_TILDE,
        TOKEN_TYPE_SYM_BANG,
        TOKEN_TYPE_SYM_CARET,
index f210da90d0a419f9fcb7d6dacfae010a3c058bc8..631fc0925a8468d8f9f03903bc4d355e337f545a 100644 (file)
@@ -13,6 +13,7 @@ typedef struct OnyxAstNodeScope OnyxAstNodeScope;
 typedef struct OnyxAstNodeBlock OnyxAstNodeBlock;
 typedef struct OnyxAstNodeParam OnyxAstNodeParam;
 typedef struct OnyxAstNodeFuncDef OnyxAstNodeFuncDef;
+typedef struct OnyxAstNodeCall OnyxAstNodeCall;
 
 typedef struct OnyxParser {
        OnyxTokenizer *tokenizer; // NOTE: not used since all tokens are lexed before parsing starts
@@ -162,6 +163,18 @@ struct OnyxAstNodeFuncDef {
        OnyxAstNodeParam *params;
 };
 
+struct OnyxAstNodeCall {
+       OnyxAstNodeKind kind;
+       u32 flags;
+       OnyxToken *token;                       // NOTE: Not specified (undefined)
+       OnyxTypeInfo *type;             // NOTE: The type that the function returns
+       OnyxAstNode *next;
+       OnyxAstNode *callee;            // NOTE: Function definition node
+       OnyxAstNode *arguments;         // NOTE: Expressions that form the actual param list
+                                                               // They will be chained down using the "next" property
+                                                               // unless this becomes used by something else
+};
+
 union OnyxAstNode {
 
        // Generic node structure for capturing all binary ops and statements
@@ -180,6 +193,7 @@ union OnyxAstNode {
        OnyxAstNodeParam as_param;
        OnyxAstNodeLocal as_local;
        OnyxAstNodeScope as_scope;
+       OnyxAstNodeCall as_call;
 };
 
 const char* onyx_ast_node_kind_string(OnyxAstNodeKind kind);
diff --git a/onyx b/onyx
index 74ff9b5d862da4e596e74b3de33f281ac0dcdca4..54fb7e20cea62187341433b97188c40a2131f32b 100755 (executable)
Binary files a/onyx and b/onyx differ
index 2300ab04c6f7770337187cc03ee1c31323f9361d..b36b5c89080e7c6e002d0584dacc17e65ded96e0 100644 (file)
@@ -1,11 +1,7 @@
-/* This is a comment
-This is also the only way to do comments
-*/
-
 use "core"; /* Looks for "core.onyx" in the current directory */
 
 Foo :: struct { x i32, y i32 };
 
 add :: proc (a i32, b i32) -> i32 {
     return a + b + 1234.56;
-};
\ No newline at end of file
+};
index 17df6c750e699d08084955503074e59e1cdc735a..79fa48570564b7d57b7798edbde0a0aec241ebd8 100644 (file)
@@ -12,13 +12,9 @@ export diff_square :: proc (a i32, b i32) -> i32 {
        c := a - b; // Mutable
        d :: a + b; // Constant
 
-       {
-               f :: 10;
-       };
-
        return (c * d) as i32;
 }
 
 export main :: proc () {
-       
+       add(2, 3);
 }
index cb32d79b2b31d78754ffdd560b8de79f6716532a..dbef39d4d0cc74311838b5eedb5e0c117e2e578c 100644 (file)
@@ -1,27 +1,21 @@
-/* Comments need to be parsed
- /* nested comments /* are /* okay */ */ */
-*/
-
 foreign console {
        log :: proc (data ptr, length i32) -> void ---;
 }
 
 export add :: proc (a i32, b i32) -> i32 {
        return a + b;
-};
+}
 
 export max :: proc (a i32, b i32) -> i32 {
-       /* Curly braces are required */
-       x := "String literal! HERE \\\"Woot Woot\" done";
-
+       // Curly braces are always required
        if a > b {
                return a;
        } else {
                return b;
        }
-};
+}
 
-export main :: proc () -> void {
+export main :: proc () {
        console.log(add(2, 3));
        console.log(max(5, 10));
-};
+}
index 7fdc43707c7c7442a316a3b11c351f3082833577..0a4c3035d6b186a93b8560bad503ef49b01acaf0 100644 (file)
@@ -15,7 +15,6 @@ static const char* onyx_token_type_names[] = {
        "for",                  //"TOKEN_TYPE_KEYWORD_FOR",
        "do",                   //"TOKEN_TYPE_KEYWORD_DO",
        "return",               //"TOKEN_TYPE_KEYWORD_RETURN",
-       "const",                //"TOKEN_TYPE_KEYWORD_CONST",
        "foreign",              //"TOKEN_TYPE_KEYWORD_FOREIGN",
        "proc",                 //"TOKEN_TYPE_KEYWORD_PROC",
        "global",               //"TOKEN_TYPE_KEYWORD_GLOBAL",
@@ -29,8 +28,6 @@ static const char* onyx_token_type_names[] = {
        "}",  //"TOKEN_TYPE_CLOSE_BRACE",
        "[",  //"TOKEN_TYPE_OPEN_BRACKET",
        "]",  //"TOKEN_TYPE_CLOSE_BRACKET",
-       "<",  //"TOKEN_TYPE_OPEN_ANGLE",
-       ">",  //"TOKEN_TYPE_CLOSE_ANGLE",
 
        "+",  // "TOKEN_TYPE_SYM_PLUS",
        "-",  // "TOKEN_TYPE_SYM_MINUS",
@@ -42,8 +39,11 @@ static const char* onyx_token_type_names[] = {
        ":",  // "TOKEN_TYPE_SYM_COLON",
        ";",  // "TOKEN_TYPE_SYM_SEMICOLON",
        ",",  // "TOKEN_TYPE_SYM_COMMA",
+       ">",  // "TOKEN_TYPE_SYM_GREATER",
+       ">=",  // "TOKEN_TYPE_SYM_GREATER_EQUAL",
+       "<",  // "TOKEN_TYPE_SYM_LESS",
+       "<=",  // "TOKEN_TYPE_SYM_LESS_EQUAL",
        "=",  // "TOKEN_TYPE_SYM_EQUALS",
-       "`",  // "TOKEN_TYPE_SYM_GRAVE",
        "~",  // "TOKEN_TYPE_SYM_TILDE",
        "!",  // "TOKEN_TYPE_SYM_BANG",
        "^",  // "TOKEN_TYPE_SYM_CARET",
@@ -139,21 +139,20 @@ OnyxToken* onyx_get_token(OnyxTokenizer* tokenizer) {
        LITERAL_TOKEN("foreign", TOKEN_TYPE_KEYWORD_FOREIGN);
        LITERAL_TOKEN("for", TOKEN_TYPE_KEYWORD_FOR);
        LITERAL_TOKEN("return", TOKEN_TYPE_KEYWORD_RETURN);
-       LITERAL_TOKEN("const", TOKEN_TYPE_KEYWORD_CONST);
        LITERAL_TOKEN("do", TOKEN_TYPE_KEYWORD_DO);
        LITERAL_TOKEN("proc", TOKEN_TYPE_KEYWORD_PROC);
        LITERAL_TOKEN("global", TOKEN_TYPE_KEYWORD_GLOBAL);
        LITERAL_TOKEN("as", TOKEN_TYPE_KEYWORD_CAST);
        LITERAL_TOKEN("->", TOKEN_TYPE_RIGHT_ARROW);
        LITERAL_TOKEN("<-", TOKEN_TYPE_RIGHT_ARROW);
+       LITERAL_TOKEN("<=", TOKEN_TYPE_SYM_LESS_EQUAL);
+       LITERAL_TOKEN(">=", TOKEN_TYPE_SYM_GREATER_EQUAL);
        LITERAL_TOKEN("(", TOKEN_TYPE_OPEN_PAREN);
        LITERAL_TOKEN(")", TOKEN_TYPE_CLOSE_PAREN);
        LITERAL_TOKEN("{", TOKEN_TYPE_OPEN_BRACE);
        LITERAL_TOKEN("}", TOKEN_TYPE_CLOSE_BRACE);
        LITERAL_TOKEN("[", TOKEN_TYPE_OPEN_BRACKET);
        LITERAL_TOKEN("]", TOKEN_TYPE_CLOSE_BRACKET);
-       LITERAL_TOKEN("<", TOKEN_TYPE_OPEN_ANGLE);
-       LITERAL_TOKEN(">", TOKEN_TYPE_CLOSE_ANGLE);
        LITERAL_TOKEN("+", TOKEN_TYPE_SYM_PLUS);
        LITERAL_TOKEN("-", TOKEN_TYPE_SYM_MINUS);
        LITERAL_TOKEN("*", TOKEN_TYPE_SYM_STAR);
@@ -164,8 +163,9 @@ OnyxToken* onyx_get_token(OnyxTokenizer* tokenizer) {
        LITERAL_TOKEN(":", TOKEN_TYPE_SYM_COLON);
        LITERAL_TOKEN(";", TOKEN_TYPE_SYM_SEMICOLON);
        LITERAL_TOKEN(",", TOKEN_TYPE_SYM_COMMA);
+       LITERAL_TOKEN(">", TOKEN_TYPE_SYM_GREATER);
+       LITERAL_TOKEN("<", TOKEN_TYPE_SYM_LESS);
        LITERAL_TOKEN("=", TOKEN_TYPE_SYM_EQUALS);
-       LITERAL_TOKEN("`", TOKEN_TYPE_SYM_GRAVE);
        LITERAL_TOKEN("~", TOKEN_TYPE_SYM_TILDE);
        LITERAL_TOKEN("!", TOKEN_TYPE_SYM_BANG);
        LITERAL_TOKEN("^", TOKEN_TYPE_SYM_CARET);
index 00530182a2dcfadd5d742198fed1109d932ab69b..dff9dbba464bc47ba165428947b6d762f1da1a48 100644 (file)
@@ -1,4 +1,3 @@
-
 #include "onyxlex.h"
 #include "onyxmsgs.h"
 #include "onyxparser.h"
@@ -92,7 +91,6 @@ static void parser_next_token(OnyxParser* parser) {
 
 static void parser_prev_token(OnyxParser* parser) {
        // TODO: This is probably wrong
-       parser->prev_token--;
        while (parser->prev_token->type == TOKEN_TYPE_COMMENT) parser->prev_token--;
        parser->curr_token = parser->prev_token;
        parser->prev_token--;
@@ -214,8 +212,42 @@ static OnyxAstNode* parse_factor(OnyxParser* parser) {
                                        onyx_token_null_toggle(*sym_token);
                                }
 
-                               // TODO: Handle calling a function
-                               return sym_node;
+                               if (parser->curr_token->type != TOKEN_TYPE_OPEN_PAREN) {
+                                       return sym_node;
+                               }
+
+                               // NOTE: Function call
+                               expect(parser, TOKEN_TYPE_OPEN_PAREN);
+
+                               OnyxAstNodeCall* call_node = (OnyxAstNodeCall *) onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_CALL);
+                               call_node->callee = sym_node;
+                               OnyxAstNode** prev = &call_node->arguments;
+                               OnyxAstNode* curr = NULL;
+                               while (parser->curr_token->type != TOKEN_TYPE_CLOSE_PAREN) {
+                                       curr = parse_expression(parser);
+
+                                       if (curr != NULL && curr->kind != ONYX_AST_NODE_KIND_ERROR) {
+                                               *prev = curr;
+                                               prev = &curr->next;
+                                       }
+
+                                       if (parser->curr_token->type == TOKEN_TYPE_CLOSE_PAREN)
+                                               break;
+
+                                       if (parser->curr_token->type != TOKEN_TYPE_SYM_COMMA) {
+                                               onyx_message_add(parser->msgs,
+                                                               ONYX_MESSAGE_TYPE_EXPECTED_TOKEN,
+                                                               parser->curr_token->pos,
+                                                               onyx_get_token_type_name(TOKEN_TYPE_SYM_COMMA),
+                                                               onyx_get_token_type_name(parser->curr_token->type));
+                                               return &error_node;
+                                       }
+
+                                       parser_next_token(parser);
+                               }
+                               parser_next_token(parser);
+
+                               return (OnyxAstNode *) call_node;
                        }
 
                case TOKEN_TYPE_LITERAL_NUMERIC:
@@ -246,6 +278,7 @@ static OnyxAstNode* parse_bin_op(OnyxParser* parser, OnyxAstNode* left) {
        case TOKEN_TYPE_SYM_STAR:               kind = ONYX_AST_NODE_KIND_MULTIPLY; break;
        case TOKEN_TYPE_SYM_FSLASH:             kind = ONYX_AST_NODE_KIND_DIVIDE; break;
        case TOKEN_TYPE_SYM_PERCENT:    kind = ONYX_AST_NODE_KIND_MODULUS; break;
+       default: break;
        }
 
        if (kind != -1) {
@@ -303,6 +336,7 @@ static OnyxAstNode* parse_expression(OnyxParser* parser) {
 
                                return cast_node;
                        }
+               default: break;
        }
 
        return left;
@@ -669,6 +703,8 @@ static OnyxAstNode* parse_top_level_statement(OnyxParser* parser) {
                                        break;
                                }
                        }
+
+               default: break;
        }
 
        parser_next_token(parser);
index 4b9f2007f94a571780bff5121ddcefef9b247c05..2dcff896e0bdfc55cfbdf91cdcf0ddeb60fffed0 100644 (file)
@@ -358,6 +358,12 @@ static void process_expression(OnyxWasmModule* mod, WasmFunc* func, OnyxAstNode*
 
                case ONYX_AST_NODE_KIND_BLOCK: process_block(mod, func, (OnyxAstNodeBlock *) expr); break;
 
+               case ONYX_AST_NODE_KIND_CALL:
+                       {
+                               DEBUG_HERE;
+                               break;
+                       }
+
                default:
                        DEBUG_HERE;
                        bh_printf("Unhandled case: %d\n", expr->kind);