From 654d6f17e43b7080023111510de454fcf7e5cac9 Mon Sep 17 00:00:00 2001 From: Krzosa Karol Date: Sat, 22 Apr 2023 13:14:08 +0200 Subject: [PATCH] Core: Add goto --- build/rtsgame/main.core | 3 --- core_ast.cpp | 10 +++++++++- core_codegen_c_language.cpp | 5 +++++ core_compiler.cpp | 3 ++- core_compiler.h | 1 + core_compiler_interface.hpp | 5 +++++ core_parsing.cpp | 6 ++++++ core_polymorph.cpp | 2 ++ core_typechecking.cpp | 15 +++++++++++---- meta.py | 1 + 10 files changed, 42 insertions(+), 9 deletions(-) diff --git a/build/rtsgame/main.core b/build/rtsgame/main.core index 4f96994..d48b50b 100644 --- a/build/rtsgame/main.core +++ b/build/rtsgame/main.core @@ -76,9 +76,6 @@ main :: (): int target_color := RED target_color.a = 255/2 - :some_label: - target_color = RED - for !WindowShouldClose() WinX = GetScreenWidth() WinY = GetScreenHeight() diff --git a/core_ast.cpp b/core_ast.cpp index 020472e..5bff871 100644 --- a/core_ast.cpp +++ b/core_ast.cpp @@ -177,6 +177,13 @@ ast_return(Token *pos, Ast_Expr *expr) { return result; } +CORE_Static Ast_Goto * +ast_goto(Token *pos, Intern_String label) { + Ast_Goto *result = ast_new(Ast_Goto, AST_GOTO, pos, AST_STMT); + result->label = label; + return result; +} + CORE_Static Ast_Label * ast_label(Token *pos, Intern_String name, Ast_Scope *scope, bool enable_goto) { Ast_Label *result = ast_new(Ast_Label, AST_LABEL, pos, AST_STMT | AST_DECL); @@ -572,10 +579,11 @@ void next(Ast_Iter *iter) { case AST_BREAK: case AST_PASS: case AST_CONTINUE: + case AST_GOTO: case AST_COMPILER_BREAKPOINT_STMT: { - Ast *node = (Ast *)ast; } break; + case AST_LABEL: case AST_NAMESPACE: case AST_STRUCT: case AST_UNION: diff --git a/core_codegen_c_language.cpp b/core_codegen_c_language.cpp index ce23236..e8a9126 100644 --- a/core_codegen_c_language.cpp +++ b/core_codegen_c_language.cpp @@ -621,6 +621,11 @@ gen_ast(Ast *ast) { BREAK(); } + case AST_GOTO: { + auto n = (Ast_Goto *)ast; + gen("goto %Q;", n->label); + } break; + case AST_LABEL: { auto n = (Ast_Label *)ast; if (n->enable_goto == false) gen("/* %Q */", n->name); diff --git a/core_compiler.cpp b/core_compiler.cpp index a336102..4366d84 100644 --- a/core_compiler.cpp +++ b/core_compiler.cpp @@ -66,8 +66,9 @@ for i in meta.token_simple_expr: pctx->keyword_else = pctx->intern("else"_s); pctx->keyword_for = pctx->intern("for"_s); pctx->keyword_enum = pctx->intern("enum"_s); + pctx->keyword_goto = pctx->intern("goto"_s); pctx->interns.first_keyword = pctx->keyword_struct.str; - pctx->interns.last_keyword = pctx->keyword_enum.str; + pctx->interns.last_keyword = pctx->keyword_goto.str; pctx->intern_typeof = pctx->intern("typeof"_s); pctx->intern_sizeof = pctx->intern("sizeof"_s); pctx->intern_len = pctx->intern("Len"_s); diff --git a/core_compiler.h b/core_compiler.h index 8cc6d67..0244bc2 100644 --- a/core_compiler.h +++ b/core_compiler.h @@ -107,6 +107,7 @@ for i in meta.interns: print(f'Intern_String intern_{i.lower()};') Intern_String keyword_else; Intern_String keyword_for; Intern_String keyword_enum; + Intern_String keyword_goto; Intern_String intern_typeof; Intern_String intern_sizeof; Intern_String intern_len; diff --git a/core_compiler_interface.hpp b/core_compiler_interface.hpp index bc7d8ec..361b701 100644 --- a/core_compiler_interface.hpp +++ b/core_compiler_interface.hpp @@ -335,6 +335,7 @@ enum Ast_Kind : uint32_t { AST_VARGS_LAMBDA_PARAM, AST_LABEL, + AST_GOTO, AST_SWITCH, AST_SWITCH_CASE, AST_VAR_UNPACK, @@ -530,6 +531,10 @@ struct Ast_If : Ast { #define Ast_Pass Ast #define Ast_Break Ast +struct Ast_Goto : Ast { + Intern_String label; +}; + struct Ast_For : Ast { Ast_Expr *init; Ast_Expr *cond; diff --git a/core_parsing.cpp b/core_parsing.cpp index 8d4a128..1f48036 100644 --- a/core_parsing.cpp +++ b/core_parsing.cpp @@ -423,6 +423,12 @@ parse_stmt_scope(Ast_Scope *scope_defined_outside = 0) { scope->stmts.add(result_if); } + else if (token_match_keyword(pctx->keyword_goto)) { + Token *ident = token_expect(TK_Identifier); + Ast_Goto *result = ast_goto(token, ident->intern_val); + scope->stmts.add(result); + } + // Label else if (token_match(TK_Colon)) { Token *ident = token_expect(TK_Identifier); diff --git a/core_polymorph.cpp b/core_polymorph.cpp index 44dc370..10e1914 100644 --- a/core_polymorph.cpp +++ b/core_polymorph.cpp @@ -324,6 +324,7 @@ Ast *ast_copy(Ast *ast, Ast_Scope *parent_scope, Array *repl) case AST_BREAK: case AST_PASS: + case AST_GOTO: case AST_CONTINUE: case AST_COMPILER_BREAKPOINT_STMT: { Ast *src = (Ast *)ast; @@ -331,6 +332,7 @@ Ast *ast_copy(Ast *ast, Ast_Scope *parent_scope, Array *repl) result = dst; } break; + case AST_LABEL: case AST_NAMESPACE: case AST_STRUCT: case AST_UNION: diff --git a/core_typechecking.cpp b/core_typechecking.cpp index 9519242..cbd09ab 100644 --- a/core_typechecking.cpp +++ b/core_typechecking.cpp @@ -766,12 +766,19 @@ CORE_Static void resolve_stmt(Ast *ast, Ast_Type *ret) { } } break; + case AST_GOTO: { + auto n = (Ast_Goto *)ast; + auto decl = (Ast_Label *)search_for_single_decl(n->parent_scope, n->label); + if (!decl) compiler_error(n->pos, "Goto label is unidentified"); + if (decl->kind != AST_LABEL) compiler_error(n->pos, "Trying to goto identifier that is not a label"); + if (decl->enable_goto == false) compiler_error(decl->pos, "Label doesn't have goto enabled, add ':' at the end"); + } break; + case AST_CONTINUE: case AST_BREAK: - CASE(PASS, Pass) { - unused(node); - BREAK(); - } + case AST_PASS: { + + } break; CASE(RUNTIME_ASSERT, Builtin) { resolve_and_require_bool("Assert condition is not boolean", node->expr, AST_CAN_BE_NULL); diff --git a/meta.py b/meta.py index 9ee318f..0e105e2 100644 --- a/meta.py +++ b/meta.py @@ -115,6 +115,7 @@ keywords = [ "else", "for", "enum", + "goto", ] interns = [