mirror of
https://github.com/odin-lang/Odin.git
synced 2026-09-02 10:13:35 +00:00
Add #no_init suffix directive for asm specifications.
This commit is contained in:
@@ -533,10 +533,11 @@ gb_internal Ast *clone_ast(Ast *node, AstFile *f) {
|
||||
case Ast_AsmRegister:
|
||||
break;
|
||||
case Ast_AsmSpec:
|
||||
n->AsmSpec.name = clone_ast(n->AsmSpec.name, f);
|
||||
n->AsmSpec.tied_name = clone_ast(n->AsmSpec.tied_name, f);
|
||||
n->AsmSpec.type = clone_ast(n->AsmSpec.type, f);
|
||||
n->AsmSpec.value = clone_ast(n->AsmSpec.value, f);
|
||||
n->AsmSpec.name = clone_ast(n->AsmSpec.name, f);
|
||||
n->AsmSpec.tied_name = clone_ast(n->AsmSpec.tied_name, f);
|
||||
n->AsmSpec.type = clone_ast(n->AsmSpec.type, f);
|
||||
n->AsmSpec.value = clone_ast(n->AsmSpec.value, f);
|
||||
n->AsmSpec.directives = clone_ast_array(n->AsmSpec.directives, f);
|
||||
break;
|
||||
case Ast_AsmClobber:
|
||||
n->AsmClobber.value = clone_ast(n->AsmClobber.value, f);
|
||||
@@ -2694,6 +2695,60 @@ gb_internal Ast *parse_asm_signature(AstFile *f, Token asm_token) {
|
||||
return ast_proc_type(f, asm_token, params, results, tags, cc, is_generic, diverging);
|
||||
}
|
||||
|
||||
gb_internal Ast *parse_asm_spec(AstFile *f) {
|
||||
Ast *name = parse_ident(f);
|
||||
Ast *tied_name = nullptr;
|
||||
Ast *type = nullptr;
|
||||
Ast *value = nullptr;
|
||||
if (allow_token(f, Token_ArrowRight)) {
|
||||
tied_name = parse_ident(f);
|
||||
}
|
||||
if (allow_token(f, Token_Colon)) {
|
||||
type = parse_type(f);
|
||||
}
|
||||
if (allow_token(f, Token_Eq)) {
|
||||
if (f->curr_token.kind == Token_Ident) {
|
||||
value = parse_ident(f);
|
||||
} else if (f->curr_token.kind == Token_Mod) {
|
||||
value = parse_asm_register(f);
|
||||
} else {
|
||||
error(f->curr_token, "Expected a register or scratch parameter");
|
||||
Ast *dummy = parse_expr(f, true);
|
||||
gb_unused(dummy);
|
||||
}
|
||||
}
|
||||
|
||||
if (tied_name != nullptr) {
|
||||
if (type != nullptr) {
|
||||
syntax_error(f->curr_token, "An asm specification for tied values cannot declare a type");
|
||||
}
|
||||
} else if (type == nullptr && value == nullptr) {
|
||||
syntax_error(f->curr_token, "An asm specification must specify at least either a type or a value if the value is not tied");
|
||||
}
|
||||
|
||||
Array<Ast *> directives = {};
|
||||
directives.allocator = heap_allocator();
|
||||
|
||||
while (f->curr_token.kind == Token_Hash) {
|
||||
Token token = expect_token(f, Token_Hash);
|
||||
Token name = expect_token_after(f, Token_Ident, "hash for directive");
|
||||
if (name.kind == Token_Ident) {
|
||||
Ast *directive = ast_basic_directive(f, token, name);
|
||||
array_add(&directives, directive);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Ast *spec = alloc_ast_node(f, Ast_AsmSpec);
|
||||
spec->AsmSpec.name = name;
|
||||
spec->AsmSpec.tied_name = tied_name;
|
||||
spec->AsmSpec.type = type;
|
||||
spec->AsmSpec.value = value;
|
||||
spec->AsmSpec.directives = directives;
|
||||
return spec;
|
||||
}
|
||||
|
||||
|
||||
gb_internal Ast *parse_asm_template(AstFile *f) {
|
||||
Token token = expect_token(f, Token_asm);
|
||||
|
||||
@@ -2718,41 +2773,7 @@ gb_internal Ast *parse_asm_template(AstFile *f) {
|
||||
f->curr_token.kind != Token_EOF) {
|
||||
Ast *spec = nullptr;
|
||||
if (f->curr_token.kind == Token_Ident) {
|
||||
Ast *name = parse_ident(f);
|
||||
Ast *tied_name = nullptr;
|
||||
Ast *type = nullptr;
|
||||
Ast *value = nullptr;
|
||||
if (allow_token(f, Token_ArrowRight)) {
|
||||
tied_name = parse_ident(f);
|
||||
}
|
||||
if (allow_token(f, Token_Colon)) {
|
||||
type = parse_type(f);
|
||||
}
|
||||
if (allow_token(f, Token_Eq)) {
|
||||
if (f->curr_token.kind == Token_Ident) {
|
||||
value = parse_ident(f);
|
||||
} else if (f->curr_token.kind == Token_Mod) {
|
||||
value = parse_asm_register(f);
|
||||
} else {
|
||||
error(f->curr_token, "Expected a register or scratch parameter");
|
||||
Ast *dummy = parse_expr(f, true);
|
||||
gb_unused(dummy);
|
||||
}
|
||||
}
|
||||
|
||||
if (tied_name != nullptr) {
|
||||
if (type != nullptr) {
|
||||
syntax_error(f->curr_token, "An asm specification for tied values cannot declare a type");
|
||||
}
|
||||
} else if (type == nullptr && value == nullptr) {
|
||||
syntax_error(f->curr_token, "An asm specification must specify at least either a type or a value if the value is not tied");
|
||||
}
|
||||
|
||||
spec = alloc_ast_node(f, Ast_AsmSpec);
|
||||
spec->AsmSpec.name = name;
|
||||
spec->AsmSpec.tied_name = tied_name;
|
||||
spec->AsmSpec.type = type;
|
||||
spec->AsmSpec.value = value;
|
||||
spec = parse_asm_spec(f);
|
||||
} else if (f->curr_token.kind == Token_Hash) {
|
||||
Token hash = expect_token(f, Token_Hash);
|
||||
Token name = expect_token(f, Token_Ident);
|
||||
|
||||
Reference in New Issue
Block a user