diff --git a/build/rtsgame/main.core b/build/rtsgame/main.core index d5b138c..f5a30fc 100644 --- a/build/rtsgame/main.core +++ b/build/rtsgame/main.core @@ -54,7 +54,9 @@ main :: (): int target_color := RED target_color.a = 255/2 + testing := 0 for !WindowShouldClose() + defer ;; testing += 1 WinX = GetScreenWidth() WinY = GetScreenHeight() MouseX = GetMouseX() diff --git a/core_ast.cpp b/core_ast.cpp index 1af02d5..94354a8 100644 --- a/core_ast.cpp +++ b/core_ast.cpp @@ -241,6 +241,7 @@ CORE_Static Ast_Scope * begin_stmt_scope(Allocator *scratch, Token *pos) { AST_NEW(Scope, SCOPE, pos, AST_STMT); result->stmts = {scratch}; + result->defers = {scratch}; result->file = pctx->currently_parsed_file; result->module = pctx->currently_parsed_file->module; result->scope_id = pctx->scope_ids++; @@ -253,6 +254,7 @@ begin_stmt_scope(Allocator *scratch, Token *pos) { CORE_Static void finalize_stmt_scope(Ast_Scope *scope) { scope->stmts = scope->stmts.tight_copy(pctx->perm); + scope->defers = scope->defers.tight_copy(pctx->perm); pctx->currently_parsed_scope = scope->parent_scope; } @@ -583,6 +585,11 @@ void next(Ast_Iter *iter) { For(node->vars) iter->stack.add(it); } break; + case AST_DEFER: { + auto node = (Ast_Defer *)ast; + iter->stack.add(node->scope); + } break; + case AST_BREAK: case AST_PASS: case AST_CONTINUE: diff --git a/core_codegen_c_language.cpp b/core_codegen_c_language.cpp index e8a9126..e7a67fe 100644 --- a/core_codegen_c_language.cpp +++ b/core_codegen_c_language.cpp @@ -17,6 +17,7 @@ global S32 is_inside_struct; CORE_Static void gen_ast(Ast *ast); CORE_Static bool gen_expr(Ast_Expr *ast); +CORE_Static void gen_stmt_scope(Ast_Scope *scope, B32 switch_case_gen_break = 0); CORE_Static void gen_indent() { @@ -266,7 +267,25 @@ gen_value(Token *pos, Value a) { } CORE_Static void -gen_stmt_scope(Ast_Scope *scope, B32 switch_case_gen_break = 0) { +gen_defers_for_scope(Ast_Scope *scope) { + int save_line = last_line; + For(scope->defers.reverse()) { + gen("/* defer */"); + gen_stmt_scope(it->scope); + } + last_line = save_line; +} + +CORE_Static void +gen_defers_for_scope_and_parents(Ast_Scope *scope) { + for (; scope;) { + gen_defers_for_scope(scope); + scope = scope->parent_scope; + } +} + +CORE_Static void +gen_stmt_scope(Ast_Scope *scope, B32 switch_case_gen_break) { gen("{"); global_indent++; For(scope->stmts) { @@ -274,6 +293,7 @@ gen_stmt_scope(Ast_Scope *scope, B32 switch_case_gen_break = 0) { genln(""); gen_ast(it); } + gen_defers_for_scope(scope); if (switch_case_gen_break == 1) genln("break;"); global_indent--; gen_last_line(); @@ -581,6 +601,7 @@ gen_ast(Ast *ast) { } CASE(RETURN, Return) { + gen_defers_for_scope_and_parents(node->parent_scope); gen("return "); if (node->expr) gen_expr(node->expr); gen(";"); @@ -634,13 +655,19 @@ gen_ast(Ast *ast) { } break; case AST_CONTINUE: { + gen_defers_for_scope(ast->parent_scope); gen("continue;"); } break; case AST_BREAK: { + gen_defers_for_scope(ast->parent_scope); gen("break;"); } break; + case AST_DEFER: { + gen("// defer"); + } break; + case AST_COMPILER_BREAKPOINT_STMT: { __debugbreak(); } break; @@ -686,6 +713,7 @@ gen_ast(Ast *ast) { } global_indent--; gen_last_line(); + gen_defers_for_scope(ast->parent_scope); genln("}"); } diff --git a/core_compiler_interface.hpp b/core_compiler_interface.hpp index 7eec953..1c4ccc4 100644 --- a/core_compiler_interface.hpp +++ b/core_compiler_interface.hpp @@ -11,51 +11,6 @@ struct Ast_Lambda; struct Ast_Type; struct Ast_Expr; -#ifndef CORE_BASE - #define CORE_BASE - -struct Allocator { - typedef void *Allocate(Allocator *, size_t); - typedef void Deallocate(Allocator *, void *p); - - Allocate *allocate; - Deallocate *deallocate; -}; - -struct String { - uint8_t *str; - int64_t len; -}; -typedef String Intern_String; - -template -struct Array { - void *allocator; - T *data; - int64_t cap; - int64_t len; -}; - -template -struct List_Node { - List_Node *next; - List_Node *prev; - int cap; - int len; - T data[]; -}; - -template -struct List { - int block_size = 0; - int allocation_multiplier = 0; - List_Node *first = 0; - List_Node *last = 0; - List_Node *first_free = 0; -}; - -#endif - enum Token_Kind { TK_End, /*# @@ -582,6 +537,7 @@ struct Ast_Scope : Ast { List implicit_imports; List decls; Array stmts; + Array defers; uint32_t scope_id; Ast_Scope *file; // Self referential for file and module diff --git a/core_parsing.cpp b/core_parsing.cpp index a0aa4c2..e8682cc 100644 --- a/core_parsing.cpp +++ b/core_parsing.cpp @@ -271,7 +271,7 @@ parse_optional_type() { return result; } -CORE_Static Ast_Scope *parse_stmt_scope(Ast_Scope *scope_defined_outside = 0, bool empty_scope_is_error = true); +CORE_Static Ast_Scope *parse_stmt_scope(Ast_Scope *scope_defined_outside = 0); CORE_Static Ast * parse_stmt() { @@ -479,7 +479,7 @@ parse_stmt() { } CORE_Static Ast_Scope * -parse_stmt_scope(Ast_Scope *scope_defined_outside, bool empty_scope_is_error) { +parse_stmt_scope(Ast_Scope *scope_defined_outside) { Scoped_Arena scratch(pctx->scratch); Ast_Scope *scope = scope_defined_outside; if (!scope_defined_outside) scope = begin_stmt_scope(scratch.arena, token_get()); @@ -488,6 +488,7 @@ parse_stmt_scope(Ast_Scope *scope_defined_outside, bool empty_scope_is_error) { do { Ast *stmt = parse_stmt(); scope->stmts.add(stmt); + if (stmt->kind == AST_DEFER) scope->defers.add((Ast_Defer *)stmt); } while (token_match(SAME_SCOPE)); token_expect(CLOSE_SCOPE); } diff --git a/core_polymorph.cpp b/core_polymorph.cpp index b514d1f..5c60360 100644 --- a/core_polymorph.cpp +++ b/core_polymorph.cpp @@ -322,6 +322,12 @@ Ast *ast_copy(Ast *ast, Ast_Scope *parent_scope, Array *repl) result = dst; } break; + case AST_DEFER: { + Ast_Defer *src = (Ast_Defer *)ast; + Ast_Defer *dst = ast_create_copy(parent_scope, Ast_Defer, ast); + dst->scope = (Ast_Scope *)ast_copy(src->scope, parent_scope, repl); + } break; + case AST_BREAK: case AST_PASS: case AST_GOTO: diff --git a/core_printer.cpp b/core_printer.cpp index 4898dab..f1d04ff 100644 --- a/core_printer.cpp +++ b/core_printer.cpp @@ -243,6 +243,12 @@ void core__stringify(Ast *ast) { core__stringify(n->expr); } break; + case AST_DEFER: { + auto n = (Ast_Defer *)ast; + genln("defer"); + core__stringify(n->scope); + } break; + case AST_PASS: { genln("pass"); } break; diff --git a/core_typechecking.cpp b/core_typechecking.cpp index e67cd3b..a954398 100644 --- a/core_typechecking.cpp +++ b/core_typechecking.cpp @@ -774,6 +774,13 @@ CORE_Static void resolve_stmt(Ast *ast, Ast_Type *ret) { if (decl->enable_goto == false) compiler_error(decl->pos, "Label doesn't have goto enabled, add ':' at the end"); } break; + case AST_DEFER: { + auto n = (Ast_Defer *)ast; + For(n->scope->stmts) { + resolve_stmt(it, ret); + } + } break; + case AST_CONTINUE: case AST_BREAK: case AST_PASS: {