Core: Add Ast_Label
This commit is contained in:
13
base.cpp
13
base.cpp
@@ -289,14 +289,13 @@ hash_string(String string) {
|
||||
return hash;
|
||||
}
|
||||
|
||||
CORE_Static U64
|
||||
force_inline U64
|
||||
hash_u64(U64 x) {
|
||||
x *= 0xff51afd7ed558ccd;
|
||||
x ^= x >> 32;
|
||||
return x;
|
||||
U64 result = hash_string({(U8 *)&x, sizeof(x)});
|
||||
return result;
|
||||
}
|
||||
|
||||
CORE_Static U64
|
||||
force_inline U64
|
||||
hash_ptr(const void *ptr) {
|
||||
return hash_u64((uintptr_t)ptr);
|
||||
}
|
||||
@@ -314,14 +313,14 @@ hash_mix(U64 x, U64 y) {
|
||||
return x;
|
||||
}
|
||||
|
||||
CORE_Static U64
|
||||
force_inline U64
|
||||
is_pow2(U64 x) {
|
||||
assert(x != 0);
|
||||
B32 result = (x & (x - 1llu)) == 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
CORE_Static U64
|
||||
force_inline U64
|
||||
wrap_around_pow2(U64 x, U64 power_of_2) {
|
||||
assert(is_pow2(power_of_2));
|
||||
U64 r = (((x) & ((power_of_2)-1llu)));
|
||||
|
||||
@@ -76,6 +76,9 @@ main :: (): int
|
||||
target_color := RED
|
||||
target_color.a = 255/2
|
||||
|
||||
:some_label:
|
||||
target_color = RED
|
||||
|
||||
for !WindowShouldClose()
|
||||
WinX = GetScreenWidth()
|
||||
WinY = GetScreenHeight()
|
||||
|
||||
@@ -177,6 +177,15 @@ ast_return(Token *pos, Ast_Expr *expr) {
|
||||
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);
|
||||
result->enable_goto = enable_goto;
|
||||
result->name = name;
|
||||
result->scope = scope;
|
||||
return result;
|
||||
}
|
||||
|
||||
CORE_Static Ast_If_Node *
|
||||
ast_if_node(Token *pos, Ast_Expr *init, Ast_Expr *expr, Ast_Scope *scope) {
|
||||
AST_NEW(If_Node, IF_NODE, pos, AST_STMT);
|
||||
|
||||
@@ -621,28 +621,28 @@ gen_ast(Ast *ast) {
|
||||
BREAK();
|
||||
}
|
||||
|
||||
CASE(CONTINUE, Pass) {
|
||||
unused(node);
|
||||
case AST_LABEL: {
|
||||
auto n = (Ast_Label *)ast;
|
||||
if (n->enable_goto == false) gen("/* %Q */", n->name);
|
||||
if (n->enable_goto == true) gen("%Q:", n->name);
|
||||
gen_stmt_scope(n->scope);
|
||||
} break;
|
||||
|
||||
case AST_CONTINUE: {
|
||||
gen("continue;");
|
||||
BREAK();
|
||||
}
|
||||
CASE(BREAK, Break) {
|
||||
unused(node);
|
||||
} break;
|
||||
|
||||
case AST_BREAK: {
|
||||
gen("break;");
|
||||
BREAK();
|
||||
}
|
||||
} break;
|
||||
|
||||
CASE(COMPILER_BREAKPOINT_STMT, Break) {
|
||||
unused(node);
|
||||
case AST_COMPILER_BREAKPOINT_STMT: {
|
||||
__debugbreak();
|
||||
BREAK();
|
||||
}
|
||||
} break;
|
||||
|
||||
CASE(PASS, Pass) {
|
||||
unused(node);
|
||||
case AST_PASS: {
|
||||
gen("// pass");
|
||||
BREAK();
|
||||
}
|
||||
} break;
|
||||
|
||||
CASE(BINARY, Binary) {
|
||||
gen_expr(node);
|
||||
|
||||
@@ -66,9 +66,8 @@ 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___compilerbreakpoint = pctx->intern("__CompilerBreakpoint"_s);
|
||||
pctx->interns.first_keyword = pctx->keyword_struct.str;
|
||||
pctx->interns.last_keyword = pctx->keyword___compilerbreakpoint.str;
|
||||
pctx->interns.last_keyword = pctx->keyword_enum.str;
|
||||
pctx->intern_typeof = pctx->intern("typeof"_s);
|
||||
pctx->intern_sizeof = pctx->intern("sizeof"_s);
|
||||
pctx->intern_len = pctx->intern("Len"_s);
|
||||
|
||||
@@ -107,7 +107,6 @@ 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___compilerbreakpoint;
|
||||
Intern_String intern_typeof;
|
||||
Intern_String intern_sizeof;
|
||||
Intern_String intern_len;
|
||||
|
||||
@@ -334,6 +334,7 @@ enum Ast_Kind : uint32_t {
|
||||
AST_TYPE_OF,
|
||||
AST_VARGS_LAMBDA_PARAM,
|
||||
|
||||
AST_LABEL,
|
||||
AST_SWITCH,
|
||||
AST_SWITCH_CASE,
|
||||
AST_VAR_UNPACK,
|
||||
@@ -404,17 +405,6 @@ struct Ast_Expr : Ast {
|
||||
};
|
||||
};
|
||||
|
||||
/* Typespecs
|
||||
*int - (AST_UNARY=TK_Pointer Ast_Unary) == TYPE_POINTER
|
||||
int - (AST_IDENT Ast_Atom) == TYPE_INT ..
|
||||
[] - (Ast_Array AST_ARRAY) == TYPE_SLICE
|
||||
[3] - (Ast_Array AST_ARRAY) == TYPE_ARRAY
|
||||
Array(int) - (Ast_Call AST_CALL) == TYPE_STRUCT, TYPE_UNION
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
struct Ast_Atom : Ast_Expr {
|
||||
// We have a field type here
|
||||
// it has a different purpose from the
|
||||
@@ -501,10 +491,25 @@ struct Ast_Builtin : Ast_Expr {
|
||||
|
||||
// Problem: We are parsing out of order, in the middle of parsing a function
|
||||
// we can jump down a different function, we cant therfore use global map.
|
||||
// Because it would have symbols from previous function we were in middle of resolving.
|
||||
//
|
||||
// On top of that in the future we want a way to inject scopes, for convenience.
|
||||
// Each scope needs to have it's checked locals list. To lookup syms we need to
|
||||
// look into global scope and to the locals list.
|
||||
//
|
||||
//
|
||||
// This seems slow though, would be nice to have a simpler scheme that's more flat.
|
||||
// Would be nice to just reuse single map while resolving that would keep track of which
|
||||
// function we are resolving.
|
||||
//
|
||||
// Also would be nice to have a more flat module scheme. The Ion approach seemed
|
||||
// very straight forward when I looked at it. It used a single locals list with
|
||||
// an index that signified from where we should consider declarations. Not really
|
||||
// sure how the packages worked though.
|
||||
//
|
||||
// The idea that you have a flat list of packages, each package has a flat list of declarations.
|
||||
// Seems nice.
|
||||
//
|
||||
|
||||
struct Ast_Return : Ast {
|
||||
Ast_Type *resolved_type;
|
||||
@@ -521,6 +526,7 @@ struct Ast_If : Ast {
|
||||
Array<Ast_If_Node *> ifs;
|
||||
};
|
||||
|
||||
// @todo: Ast_Simple_Stmt
|
||||
#define Ast_Pass Ast
|
||||
#define Ast_Break Ast
|
||||
|
||||
@@ -615,6 +621,7 @@ struct Ast_Decl : Ast {
|
||||
Intern_String name;
|
||||
Intern_String unique_name; // For code generation, currently only present on lambdas
|
||||
|
||||
// @todo: Move this to Ast_Operator_Overload
|
||||
uint64_t operator_overload_arguments_hash;
|
||||
Ast_Operator_Info *overload_op_info;
|
||||
|
||||
@@ -651,6 +658,10 @@ meta.inline_value_fields()
|
||||
/*END*/
|
||||
};
|
||||
|
||||
struct Ast_Label : Ast_Decl {
|
||||
bool enable_goto;
|
||||
};
|
||||
|
||||
enum Core_Message_Kind {
|
||||
CORE_ERROR,
|
||||
CORE_WARNING,
|
||||
|
||||
@@ -293,7 +293,7 @@ parse_stmt_scope(Ast_Scope *scope_defined_outside = 0) {
|
||||
scope->stmts.add(ast_continue(token));
|
||||
}
|
||||
|
||||
else if (token_match_keyword(pctx->keyword___compilerbreakpoint)) {
|
||||
else if (token_match_keyword(pctx->intern_compiler_breakpoint)) {
|
||||
scope->stmts.add(ast_compiler_breakpoint(token));
|
||||
}
|
||||
|
||||
@@ -423,6 +423,21 @@ parse_stmt_scope(Ast_Scope *scope_defined_outside = 0) {
|
||||
scope->stmts.add(result_if);
|
||||
}
|
||||
|
||||
// Label
|
||||
else if (token_match(TK_Colon)) {
|
||||
Token *ident = token_expect(TK_Identifier);
|
||||
Token *enable_goto_token = token_match(TK_Colon);
|
||||
bool enable_goto = enable_goto_token ? 1 : 0;
|
||||
Token *breakpoint = token_match_pound(pctx->intern_compiler_breakpoint);
|
||||
|
||||
Ast_Scope *s = 0;
|
||||
if (token_is(OPEN_SCOPE)) s = parse_stmt_scope();
|
||||
|
||||
Ast_Label *result = ast_label(token, ident->intern_val, s, enable_goto);
|
||||
if (breakpoint) set_flag(result->flags, AST_COMPILER_BREAKPOINT);
|
||||
scope->stmts.add(result);
|
||||
}
|
||||
|
||||
// Var unpack
|
||||
else if (token_is(TK_Identifier) && token_is(TK_Comma, 1)) {
|
||||
Array<Ast_Decl *> decls = {scratch.arena};
|
||||
|
||||
@@ -758,6 +758,14 @@ CORE_Static void resolve_stmt(Ast *ast, Ast_Type *ret) {
|
||||
__debugbreak();
|
||||
} break;
|
||||
|
||||
case AST_LABEL: {
|
||||
auto n = (Ast_Label *)ast;
|
||||
insert_into_scope(n->parent_scope, n);
|
||||
For(n->scope->stmts) {
|
||||
resolve_stmt(it, ret);
|
||||
}
|
||||
} break;
|
||||
|
||||
case AST_CONTINUE:
|
||||
case AST_BREAK:
|
||||
CASE(PASS, Pass) {
|
||||
|
||||
Reference in New Issue
Block a user