Core: Add defer
This commit is contained in:
@@ -54,7 +54,9 @@ main :: (): int
|
|||||||
target_color := RED
|
target_color := RED
|
||||||
target_color.a = 255/2
|
target_color.a = 255/2
|
||||||
|
|
||||||
|
testing := 0
|
||||||
for !WindowShouldClose()
|
for !WindowShouldClose()
|
||||||
|
defer ;; testing += 1
|
||||||
WinX = GetScreenWidth()
|
WinX = GetScreenWidth()
|
||||||
WinY = GetScreenHeight()
|
WinY = GetScreenHeight()
|
||||||
MouseX = GetMouseX()
|
MouseX = GetMouseX()
|
||||||
|
|||||||
@@ -241,6 +241,7 @@ CORE_Static Ast_Scope *
|
|||||||
begin_stmt_scope(Allocator *scratch, Token *pos) {
|
begin_stmt_scope(Allocator *scratch, Token *pos) {
|
||||||
AST_NEW(Scope, SCOPE, pos, AST_STMT);
|
AST_NEW(Scope, SCOPE, pos, AST_STMT);
|
||||||
result->stmts = {scratch};
|
result->stmts = {scratch};
|
||||||
|
result->defers = {scratch};
|
||||||
result->file = pctx->currently_parsed_file;
|
result->file = pctx->currently_parsed_file;
|
||||||
result->module = pctx->currently_parsed_file->module;
|
result->module = pctx->currently_parsed_file->module;
|
||||||
result->scope_id = pctx->scope_ids++;
|
result->scope_id = pctx->scope_ids++;
|
||||||
@@ -253,6 +254,7 @@ begin_stmt_scope(Allocator *scratch, Token *pos) {
|
|||||||
CORE_Static void
|
CORE_Static void
|
||||||
finalize_stmt_scope(Ast_Scope *scope) {
|
finalize_stmt_scope(Ast_Scope *scope) {
|
||||||
scope->stmts = scope->stmts.tight_copy(pctx->perm);
|
scope->stmts = scope->stmts.tight_copy(pctx->perm);
|
||||||
|
scope->defers = scope->defers.tight_copy(pctx->perm);
|
||||||
pctx->currently_parsed_scope = scope->parent_scope;
|
pctx->currently_parsed_scope = scope->parent_scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -583,6 +585,11 @@ void next(Ast_Iter *iter) {
|
|||||||
For(node->vars) iter->stack.add(it);
|
For(node->vars) iter->stack.add(it);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case AST_DEFER: {
|
||||||
|
auto node = (Ast_Defer *)ast;
|
||||||
|
iter->stack.add(node->scope);
|
||||||
|
} break;
|
||||||
|
|
||||||
case AST_BREAK:
|
case AST_BREAK:
|
||||||
case AST_PASS:
|
case AST_PASS:
|
||||||
case AST_CONTINUE:
|
case AST_CONTINUE:
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ global S32 is_inside_struct;
|
|||||||
|
|
||||||
CORE_Static void gen_ast(Ast *ast);
|
CORE_Static void gen_ast(Ast *ast);
|
||||||
CORE_Static bool gen_expr(Ast_Expr *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
|
CORE_Static void
|
||||||
gen_indent() {
|
gen_indent() {
|
||||||
@@ -266,7 +267,25 @@ gen_value(Token *pos, Value a) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CORE_Static void
|
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("{");
|
gen("{");
|
||||||
global_indent++;
|
global_indent++;
|
||||||
For(scope->stmts) {
|
For(scope->stmts) {
|
||||||
@@ -274,6 +293,7 @@ gen_stmt_scope(Ast_Scope *scope, B32 switch_case_gen_break = 0) {
|
|||||||
genln("");
|
genln("");
|
||||||
gen_ast(it);
|
gen_ast(it);
|
||||||
}
|
}
|
||||||
|
gen_defers_for_scope(scope);
|
||||||
if (switch_case_gen_break == 1) genln("break;");
|
if (switch_case_gen_break == 1) genln("break;");
|
||||||
global_indent--;
|
global_indent--;
|
||||||
gen_last_line();
|
gen_last_line();
|
||||||
@@ -581,6 +601,7 @@ gen_ast(Ast *ast) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CASE(RETURN, Return) {
|
CASE(RETURN, Return) {
|
||||||
|
gen_defers_for_scope_and_parents(node->parent_scope);
|
||||||
gen("return ");
|
gen("return ");
|
||||||
if (node->expr) gen_expr(node->expr);
|
if (node->expr) gen_expr(node->expr);
|
||||||
gen(";");
|
gen(";");
|
||||||
@@ -634,13 +655,19 @@ gen_ast(Ast *ast) {
|
|||||||
} break;
|
} break;
|
||||||
|
|
||||||
case AST_CONTINUE: {
|
case AST_CONTINUE: {
|
||||||
|
gen_defers_for_scope(ast->parent_scope);
|
||||||
gen("continue;");
|
gen("continue;");
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case AST_BREAK: {
|
case AST_BREAK: {
|
||||||
|
gen_defers_for_scope(ast->parent_scope);
|
||||||
gen("break;");
|
gen("break;");
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case AST_DEFER: {
|
||||||
|
gen("// defer");
|
||||||
|
} break;
|
||||||
|
|
||||||
case AST_COMPILER_BREAKPOINT_STMT: {
|
case AST_COMPILER_BREAKPOINT_STMT: {
|
||||||
__debugbreak();
|
__debugbreak();
|
||||||
} break;
|
} break;
|
||||||
@@ -686,6 +713,7 @@ gen_ast(Ast *ast) {
|
|||||||
}
|
}
|
||||||
global_indent--;
|
global_indent--;
|
||||||
gen_last_line();
|
gen_last_line();
|
||||||
|
gen_defers_for_scope(ast->parent_scope);
|
||||||
genln("}");
|
genln("}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,51 +11,6 @@ struct Ast_Lambda;
|
|||||||
struct Ast_Type;
|
struct Ast_Type;
|
||||||
struct Ast_Expr;
|
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 <class T>
|
|
||||||
struct Array {
|
|
||||||
void *allocator;
|
|
||||||
T *data;
|
|
||||||
int64_t cap;
|
|
||||||
int64_t len;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
struct List_Node {
|
|
||||||
List_Node<T> *next;
|
|
||||||
List_Node<T> *prev;
|
|
||||||
int cap;
|
|
||||||
int len;
|
|
||||||
T data[];
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
struct List {
|
|
||||||
int block_size = 0;
|
|
||||||
int allocation_multiplier = 0;
|
|
||||||
List_Node<T> *first = 0;
|
|
||||||
List_Node<T> *last = 0;
|
|
||||||
List_Node<T> *first_free = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
enum Token_Kind {
|
enum Token_Kind {
|
||||||
TK_End,
|
TK_End,
|
||||||
/*#
|
/*#
|
||||||
@@ -582,6 +537,7 @@ struct Ast_Scope : Ast {
|
|||||||
List<Ast_Scope *> implicit_imports;
|
List<Ast_Scope *> implicit_imports;
|
||||||
List<Ast_Decl *> decls;
|
List<Ast_Decl *> decls;
|
||||||
Array<Ast *> stmts;
|
Array<Ast *> stmts;
|
||||||
|
Array<Ast_Defer *> defers;
|
||||||
|
|
||||||
uint32_t scope_id;
|
uint32_t scope_id;
|
||||||
Ast_Scope *file; // Self referential for file and module
|
Ast_Scope *file; // Self referential for file and module
|
||||||
|
|||||||
@@ -271,7 +271,7 @@ parse_optional_type() {
|
|||||||
return result;
|
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 *
|
CORE_Static Ast *
|
||||||
parse_stmt() {
|
parse_stmt() {
|
||||||
@@ -479,7 +479,7 @@ parse_stmt() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CORE_Static Ast_Scope *
|
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);
|
Scoped_Arena scratch(pctx->scratch);
|
||||||
Ast_Scope *scope = scope_defined_outside;
|
Ast_Scope *scope = scope_defined_outside;
|
||||||
if (!scope_defined_outside) scope = begin_stmt_scope(scratch.arena, token_get());
|
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 {
|
do {
|
||||||
Ast *stmt = parse_stmt();
|
Ast *stmt = parse_stmt();
|
||||||
scope->stmts.add(stmt);
|
scope->stmts.add(stmt);
|
||||||
|
if (stmt->kind == AST_DEFER) scope->defers.add((Ast_Defer *)stmt);
|
||||||
} while (token_match(SAME_SCOPE));
|
} while (token_match(SAME_SCOPE));
|
||||||
token_expect(CLOSE_SCOPE);
|
token_expect(CLOSE_SCOPE);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -322,6 +322,12 @@ Ast *ast_copy(Ast *ast, Ast_Scope *parent_scope, Array<Poly_Replacement> *repl)
|
|||||||
result = dst;
|
result = dst;
|
||||||
} break;
|
} 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_BREAK:
|
||||||
case AST_PASS:
|
case AST_PASS:
|
||||||
case AST_GOTO:
|
case AST_GOTO:
|
||||||
|
|||||||
@@ -243,6 +243,12 @@ void core__stringify(Ast *ast) {
|
|||||||
core__stringify(n->expr);
|
core__stringify(n->expr);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case AST_DEFER: {
|
||||||
|
auto n = (Ast_Defer *)ast;
|
||||||
|
genln("defer");
|
||||||
|
core__stringify(n->scope);
|
||||||
|
} break;
|
||||||
|
|
||||||
case AST_PASS: {
|
case AST_PASS: {
|
||||||
genln("pass");
|
genln("pass");
|
||||||
} break;
|
} break;
|
||||||
|
|||||||
@@ -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");
|
if (decl->enable_goto == false) compiler_error(decl->pos, "Label doesn't have goto enabled, add ':' at the end");
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case AST_DEFER: {
|
||||||
|
auto n = (Ast_Defer *)ast;
|
||||||
|
For(n->scope->stmts) {
|
||||||
|
resolve_stmt(it, ret);
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
case AST_CONTINUE:
|
case AST_CONTINUE:
|
||||||
case AST_BREAK:
|
case AST_BREAK:
|
||||||
case AST_PASS: {
|
case AST_PASS: {
|
||||||
|
|||||||
Reference in New Issue
Block a user