Begin work on semantically type checking asm templates

This commit is contained in:
gingerBill
2026-08-09 18:24:56 +01:00
parent 5e49e6c1a5
commit 5ac28cdecd
8 changed files with 769 additions and 29 deletions

View File

@@ -542,6 +542,7 @@ gb_internal Ast *clone_ast(Ast *node, AstFile *f) {
n->AsmLabelDecl.name = clone_ast(n->AsmLabelDecl.name, f);
break;
case Ast_AsmInstruction:
n->AsmInstruction.name = clone_ast(n->AsmInstruction.name, f);
n->AsmInstruction.operands = clone_ast_array(n->AsmInstruction.operands, f);
break;
case Ast_AsmMemoryOperand:
@@ -2512,7 +2513,7 @@ gb_internal Ast *parse_asm_instruction(AstFile *f) {
/*fallthrough*/
case Token_Ident:
{
Token name = advance_token(f);
Ast *name = parse_ident(f);
auto operands = parse_asm_operands(f);
Ast *instruction = alloc_ast_node(f, Ast_AsmInstruction);
instruction->AsmInstruction.name = name;
@@ -2535,6 +2536,33 @@ gb_internal Ast *parse_asm_instruction(AstFile *f) {
return nullptr;
}
gb_internal Ast *parse_results(AstFile *f, bool *diverging);
gb_internal bool is_field_list_generic(AstFieldList *field_list, bool check_names);
gb_internal Ast *parse_asm_signature(AstFile *f, Token asm_token) {
Ast *params = nullptr;
Ast *results = nullptr;
bool diverging = false;
ProcCallingConvention cc = ProcCC_InlineAsm;
expect_token(f, Token_OpenParen);
f->expr_level += 1;
params = parse_field_list(f, nullptr, FieldFlag_Signature, Token_CloseParen, false, false);
if (file_allow_newline(f)) {
skip_possible_newline(f);
}
f->expr_level -= 1;
expect_token_after(f, Token_CloseParen, "asm template parameter list");
results = parse_results(f, &diverging);
u64 tags = 0;
bool is_generic = is_field_list_generic(&params->FieldList, true);
if (!is_generic && (results != nullptr)) {
is_generic = is_field_list_generic(&results->FieldList, false);
}
return ast_proc_type(f, asm_token, params, results, tags, cc, is_generic, diverging);
}
gb_internal Ast *parse_asm_template(AstFile *f) {
Token token = expect_token(f, Token_asm);
@@ -2542,6 +2570,8 @@ gb_internal Ast *parse_asm_template(AstFile *f) {
bool has_side_effects = false;
bool is_align_stack = false;
Ast *signature = parse_asm_signature(f, token);
while (f->curr_token.kind == Token_Hash) {
advance_token(f);
if (f->curr_token.kind == Token_Ident) {
@@ -2565,12 +2595,13 @@ gb_internal Ast *parse_asm_template(AstFile *f) {
}
}
Ast *signature = parse_proc_type(f, token);
Slice<Ast *> asm_specs = {};
Slice<Ast *> asm_clobbers = {};
if (file_allow_newline(f)) {
skip_possible_newline(f);
}
if (f->curr_token.kind == Token_OpenBracket) {
Array<Ast *> specs = {};
specs.allocator = heap_allocator();
@@ -2630,6 +2661,9 @@ gb_internal Ast *parse_asm_template(AstFile *f) {
}
}
Token close = expect_token(f, Token_CloseBracket);
if (file_allow_newline(f)) {
skip_possible_newline(f);
}
asm_specs = slice_from_array(specs);
asm_clobbers = slice_from_array(clobbers);