From 1b8763dae82da3809aca609f027a5e1e3f41523f Mon Sep 17 00:00:00 2001 From: Brendan Hansen Date: Tue, 19 May 2020 17:59:20 -0500 Subject: [PATCH] Working more on the parser --- onyx | Bin 69296 -> 68704 bytes onyx.c | 17 ++-- onyxlex.c | 84 ++++++++-------- onyxlex.h | 4 +- onyxmsgs.c | 2 +- onyxparser.c | 243 +++++++++++++++++++++++++-------------------- onyxparser.h | 5 +- progs/minimal.onyx | 9 +- 8 files changed, 203 insertions(+), 161 deletions(-) diff --git a/onyx b/onyx index 1cada87b18070428c1c4e5a7f8e4f39090250da9..bd859e2258a9ab525bdcccf169e25f0891856924 100755 GIT binary patch literal 68704 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 z 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 diff --git a/onyx.c b/onyx.c index 8406fc07..3840fa00 100644 --- a/onyx.c +++ b/onyx.c @@ -1,5 +1,5 @@ #define BH_NO_STRING -#define BH_DEBUG +// #define BH_DEBUG #define BH_DEFINE #include "bh.h" @@ -23,16 +23,16 @@ int main(int argc, char *argv[]) { bh_file_close(&source_file); OnyxTokenizer tokenizer = onyx_tokenizer_create(alloc, &fc); - onyx_parse_tokens(&tokenizer); + onyx_lex_tokens(&tokenizer); bh_arr(OnyxToken) token_arr = tokenizer.tokens; - printf("There are %d tokens (Allocated space for %d tokens)\n", bh_arr_length(token_arr), bh_arr_capacity(token_arr)); + // printf("There are %d tokens (Allocated space for %d tokens)\n", bh_arr_length(token_arr), bh_arr_capacity(token_arr)); - for (OnyxToken* it = token_arr; !bh_arr_end(token_arr, it); it++) { - onyx_token_null_toggle(*it); - printf("%s '%s' (%s:%ld:%ld)\n", onyx_get_token_type_name(*it), it->token, it->pos.filename, it->pos.line, it->pos.column); - onyx_token_null_toggle(*it); - } + // for (OnyxToken* it = token_arr; !bh_arr_end(token_arr, it); it++) { + // onyx_token_null_toggle(*it); + // printf("%s '%s' (%s:%ld:%ld)\n", onyx_get_token_type_name(*it), it->token, it->pos.filename, it->pos.line, it->pos.column); + // onyx_token_null_toggle(*it); + // } bh_arena msg_arena; bh_arena_init(&msg_arena, alloc, 4096); @@ -52,6 +52,7 @@ int main(int argc, char *argv[]) { bh_file_contents_delete(&fc); onyx_tokenizer_free(&tokenizer); + onyx_parser_free(&parser); bh_arena_free(&msg_arena); bh_arena_free(&ast_arena); diff --git a/onyxlex.c b/onyxlex.c index 2f790a1b..ca877d6c 100644 --- a/onyxlex.c +++ b/onyxlex.c @@ -7,45 +7,45 @@ static const char* onyx_token_type_names[] = { "TOKEN_TYPE_COMMENT", - "TOKEN_TYPE_KEYWORD_STRUCT", - "TOKEN_TYPE_KEYWORD_USE", - "TOKEN_TYPE_KEYWORD_EXPORT", - "TOKEN_TYPE_KEYWORD_IF", - "TOKEN_TYPE_KEYWORD_ELSE", - "TOKEN_TYPE_KEYWORD_FOR", - "TOKEN_TYPE_KEYWORD_DO", - "TOKEN_TYPE_KEYWORD_RETURN", - "TOKEN_TYPE_KEYWORD_FOREIGN", - "TOKEN_TYPE_KEYWORD_PROC", - "TOKEN_TYPE_KEYWORD_GLOBAL", - - "TOKEN_TYPE_RIGHT_ARROW", - "TOKEN_TYPE_LEFT_ARROW", - "TOKEN_TYPE_OPEN_PAREN", - "TOKEN_TYPE_CLOSE_PAREN", - "TOKEN_TYPE_OPEN_BRACE", - "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", - "TOKEN_TYPE_SYM_STAR", - "TOKEN_TYPE_SYM_PERCENT", - "TOKEN_TYPE_SYM_DOT", - "TOKEN_TYPE_SYM_FSLASH", - "TOKEN_TYPE_SYM_BSLASH", - "TOKEN_TYPE_SYM_COLON", - "TOKEN_TYPE_SYM_SEMICOLON", - "TOKEN_TYPE_SYM_COMMA", - "TOKEN_TYPE_SYM_EQUALS", - "TOKEN_TYPE_SYM_GRAVE", - "TOKEN_TYPE_SYM_TILDE", - "TOKEN_TYPE_SYM_BANG", - "TOKEN_TYPE_SYM_CARET", - "TOKEN_TYPE_SYM_AMPERSAND", + "struct", //"TOKEN_TYPE_KEYWORD_STRUCT", + "use", //"TOKEN_TYPE_KEYWORD_USE", + "export", //"TOKEN_TYPE_KEYWORD_EXPORT", + "if", //"TOKEN_TYPE_KEYWORD_IF", + "else", //"TOKEN_TYPE_KEYWORD_ELSE", + "for", //"TOKEN_TYPE_KEYWORD_FOR", + "do", //"TOKEN_TYPE_KEYWORD_DO", + "return", //"TOKEN_TYPE_KEYWORD_RETURN", + "foreign", //"TOKEN_TYPE_KEYWORD_FOREIGN", + "proc", //"TOKEN_TYPE_KEYWORD_PROC", + "global", //"TOKEN_TYPE_KEYWORD_GLOBAL", + + "->", //"TOKEN_TYPE_RIGHT_ARROW", + "<-", //"TOKEN_TYPE_LEFT_ARROW", + "(", //"TOKEN_TYPE_OPEN_PAREN", + ")", //"TOKEN_TYPE_CLOSE_PAREN", + "{", //"TOKEN_TYPE_OPEN_BRACE", + "}", //"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", + "*", // "TOKEN_TYPE_SYM_STAR", + "%", // "TOKEN_TYPE_SYM_PERCENT", + ".", // "TOKEN_TYPE_SYM_DOT", + "/", // "TOKEN_TYPE_SYM_FSLASH", + "\\", // "TOKEN_TYPE_SYM_BSLASH", + ":", // "TOKEN_TYPE_SYM_COLON", + ";", // "TOKEN_TYPE_SYM_SEMICOLON", + ",", // "TOKEN_TYPE_SYM_COMMA", + "=", // "TOKEN_TYPE_SYM_EQUALS", + "`", // "TOKEN_TYPE_SYM_GRAVE", + "~", // "TOKEN_TYPE_SYM_TILDE", + "!", // "TOKEN_TYPE_SYM_BANG", + "^", // "TOKEN_TYPE_SYM_CARET", + "&", // "TOKEN_TYPE_SYM_AMPERSAND", "TOKEN_TYPE_SYMBOL", "TOKEN_TYPE_LITERAL_STRING", @@ -85,8 +85,8 @@ static b32 token_lit(OnyxTokenizer* tokenizer, OnyxToken* tk, char* lit, OnyxTok return 0; } -const char* onyx_get_token_type_name(OnyxToken tkn) { - return onyx_token_type_names[tkn.type]; +const char* onyx_get_token_type_name(OnyxTokenType tkn_type) { + return onyx_token_type_names[tkn_type]; } void onyx_token_null_toggle(OnyxToken tkn) { @@ -267,7 +267,7 @@ void onyx_tokenizer_free(OnyxTokenizer* tokenizer) { bh_arr_free(tokenizer->tokens); } -void onyx_parse_tokens(OnyxTokenizer* tokenizer) { +void onyx_lex_tokens(OnyxTokenizer* tokenizer) { OnyxToken* tk; do { tk = onyx_get_token(tokenizer); diff --git a/onyxlex.h b/onyxlex.h index 9a3b3f12..1fbce3a9 100644 --- a/onyxlex.h +++ b/onyxlex.h @@ -79,11 +79,11 @@ typedef struct OnyxTokenizer { bh_arr(OnyxToken) tokens; } OnyxTokenizer; -const char* onyx_get_token_type_name(OnyxToken tkn); +const char* onyx_get_token_type_name(OnyxTokenType tkn_type); void onyx_token_null_toggle(OnyxToken tkn); OnyxToken* onyx_get_token(OnyxTokenizer* tokenizer); OnyxTokenizer onyx_tokenizer_create(bh_allocator allocator, bh_file_contents *fc); void onyx_tokenizer_free(OnyxTokenizer* tokenizer); -void onyx_parse_tokens(OnyxTokenizer* tokenizer); +void onyx_lex_tokens(OnyxTokenizer* tokenizer); #endif diff --git a/onyxmsgs.c b/onyxmsgs.c index 9838fa02..81f7b1df 100644 --- a/onyxmsgs.c +++ b/onyxmsgs.c @@ -2,7 +2,7 @@ #include "onyxmsgs.h" static const char* msg_formats[] = { - "expected token '%s'", + "expected token '%s', got '%s'", "unexpected token '%s'", "unknown type '%s'" }; diff --git a/onyxparser.c b/onyxparser.c index 002dd6ce..f194266b 100644 --- a/onyxparser.c +++ b/onyxparser.c @@ -5,24 +5,24 @@ struct OnyxTypeInfo builtin_types[] = { { ONYX_TYPE_INFO_KIND_UNKNOWN, 0, "unknown" }, { ONYX_TYPE_INFO_KIND_VOID, 0, "void" }, - + { ONYX_TYPE_INFO_KIND_BOOL, 1, "bool", 0, 0, 0, 1 }, - + { ONYX_TYPE_INFO_KIND_UINT8, 1, "u8", 1, 1, 0, 0 }, { ONYX_TYPE_INFO_KIND_UINT16, 2, "u16", 1, 1, 0, 0 }, { ONYX_TYPE_INFO_KIND_UINT32, 4, "u32", 1, 1, 0, 0 }, { ONYX_TYPE_INFO_KIND_UINT64, 8, "u64", 1, 1, 0, 0 }, - + { ONYX_TYPE_INFO_KIND_INT8, 1, "i8", 1, 0, 0, 0 }, { ONYX_TYPE_INFO_KIND_INT16, 2, "i16", 1, 0, 0, 0 }, { ONYX_TYPE_INFO_KIND_INT32, 4, "i32", 1, 0, 0, 0 }, { ONYX_TYPE_INFO_KIND_INT64, 8, "i64", 1, 0, 0, 0 }, - + { ONYX_TYPE_INFO_KIND_FLOAT32, 4, "f32", 0, 0, 1, 0 }, { ONYX_TYPE_INFO_KIND_FLOAT64, 8, "f64", 0, 0, 1, 0 }, { ONYX_TYPE_INFO_KIND_SOFT_FLOAT, 8, "sf64", 0, 0, 1, 0 }, - - { 0xffffffff } + + { 0xffffffff } // Sentinel }; static OnyxAstNode error_node = { { ONYX_AST_NODE_KIND_ERROR, 0, NULL, &builtin_types[0], NULL, NULL, NULL } }; @@ -30,16 +30,17 @@ static OnyxAstNode error_node = { { ONYX_AST_NODE_KIND_ERROR, 0, NULL, &builtin_ static void parser_next_token(OnyxParser* parser) { parser->prev_token = parser->curr_token; parser->curr_token++; + while (parser->curr_token->type == TOKEN_TYPE_COMMENT) parser->curr_token++; } static b32 is_terminating_token(OnyxTokenType token_type) { switch (token_type) { - case TOKEN_TYPE_SYM_SEMICOLON: - case TOKEN_TYPE_CLOSE_BRACE: - case TOKEN_TYPE_OPEN_BRACE: - case TOKEN_TYPE_END_STREAM: + case TOKEN_TYPE_SYM_SEMICOLON: + case TOKEN_TYPE_CLOSE_BRACE: + case TOKEN_TYPE_OPEN_BRACE: + case TOKEN_TYPE_END_STREAM: return 1; - default: + default: return 0; } } @@ -47,12 +48,16 @@ static b32 is_terminating_token(OnyxTokenType token_type) { // Advances to next token no matter what static OnyxToken* expect(OnyxParser* parser, OnyxTokenType token_type) { OnyxToken* token = parser->curr_token; + parser_next_token(parser); + if (token->type != token_type) { - onyx_message_add(parser->msgs, ONYX_MESSAGE_TYPE_EXPECTED_TOKEN, token->pos, onyx_get_token_type_name(*token)); + onyx_message_add(parser->msgs, + ONYX_MESSAGE_TYPE_EXPECTED_TOKEN, + token->pos, + onyx_get_token_type_name(token_type), onyx_get_token_type_name(token->type)); return NULL; } - - parser_next_token(parser); + return token; } @@ -64,175 +69,199 @@ static OnyxAstNode* parse_if_stmt(OnyxParser* parser) { return &error_node; } -static OnyxAstNode* parse_block(OnyxParser* parser) { - assert(parser->curr_token->type == TOKEN_TYPE_OPEN_BRACE); - - return &error_node; -} - static OnyxAstNode* parse_expression_statement(OnyxParser* parser) { - + } static OnyxAstNode* parse_return_statement(OnyxParser* parser) { - // Only should get here with a return as the current token - assert(parser->curr_token->type == TOKEN_TYPE_KEYWORD_RETURN); - + expect(parser, TOKEN_TYPE_KEYWORD_RETURN); + OnyxAstNode* expr = NULL; - - OnyxToken* return_token = parser->curr_token; + parser_next_token(parser); if (parser->curr_token->type != TOKEN_TYPE_SYM_SEMICOLON) { expr = parse_expression(parser); - + if (expr == &error_node) { return &error_node; } } } -static OnyxAstNode* parse_statement(OnyxParser* parser, b32 is_top_level) { +static OnyxAstNodeBlock* parse_block(OnyxParser* parser); + +static OnyxAstNode* parse_statement(OnyxParser* parser) { switch (parser->curr_token->type) { - case TOKEN_TYPE_KEYWORD_RETURN: + case TOKEN_TYPE_KEYWORD_RETURN: return parse_return_statement(parser); - - case TOKEN_TYPE_OPEN_BRACE: + + case TOKEN_TYPE_OPEN_BRACE: return (OnyxAstNode *) parse_block(parser); - - case TOKEN_TYPE_SYMBOL: - case TOKEN_TYPE_OPEN_PAREN: - case TOKEN_TYPE_SYM_PLUS: - case TOKEN_TYPE_SYM_MINUS: - case TOKEN_TYPE_SYM_BANG: - case TOKEN_TYPE_LITERAL_NUMERIC: - case TOKEN_TYPE_LITERAL_STRING: + + case TOKEN_TYPE_SYMBOL: + case TOKEN_TYPE_OPEN_PAREN: + case TOKEN_TYPE_SYM_PLUS: + case TOKEN_TYPE_SYM_MINUS: + case TOKEN_TYPE_SYM_BANG: + case TOKEN_TYPE_LITERAL_NUMERIC: + case TOKEN_TYPE_LITERAL_STRING: return parse_expression_statement(parser); - - case TOKEN_TYPE_KEYWORD_IF: + + case TOKEN_TYPE_KEYWORD_IF: return parse_if_stmt(parser); - - case TOKEN_TYPE_SYM_SEMICOLON: + + case TOKEN_TYPE_SYM_SEMICOLON: return NULL; - - default: + + default: printf("ERROR\n"); parser_next_token(parser); return NULL; } } +static OnyxAstNodeBlock* parse_block(OnyxParser* parser) { + // --- 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; + } + + expect(parser, TOKEN_TYPE_OPEN_BRACE); + + OnyxAstNodeBlock* block = (OnyxAstNodeBlock *) onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_BLOCK); + + OnyxAstNode** next = &block->body; + OnyxAstNode* stmt = NULL; + while (parser->curr_token->type != TOKEN_TYPE_CLOSE_BRACE) { + stmt = parse_statement(parser); + + if (stmt != NULL && stmt->kind != ONYX_AST_NODE_KIND_ERROR) { + *next = stmt; + next = &stmt->next; + } + + expect(parser, TOKEN_TYPE_SYM_SEMICOLON); + } + + return block; +} + static OnyxTypeInfo* parse_type(OnyxParser* parser) { OnyxTypeInfo* type_info = &builtin_types[ONYX_TYPE_INFO_KIND_UNKNOWN]; - + OnyxToken* symbol = expect(parser, TOKEN_TYPE_SYMBOL); if (symbol == NULL) return type_info; - + onyx_token_null_toggle(*symbol); - + if (!bh_hash_has(OnyxAstNode*, parser->identifiers, symbol->token)) { onyx_message_add(parser->msgs, ONYX_MESSAGE_TYPE_UNKNOWN_TYPE, symbol->pos, symbol->token); } else { OnyxAstNode* type_info_node = bh_hash_get(OnyxAstNode*, parser->identifiers, symbol->token); - + if (type_info_node->kind == ONYX_AST_NODE_KIND_TYPE) { type_info = type_info_node->type; } } - + onyx_token_null_toggle(*symbol); return type_info; } static OnyxAstNodeParam* parse_function_params(OnyxParser* parser) { expect(parser, TOKEN_TYPE_OPEN_PAREN); - + if (parser->curr_token->type == TOKEN_TYPE_CLOSE_PAREN) { parser_next_token(parser); return NULL; } - + OnyxAstNodeParam* first_param = NULL; - + OnyxAstNodeParam* curr_param = NULL; - OnyxAstNodeParam** walker = NULL; - + OnyxAstNodeParam* trailer = NULL; + OnyxToken* symbol; while (parser->curr_token->type != TOKEN_TYPE_CLOSE_PAREN) { if (parser->curr_token->type == TOKEN_TYPE_SYM_COMMA) parser_next_token(parser); - + symbol = expect(parser, TOKEN_TYPE_SYMBOL); + curr_param = (OnyxAstNodeParam *) onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_PARAM); curr_param->token = symbol; curr_param->type = parse_type(parser); - + + if (first_param == NULL) first_param = curr_param; + curr_param->next = NULL; - if (first_param == NULL) { - first_param = curr_param; - } else { - (*walker)->next = curr_param; - } - walker = &curr_param; + if (trailer) trailer->next = curr_param; + + trailer = curr_param; } - + parser_next_token(parser); // Skip the ) return first_param; } static OnyxAstNodeFuncDef* parse_function_definition(OnyxParser* parser) { expect(parser, TOKEN_TYPE_KEYWORD_PROC); - + OnyxAstNodeFuncDef* func_def = (OnyxAstNodeFuncDef *) onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_FUNCDEF); func_def->param_count = 0; - + OnyxAstNodeParam* params = parse_function_params(parser); func_def->params = params; - + for (OnyxAstNode* walker = (OnyxAstNode *) params; walker != NULL; walker = walker->next) func_def->param_count++; - + expect(parser, TOKEN_TYPE_RIGHT_ARROW); - + OnyxTypeInfo* return_type = parse_type(parser); func_def->return_type = return_type; - - func_def->body = NULL; + + func_def->body = parse_block(parser); return func_def; } static OnyxAstNode* parse_top_level_statement(OnyxParser* parser) { switch (parser->curr_token->type) { - case TOKEN_TYPE_KEYWORD_USE: + case TOKEN_TYPE_KEYWORD_USE: assert(0); break; - - case TOKEN_TYPE_KEYWORD_EXPORT: + + case TOKEN_TYPE_KEYWORD_EXPORT: assert(0); break; - - case TOKEN_TYPE_SYMBOL: { - OnyxToken* symbol = parser->curr_token; - parser_next_token(parser); - - expect(parser, TOKEN_TYPE_SYM_COLON); - expect(parser, TOKEN_TYPE_SYM_COLON); - - if (parser->curr_token->type == TOKEN_TYPE_KEYWORD_PROC) { - OnyxAstNodeFuncDef* func_def = parse_function_definition(parser); - func_def->token = symbol; - return (OnyxAstNode *) func_def; - - } else if (parser->curr_token->type == TOKEN_TYPE_KEYWORD_STRUCT) { - // Handle struct case - assert(0); - } else { - onyx_message_add(parser->msgs, - ONYX_MESSAGE_TYPE_UNEXPECTED_TOKEN, - parser->curr_token->pos, - onyx_get_token_type_name(*parser->curr_token)); - } - } break; + + case TOKEN_TYPE_SYMBOL: { + OnyxToken* symbol = parser->curr_token; + parser_next_token(parser); + + expect(parser, TOKEN_TYPE_SYM_COLON); + expect(parser, TOKEN_TYPE_SYM_COLON); + + if (parser->curr_token->type == TOKEN_TYPE_KEYWORD_PROC) { + OnyxAstNodeFuncDef* func_def = parse_function_definition(parser); + func_def->token = symbol; + return (OnyxAstNode *) func_def; + + } else if (parser->curr_token->type == TOKEN_TYPE_KEYWORD_STRUCT) { + // Handle struct case + assert(0); + } else { + onyx_message_add(parser->msgs, + ONYX_MESSAGE_TYPE_UNEXPECTED_TOKEN, + parser->curr_token->pos, + onyx_get_token_type_name(parser->curr_token->type)); + } + } break; } + parser_next_token(parser); return NULL; } @@ -246,15 +275,15 @@ static OnyxAstNode* parse_top_level_statement(OnyxParser* parser) { OnyxAstNode* onyx_ast_node_new(bh_allocator alloc, OnyxAstNodeKind kind) {\ OnyxAstNode* node = (OnyxAstNode *) bh_alloc(alloc, sizeof(OnyxAstNode)); node->kind = kind; - + return node; } OnyxParser onyx_parser_create(bh_allocator alloc, OnyxTokenizer *tokenizer, OnyxMessages* msgs) { OnyxParser parser; - + bh_hash_init(bh_heap_allocator(), parser.identifiers); - + OnyxTypeInfo* it = &builtin_types[0]; while (it->kind != 0xffffffff) { OnyxAstNode* tmp = onyx_ast_node_new(alloc, ONYX_AST_NODE_KIND_TYPE); @@ -262,30 +291,34 @@ OnyxParser onyx_parser_create(bh_allocator alloc, OnyxTokenizer *tokenizer, Onyx bh_hash_put(OnyxAstNode*, parser.identifiers, (char *)it->name, tmp); it++; } - + parser.allocator = alloc; parser.tokenizer = tokenizer; parser.curr_token = tokenizer->tokens; parser.prev_token = NULL; parser.msgs = msgs; - + return parser; } +void onyx_parser_free(OnyxParser* parser) { + bh_hash_free(parser->identifiers); +} + OnyxAstNode* onyx_parse(OnyxParser *parser) { OnyxAstNode* program = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_PROGRAM); - + OnyxAstNode** prev_stmt = &program->next; OnyxAstNode* curr_stmt = NULL; while (parser->curr_token->type != TOKEN_TYPE_END_STREAM) { curr_stmt = parse_top_level_statement(parser); - + // Building a linked list of statements down the "next" chain if (curr_stmt != NULL && curr_stmt != &error_node) { *prev_stmt = curr_stmt; prev_stmt = &curr_stmt->next; } } - + return program; } diff --git a/onyxparser.h b/onyxparser.h index 5b2731fd..54c2553c 100644 --- a/onyxparser.h +++ b/onyxparser.h @@ -104,8 +104,8 @@ struct OnyxAstNodeBlock { OnyxToken *token; OnyxTypeInfo *return_type; OnyxAstNode *next; + OnyxAstNode *body; OnyxAstNode *unused1; - OnyxAstNode *unused2; }; struct OnyxAstNodeParam { @@ -142,10 +142,13 @@ union OnyxAstNode { }; OnyxAstNodeBlock as_block; + OnyxAstNodeFuncDef as_funcdef; + OnyxAstNodeParam as_param; }; OnyxAstNode* onyx_ast_node_new(bh_allocator alloc, OnyxAstNodeKind kind); OnyxParser onyx_parser_create(bh_allocator alloc, OnyxTokenizer *tokenizer, OnyxMessages* msgs); +void onyx_parser_free(OnyxParser* parser); OnyxAstNode* onyx_parse(OnyxParser *parser); #endif // #ifndef ONYXPARSER_H \ No newline at end of file diff --git a/progs/minimal.onyx b/progs/minimal.onyx index 0d4bee4b..9985f5a7 100644 --- a/progs/minimal.onyx +++ b/progs/minimal.onyx @@ -1,3 +1,8 @@ -add :: proc(a i32, b i32) -> i32 { +/* This is a comment */ + +log :: proc (a i32, b i64) -> i32 ---; + +add :: proc (a i32, b i32) -> i32 { + /* More comments */ return a + b; -}; +}; \ No newline at end of file -- 2.25.1