From: Brendan Hansen Date: Tue, 30 Jun 2020 21:16:08 +0000 (-0500) Subject: Starting work on globals X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=f6fe630f805a1f7f99916b30290235bc19dc5863;p=onyx.git Starting work on globals --- diff --git a/.vimspector.json b/.vimspector.json index 1ecdcd93..b101bde4 100644 --- a/.vimspector.json +++ b/.vimspector.json @@ -6,7 +6,7 @@ "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}/onyx", - "args": ["progs/other.onyx", "progs/test.onyx"], + "args": ["-ast", "progs/other.onyx", "progs/test.onyx"], "stopAtEntry": true, "cwd": "${workspaceFolder}", "environment": [], diff --git a/include/onyxparser.h b/include/onyxparser.h index 312b2d54..6f256564 100644 --- a/include/onyxparser.h +++ b/include/onyxparser.h @@ -18,6 +18,7 @@ typedef struct OnyxAstNodeWhile OnyxAstNodeWhile; typedef struct OnyxAstNodeParam OnyxAstNodeParam; typedef struct OnyxAstNodeFuncDef OnyxAstNodeFuncDef; typedef struct OnyxAstNodeForeign OnyxAstNodeForeign; +typedef struct OnyxAstNodeGlobal OnyxAstNodeGlobal; typedef struct OnyxAstNodeCall OnyxAstNodeCall; typedef struct OnyxAstNodeFile OnyxAstNodeFile; @@ -43,6 +44,7 @@ typedef enum OnyxAstNodeKind { ONYX_AST_NODE_KIND_BLOCK, ONYX_AST_NODE_KIND_SCOPE, ONYX_AST_NODE_KIND_LOCAL, + ONYX_AST_NODE_KIND_GLOBAL, ONYX_AST_NODE_KIND_SYMBOL, ONYX_AST_NODE_KIND_UNARY_OP, @@ -150,6 +152,7 @@ struct OnyxAstNodeNumLit { u32 flags; OnyxToken *token; OnyxTypeInfo *type; + u64 data; OnyxAstNode *next; union { i32 i; i64 l; f32 f; f64 d; } value; }; @@ -239,6 +242,16 @@ struct OnyxAstNodeForeign { OnyxAstNode *import; }; +struct OnyxAstNodeGlobal { + OnyxAstNodeKind kind; + u32 flags; + OnyxToken *token; + OnyxTypeInfo *type; + u64 data; + OnyxAstNode* next; + OnyxAstNode* initial_value; +}; + struct OnyxAstNodeCall { OnyxAstNodeKind kind; u32 flags; @@ -286,6 +299,7 @@ union OnyxAstNode { OnyxAstNodeBinOp as_binop; OnyxAstNodeUnaryOp as_unaryop; OnyxAstNodeForeign as_foreign; + OnyxAstNodeGlobal as_global; OnyxAstNodeIf as_if; OnyxAstNodeWhile as_while; OnyxAstNodeFile as_file; diff --git a/onyx b/onyx index 53154945..b186232a 100755 Binary files a/onyx and b/onyx differ diff --git a/progs/test.onyx b/progs/test.onyx index 1f635f5b..a0a8af2f 100644 --- a/progs/test.onyx +++ b/progs/test.onyx @@ -22,6 +22,8 @@ something_else :: proc (n i32) -> i32 { // symbol := 5 Global mutable variable // symbol : i32 Global mutable i32 (defaults to 0 initial value) +global_value := 5 + 6; + // This is the entry point export main :: proc { i := 0; diff --git a/src/onyx.c b/src/onyx.c index 051d0562..ec1d9420 100644 --- a/src/onyx.c +++ b/src/onyx.c @@ -30,6 +30,8 @@ typedef struct OnyxCompileOptions { bh_allocator allocator; CompileAction action; + u32 print_ast : 1; + bh_arr(const char *) files; const char* target_file; } OnyxCompileOptions; @@ -57,6 +59,8 @@ static OnyxCompileOptions compile_opts_parse(bh_allocator alloc, int argc, char .allocator = alloc, .action = ONYX_COMPILE_ACTION_PRINT_HELP, + .print_ast = 0, + .files = NULL, .target_file = "out.wasm", }; @@ -72,6 +76,9 @@ static OnyxCompileOptions compile_opts_parse(bh_allocator alloc, int argc, char options.action = ONYX_COMPILE_ACTION_COMPILE; options.target_file = argv[++i]; } + else if (!strcmp(argv[i], "-ast")) { + options.print_ast = 1; + } else { options.action = ONYX_COMPILE_ACTION_COMPILE; bh_arr_push(options.files, argv[i]); @@ -136,6 +143,11 @@ i32 onyx_compile(OnyxCompileOptions* opts, CompilerState* compiler_state) { bh_table_each_start(bh_file_contents, compiler_state->loaded_files); OnyxAstNodeFile* file_node = parse_source_file(&value, compiler_state); + if (opts->print_ast) { + onyx_ast_print((OnyxAstNode *) file_node, 0); + bh_printf("\n"); + } + if (!root_file) { root_file = file_node; } @@ -155,6 +167,11 @@ i32 onyx_compile(OnyxCompileOptions* opts, CompilerState* compiler_state) { OnyxSemPassState sp_state = onyx_sempass_create(compiler_state->sp_alloc, compiler_state->ast_alloc, &compiler_state->msgs); onyx_sempass(&sp_state, root_file); + if (opts->print_ast) { + onyx_ast_print((OnyxAstNode *) root_file, 0); + bh_printf("\n"); + } + if (onyx_message_has_errors(&compiler_state->msgs)) { return ONYX_COMPILER_PROGRESS_FAILED_SEMPASS; } diff --git a/src/onyxparser.c b/src/onyxparser.c index d045613e..af39eb91 100644 --- a/src/onyxparser.c +++ b/src/onyxparser.c @@ -12,6 +12,7 @@ static const char* ast_node_names[] = { "BLOCK", "SCOPE", "LOCAL", + "GLOBAL", "SYMBOL", "UN_OP", @@ -19,7 +20,6 @@ static const char* ast_node_names[] = { "TYPE", "LITERAL", - "CAST", "PARAM", "ARGUMENT", "CALL", @@ -28,6 +28,8 @@ static const char* ast_node_names[] = { "IF", "WHILE", + "BREAK", + "CONTINUE", "ONYX_AST_NODE_KIND_COUNT", }; @@ -705,29 +707,50 @@ static OnyxAstNodeFuncDef* parse_function_definition(OnyxParser* parser) { return func_def; } -static OnyxAstNode* parse_top_level_symbol(OnyxParser* parser) { +static OnyxAstNode* parse_foreign(OnyxParser* parser) { + expect(parser, TOKEN_TYPE_KEYWORD_FOREIGN); + + OnyxAstNodeForeign* foreign = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_FOREIGN); + foreign->mod_token = expect(parser, TOKEN_TYPE_LITERAL_STRING); + foreign->name_token = expect(parser, TOKEN_TYPE_LITERAL_STRING); + if (parser->curr_token->type == TOKEN_TYPE_KEYWORD_PROC) { - OnyxAstNodeFuncDef* func_def = parse_function_definition(parser); - return (OnyxAstNode *) func_def; + foreign->import = (OnyxAstNode *) parse_function_definition(parser); + + } else { + OnyxTypeInfo* type = parse_type(parser); + + OnyxAstNodeGlobal* global = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_GLOBAL); + global->type = type; + global->flags |= ONYX_AST_FLAG_LVAL; + + foreign->import = (OnyxAstNode *) global; + } + + return (OnyxAstNode *) foreign; +} + +static OnyxAstNode* parse_top_level_constant_symbol(OnyxParser* parser) { + if (parser->curr_token->type == TOKEN_TYPE_KEYWORD_PROC) { + return (OnyxAstNode *) parse_function_definition(parser); } else if (parser->curr_token->type == TOKEN_TYPE_KEYWORD_STRUCT) { // Handle struct case assert(0); - } else if (parser->curr_token->type == TOKEN_TYPE_KEYWORD_FOREIGN) { - parser_next_token(parser); - OnyxAstNodeForeign* foreign = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_FOREIGN); - foreign->mod_token = expect(parser, TOKEN_TYPE_LITERAL_STRING); - foreign->name_token = expect(parser, TOKEN_TYPE_LITERAL_STRING); - foreign->import = parse_top_level_symbol(parser); + } else if (parser->curr_token->type == TOKEN_TYPE_KEYWORD_FOREIGN) { + return (OnyxAstNode *) parse_foreign(parser); - return (OnyxAstNode *) foreign; } else { - onyx_message_add(parser->msgs, - ONYX_MESSAGE_TYPE_UNEXPECTED_TOKEN, - parser->curr_token->pos, - onyx_get_token_type_name(parser->curr_token->type)); - return &error_node; + // Global constant with initial value + OnyxAstNodeGlobal* global = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_GLOBAL); + global->initial_value = parse_expression(parser); + global->type = &builtin_types[ONYX_TYPE_INFO_KIND_UNKNOWN]; + global->flags |= ONYX_AST_FLAG_CONST; + global->flags |= ONYX_AST_FLAG_LVAL; + global->flags |= ONYX_AST_FLAG_COMPTIME; + + return (OnyxAstNode *) global; } } @@ -759,21 +782,43 @@ static OnyxAstNode* parse_top_level_statement(OnyxParser* parser) { OnyxToken* symbol = parser->curr_token; parser_next_token(parser); - expect(parser, TOKEN_TYPE_SYM_COLON); expect(parser, TOKEN_TYPE_SYM_COLON); - OnyxAstNode* node = parse_top_level_symbol(parser); - if (node->kind == ONYX_AST_NODE_KIND_FUNCDEF) { - node->token = symbol; - } + if (parser->curr_token->type == TOKEN_TYPE_SYM_COLON) { + parser_next_token(parser); + + OnyxAstNode* node = parse_top_level_constant_symbol(parser); - if (node->kind == ONYX_AST_NODE_KIND_FOREIGN) { - OnyxAstNodeForeign* foreign = &node->as_foreign; + if (node->kind == ONYX_AST_NODE_KIND_FOREIGN) { + node->as_foreign.import->token = symbol; + + } else { + node->token = symbol; + } - foreign->import->token = symbol; + return node; + + } else if (parser->curr_token->type == TOKEN_TYPE_SYM_EQUALS) { + parser_next_token(parser); + + OnyxAstNodeGlobal* global = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_GLOBAL); + global->token = symbol; + global->flags |= ONYX_AST_FLAG_LVAL; + global->initial_value = parse_expression(parser); + global->type = &builtin_types[ONYX_TYPE_INFO_KIND_UNKNOWN]; + + return (OnyxAstNode *) global; + + } else { + onyx_token_null_toggle(*parser->curr_token); + onyx_message_add(parser->msgs, + ONYX_MESSAGE_TYPE_UNEXPECTED_TOKEN, + parser->curr_token->pos, + parser->curr_token->token); + onyx_token_null_toggle(*parser->curr_token); } - return node; + return &error_node; } default: break; diff --git a/src/onyxutils.c b/src/onyxutils.c index c98dd67f..cae6546a 100644 --- a/src/onyxutils.c +++ b/src/onyxutils.c @@ -18,8 +18,12 @@ void onyx_ast_print(OnyxAstNode* node, i32 indent) { switch (node->kind) { case ONYX_AST_NODE_KIND_PROGRAM: { + OnyxAstNodeFile* file_node = &node->as_file; + if (file_node->contents) + onyx_ast_print(file_node->contents, indent + 1); + if (node->next) - onyx_ast_print(node->next, indent + 1); + onyx_ast_print(node->next, indent); break; } @@ -97,6 +101,19 @@ void onyx_ast_print(OnyxAstNode* node, i32 indent) { break; } + case ONYX_AST_NODE_KIND_GLOBAL: { + OnyxAstNodeGlobal* global = &node->as_global; + bh_printf("%b %s", global->token->token, global->token->length, global->type->name); + if (global->initial_value) { + onyx_ast_print(global->initial_value, indent + 1); + } + + if (node->next) { + onyx_ast_print(node->next, indent); + } + break; + } + case ONYX_AST_NODE_KIND_SYMBOL: { bh_printf("%b", node->token->token, node->token->length); if (node->next) { @@ -176,6 +193,19 @@ void onyx_ast_print(OnyxAstNode* node, i32 indent) { break; } + case ONYX_AST_NODE_KIND_BIN_OP: { + OnyxAstNodeBinOp* binop = &node->as_binop; + bh_printf("%b", binop->token->token, binop->token->length); + + onyx_ast_print(node->left, indent + 1); + onyx_ast_print(node->right, indent + 1); + if (node->next) { + onyx_ast_print(node->next, indent); + } + + break; + } + default: { onyx_ast_print(node->left, indent + 1); onyx_ast_print(node->right, indent + 1);