Core: Factor + start defer
This commit is contained in:
@@ -177,6 +177,13 @@ ast_return(Token *pos, Ast_Expr *expr) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CORE_Static Ast_Defer *
|
||||||
|
ast_defer(Token *pos, Ast_Scope *scope) {
|
||||||
|
Ast_Defer *result = ast_new(Ast_Defer, AST_DEFER, pos, AST_STMT);
|
||||||
|
result->scope = scope;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
CORE_Static Ast_Goto *
|
CORE_Static Ast_Goto *
|
||||||
ast_goto(Token *pos, Intern_String label) {
|
ast_goto(Token *pos, Intern_String label) {
|
||||||
Ast_Goto *result = ast_new(Ast_Goto, AST_GOTO, pos, AST_STMT);
|
Ast_Goto *result = ast_new(Ast_Goto, AST_GOTO, pos, AST_STMT);
|
||||||
|
|||||||
@@ -67,8 +67,9 @@ for i in meta.token_simple_expr:
|
|||||||
pctx->keyword_for = pctx->intern("for"_s);
|
pctx->keyword_for = pctx->intern("for"_s);
|
||||||
pctx->keyword_enum = pctx->intern("enum"_s);
|
pctx->keyword_enum = pctx->intern("enum"_s);
|
||||||
pctx->keyword_goto = pctx->intern("goto"_s);
|
pctx->keyword_goto = pctx->intern("goto"_s);
|
||||||
|
pctx->keyword_defer = pctx->intern("defer"_s);
|
||||||
pctx->interns.first_keyword = pctx->keyword_struct.str;
|
pctx->interns.first_keyword = pctx->keyword_struct.str;
|
||||||
pctx->interns.last_keyword = pctx->keyword_goto.str;
|
pctx->interns.last_keyword = pctx->keyword_defer.str;
|
||||||
pctx->intern_typeof = pctx->intern("typeof"_s);
|
pctx->intern_typeof = pctx->intern("typeof"_s);
|
||||||
pctx->intern_sizeof = pctx->intern("sizeof"_s);
|
pctx->intern_sizeof = pctx->intern("sizeof"_s);
|
||||||
pctx->intern_len = pctx->intern("Len"_s);
|
pctx->intern_len = pctx->intern("Len"_s);
|
||||||
|
|||||||
@@ -108,6 +108,7 @@ for i in meta.interns: print(f'Intern_String intern_{i.lower()};')
|
|||||||
Intern_String keyword_for;
|
Intern_String keyword_for;
|
||||||
Intern_String keyword_enum;
|
Intern_String keyword_enum;
|
||||||
Intern_String keyword_goto;
|
Intern_String keyword_goto;
|
||||||
|
Intern_String keyword_defer;
|
||||||
Intern_String intern_typeof;
|
Intern_String intern_typeof;
|
||||||
Intern_String intern_sizeof;
|
Intern_String intern_sizeof;
|
||||||
Intern_String intern_len;
|
Intern_String intern_len;
|
||||||
|
|||||||
@@ -334,6 +334,7 @@ enum Ast_Kind : uint32_t {
|
|||||||
AST_TYPE_OF,
|
AST_TYPE_OF,
|
||||||
AST_VARGS_LAMBDA_PARAM,
|
AST_VARGS_LAMBDA_PARAM,
|
||||||
|
|
||||||
|
AST_DEFER,
|
||||||
AST_LABEL,
|
AST_LABEL,
|
||||||
AST_GOTO,
|
AST_GOTO,
|
||||||
AST_SWITCH,
|
AST_SWITCH,
|
||||||
@@ -535,6 +536,10 @@ struct Ast_Goto : Ast {
|
|||||||
Intern_String label;
|
Intern_String label;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Ast_Defer : Ast {
|
||||||
|
Ast_Scope *scope;
|
||||||
|
};
|
||||||
|
|
||||||
struct Ast_For : Ast {
|
struct Ast_For : Ast {
|
||||||
Ast_Expr *init;
|
Ast_Expr *init;
|
||||||
Ast_Expr *cond;
|
Ast_Expr *cond;
|
||||||
|
|||||||
@@ -271,38 +271,33 @@ parse_optional_type() {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
CORE_Static Ast_Scope *
|
CORE_Static Ast_Scope *parse_stmt_scope(Ast_Scope *scope_defined_outside = 0, bool empty_scope_is_error = true);
|
||||||
parse_stmt_scope(Ast_Scope *scope_defined_outside = 0) {
|
|
||||||
Ast_Scope *scope = scope_defined_outside;
|
|
||||||
|
|
||||||
if (token_expect(OPEN_SCOPE)) { // @todo: Fix error message here, it doesn't show proper token context
|
CORE_Static Ast *
|
||||||
Token *token_block = token_get();
|
parse_stmt() {
|
||||||
|
|
||||||
Scoped_Arena scratch(pctx->scratch);
|
|
||||||
if (!scope_defined_outside) scope = begin_stmt_scope(scratch.arena, token_block);
|
|
||||||
do {
|
|
||||||
Token *token = token_get();
|
Token *token = token_get();
|
||||||
|
Scoped_Arena scratch(pctx->scratch);
|
||||||
|
|
||||||
if (token_match_keyword(pctx->keyword_return)) {
|
if (token_match_keyword(pctx->keyword_return)) {
|
||||||
Ast_Expr *expr = 0;
|
Ast_Expr *expr = 0;
|
||||||
if (!token_is_scope()) expr = parse_expr();
|
if (!token_is_scope()) expr = parse_expr();
|
||||||
scope->stmts.add(ast_return(token, expr));
|
return ast_return(token, expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (token_match_keyword(pctx->keyword_continue)) {
|
else if (token_match_keyword(pctx->keyword_continue)) {
|
||||||
scope->stmts.add(ast_continue(token));
|
return ast_continue(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (token_match_keyword(pctx->intern_compiler_breakpoint)) {
|
else if (token_match_keyword(pctx->intern_compiler_breakpoint)) {
|
||||||
scope->stmts.add(ast_compiler_breakpoint(token));
|
return ast_compiler_breakpoint(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (token_match_keyword(pctx->keyword_break)) {
|
else if (token_match_keyword(pctx->keyword_break)) {
|
||||||
scope->stmts.add(ast_break(token));
|
return ast_break(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (token_match_keyword(pctx->keyword_pass)) {
|
else if (token_match_keyword(pctx->keyword_pass)) {
|
||||||
scope->stmts.add(ast_pass(token));
|
return ast_pass(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (token_match_keyword(pctx->keyword_switch)) {
|
else if (token_match_keyword(pctx->keyword_switch)) {
|
||||||
@@ -333,7 +328,7 @@ parse_stmt_scope(Ast_Scope *scope_defined_outside = 0) {
|
|||||||
token_expect(CLOSE_SCOPE);
|
token_expect(CLOSE_SCOPE);
|
||||||
result->cases = result->cases.tight_copy(pctx->perm);
|
result->cases = result->cases.tight_copy(pctx->perm);
|
||||||
|
|
||||||
scope->stmts.add(result);
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (token_match_keyword(pctx->keyword_assert)) {
|
else if (token_match_keyword(pctx->keyword_assert)) {
|
||||||
@@ -345,7 +340,7 @@ parse_stmt_scope(Ast_Scope *scope_defined_outside = 0) {
|
|||||||
message = t->intern_val;
|
message = t->intern_val;
|
||||||
}
|
}
|
||||||
token_expect(TK_CloseParen);
|
token_expect(TK_CloseParen);
|
||||||
scope->stmts.add(ast_runtime_assert(token, expr, message));
|
return ast_runtime_assert(token, expr, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (token_match_pound(pctx->keyword_assert)) {
|
else if (token_match_pound(pctx->keyword_assert)) {
|
||||||
@@ -357,7 +352,7 @@ parse_stmt_scope(Ast_Scope *scope_defined_outside = 0) {
|
|||||||
message = t->intern_val;
|
message = t->intern_val;
|
||||||
}
|
}
|
||||||
token_expect(TK_CloseParen);
|
token_expect(TK_CloseParen);
|
||||||
scope->stmts.add(ast_constant_assert(token, expr, message));
|
return ast_constant_assert(token, expr, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (token_match_keyword(pctx->keyword_for)) {
|
else if (token_match_keyword(pctx->keyword_for)) {
|
||||||
@@ -383,7 +378,7 @@ parse_stmt_scope(Ast_Scope *scope_defined_outside = 0) {
|
|||||||
|
|
||||||
parse_stmt_scope(for_scope);
|
parse_stmt_scope(for_scope);
|
||||||
finalize_stmt_scope(for_scope);
|
finalize_stmt_scope(for_scope);
|
||||||
scope->stmts.add(ast_for(token, init, cond, iter, for_scope));
|
return ast_for(token, init, cond, iter, for_scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (token_match_keyword(pctx->keyword_if)) {
|
else if (token_match_keyword(pctx->keyword_if)) {
|
||||||
@@ -419,14 +414,17 @@ parse_stmt_scope(Ast_Scope *scope_defined_outside = 0) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ast_If *result_if = ast_if(token, if_nodes);
|
return ast_if(token, if_nodes);
|
||||||
scope->stmts.add(result_if);
|
}
|
||||||
|
|
||||||
|
else if (token_match_keyword(pctx->keyword_defer)) {
|
||||||
|
Ast_Scope *s = parse_stmt_scope();
|
||||||
|
return ast_defer(token, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (token_match_keyword(pctx->keyword_goto)) {
|
else if (token_match_keyword(pctx->keyword_goto)) {
|
||||||
Token *ident = token_expect(TK_Identifier);
|
Token *ident = token_expect(TK_Identifier);
|
||||||
Ast_Goto *result = ast_goto(token, ident->intern_val);
|
return ast_goto(token, ident->intern_val);
|
||||||
scope->stmts.add(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Label
|
// Label
|
||||||
@@ -441,7 +439,7 @@ parse_stmt_scope(Ast_Scope *scope_defined_outside = 0) {
|
|||||||
|
|
||||||
Ast_Label *result = ast_label(token, ident->intern_val, s, enable_goto);
|
Ast_Label *result = ast_label(token, ident->intern_val, s, enable_goto);
|
||||||
if (breakpoint) set_flag(result->flags, AST_COMPILER_BREAKPOINT);
|
if (breakpoint) set_flag(result->flags, AST_COMPILER_BREAKPOINT);
|
||||||
scope->stmts.add(result);
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Var unpack
|
// Var unpack
|
||||||
@@ -456,7 +454,7 @@ parse_stmt_scope(Ast_Scope *scope_defined_outside = 0) {
|
|||||||
token_expect(TK_ColonAssign);
|
token_expect(TK_ColonAssign);
|
||||||
Ast_Expr *expr = parse_expr();
|
Ast_Expr *expr = parse_expr();
|
||||||
Ast_Var_Unpack *vars = ast_var_unpack(token, decls, expr);
|
Ast_Var_Unpack *vars = ast_var_unpack(token, decls, expr);
|
||||||
scope->stmts.add(vars);
|
return vars;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Declaration or init stmt
|
// Declaration or init stmt
|
||||||
@@ -469,20 +467,32 @@ parse_stmt_scope(Ast_Scope *scope_defined_outside = 0) {
|
|||||||
result = parse_expr();
|
result = parse_expr();
|
||||||
result = parse_init_stmt((Ast_Expr *)result);
|
result = parse_init_stmt((Ast_Expr *)result);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
result->flags = set_flag(result->flags, AST_STMT);
|
result->flags = set_flag(result->flags, AST_STMT);
|
||||||
scope->stmts.add(result);
|
return result;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
compiler_error(token, "Unexpected token [%s] while parsing statement", name(token->kind));
|
compiler_error(token, "Unexpected token [%s] while parsing statement", name(token->kind));
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CORE_Static Ast_Scope *
|
||||||
|
parse_stmt_scope(Ast_Scope *scope_defined_outside, bool empty_scope_is_error) {
|
||||||
|
Scoped_Arena scratch(pctx->scratch);
|
||||||
|
Ast_Scope *scope = scope_defined_outside;
|
||||||
|
if (!scope_defined_outside) scope = begin_stmt_scope(scratch.arena, token_get());
|
||||||
|
|
||||||
|
if (token_expect(OPEN_SCOPE)) { // @todo: Fix error message here, it doesn't show proper token context
|
||||||
|
do {
|
||||||
|
Ast *stmt = parse_stmt();
|
||||||
|
scope->stmts.add(stmt);
|
||||||
} while (token_match(SAME_SCOPE));
|
} while (token_match(SAME_SCOPE));
|
||||||
token_expect(CLOSE_SCOPE);
|
token_expect(CLOSE_SCOPE);
|
||||||
|
}
|
||||||
|
|
||||||
if (!scope_defined_outside) finalize_stmt_scope(scope);
|
if (!scope_defined_outside) finalize_stmt_scope(scope);
|
||||||
}
|
|
||||||
return scope;
|
return scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user