diff options
| author | Daniel Gavin <danielgavin5@hotmail.com> | 2021-05-20 12:15:14 +0200 |
|---|---|---|
| committer | Daniel Gavin <danielgavin5@hotmail.com> | 2021-05-20 12:15:14 +0200 |
| commit | 44ee0f2cdc773fc3ba3261de076b8a8a7fb64f03 (patch) | |
| tree | c408237d1bd2e6bfcb0c5526d9c0d8cdb97bbf69 /src/parser.cpp | |
| parent | 50035f257eb33769211ca49a30c51f9a20440a0e (diff) | |
| parent | 92abddddc5ca4be622e93856c7246159b594e9e9 (diff) | |
Merge branch 'master' into prototype-fmt
Diffstat (limited to 'src/parser.cpp')
| -rw-r--r-- | src/parser.cpp | 334 |
1 files changed, 159 insertions, 175 deletions
diff --git a/src/parser.cpp b/src/parser.cpp index a7e4c9162..a5180b4dd 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -1,110 +1,4 @@ -Token ast_token(Ast *node) { - switch (node->kind) { - case Ast_Ident: return node->Ident.token; - case Ast_Implicit: return node->Implicit; - case Ast_Undef: return node->Undef; - case Ast_BasicLit: return node->BasicLit.token; - case Ast_BasicDirective: return node->BasicDirective.token; - case Ast_ProcGroup: return node->ProcGroup.token; - case Ast_ProcLit: return ast_token(node->ProcLit.type); - case Ast_CompoundLit: - if (node->CompoundLit.type != nullptr) { - return ast_token(node->CompoundLit.type); - } - return node->CompoundLit.open; - - case Ast_TagExpr: return node->TagExpr.token; - case Ast_BadExpr: return node->BadExpr.begin; - case Ast_UnaryExpr: return node->UnaryExpr.op; - case Ast_BinaryExpr: return ast_token(node->BinaryExpr.left); - case Ast_ParenExpr: return node->ParenExpr.open; - case Ast_CallExpr: return ast_token(node->CallExpr.proc); - case Ast_SelectorExpr: - if (node->SelectorExpr.selector != nullptr) { - return ast_token(node->SelectorExpr.selector); - } - return node->SelectorExpr.token; - case Ast_SelectorCallExpr: - if (node->SelectorCallExpr.expr != nullptr) { - return ast_token(node->SelectorCallExpr.expr); - } - return node->SelectorCallExpr.token; - case Ast_ImplicitSelectorExpr: - if (node->ImplicitSelectorExpr.selector != nullptr) { - return ast_token(node->ImplicitSelectorExpr.selector); - } - return node->ImplicitSelectorExpr.token; - case Ast_IndexExpr: return node->IndexExpr.open; - case Ast_SliceExpr: return node->SliceExpr.open; - case Ast_Ellipsis: return node->Ellipsis.token; - case Ast_FieldValue: return node->FieldValue.eq; - case Ast_DerefExpr: return node->DerefExpr.op; - case Ast_TernaryExpr: return ast_token(node->TernaryExpr.cond); - case Ast_TernaryIfExpr: return ast_token(node->TernaryIfExpr.x); - case Ast_TernaryWhenExpr: return ast_token(node->TernaryWhenExpr.x); - case Ast_TypeAssertion: return ast_token(node->TypeAssertion.expr); - case Ast_TypeCast: return node->TypeCast.token; - case Ast_AutoCast: return node->AutoCast.token; - case Ast_InlineAsmExpr: return node->InlineAsmExpr.token; - - case Ast_BadStmt: return node->BadStmt.begin; - case Ast_EmptyStmt: return node->EmptyStmt.token; - case Ast_ExprStmt: return ast_token(node->ExprStmt.expr); - case Ast_TagStmt: return node->TagStmt.token; - case Ast_AssignStmt: return node->AssignStmt.op; - case Ast_BlockStmt: return node->BlockStmt.open; - case Ast_IfStmt: return node->IfStmt.token; - case Ast_WhenStmt: return node->WhenStmt.token; - case Ast_ReturnStmt: return node->ReturnStmt.token; - case Ast_ForStmt: return node->ForStmt.token; - case Ast_RangeStmt: return node->RangeStmt.token; - case Ast_UnrollRangeStmt: return node->UnrollRangeStmt.unroll_token; - case Ast_CaseClause: return node->CaseClause.token; - case Ast_SwitchStmt: return node->SwitchStmt.token; - case Ast_TypeSwitchStmt: return node->TypeSwitchStmt.token; - case Ast_DeferStmt: return node->DeferStmt.token; - case Ast_BranchStmt: return node->BranchStmt.token; - case Ast_UsingStmt: return node->UsingStmt.token; - - case Ast_BadDecl: return node->BadDecl.begin; - case Ast_Label: return node->Label.token; - - case Ast_ValueDecl: return ast_token(node->ValueDecl.names[0]); - case Ast_PackageDecl: return node->PackageDecl.token; - case Ast_ImportDecl: return node->ImportDecl.token; - case Ast_ForeignImportDecl: return node->ForeignImportDecl.token; - - case Ast_ForeignBlockDecl: return node->ForeignBlockDecl.token; - - case Ast_Attribute: - return node->Attribute.token; - - case Ast_Field: - if (node->Field.names.count > 0) { - return ast_token(node->Field.names[0]); - } - return ast_token(node->Field.type); - case Ast_FieldList: - return node->FieldList.token; - - case Ast_TypeidType: return node->TypeidType.token; - case Ast_HelperType: return node->HelperType.token; - case Ast_DistinctType: return node->DistinctType.token; - case Ast_PolyType: return node->PolyType.token; - case Ast_ProcType: return node->ProcType.token; - case Ast_RelativeType: return ast_token(node->RelativeType.tag); - case Ast_PointerType: return node->PointerType.token; - case Ast_ArrayType: return node->ArrayType.token; - case Ast_DynamicArrayType: return node->DynamicArrayType.token; - case Ast_StructType: return node->StructType.token; - case Ast_UnionType: return node->UnionType.token; - case Ast_EnumType: return node->EnumType.token; - case Ast_BitSetType: return node->BitSetType.token; - case Ast_MapType: return node->MapType.token; - } - - return empty_token; -} +#include "parser_pos.cpp" Token token_end_of_line(AstFile *f, Token tok) { u8 const *start = f->tokenizer.start + tok.pos.offset; @@ -116,6 +10,48 @@ Token token_end_of_line(AstFile *f, Token tok) { return tok; } +gbString get_file_line_as_string(TokenPos const &pos, i32 *offset_) { + AstFile *file = get_ast_file_from_id(pos.file_id); + if (file == nullptr) { + return nullptr; + } + isize offset = pos.offset; + + u8 *start = file->tokenizer.start; + u8 *end = file->tokenizer.end; + isize len = end-start; + if (len < offset) { + return nullptr; + } + + u8 *pos_offset = start+offset; + + u8 *line_start = pos_offset; + u8 *line_end = pos_offset; + while (line_start >= start) { + if (*line_start == '\n') { + line_start += 1; + break; + } + line_start -= 1; + } + + while (line_end < end) { + if (*line_end == '\n') { + line_end -= 1; + break; + } + line_end += 1; + } + String the_line = make_string(line_start, line_end-line_start); + the_line = string_trim_whitespace(the_line); + + if (offset_) *offset_ = cast(i32)(pos_offset - the_line.text); + + return gb_string_make_length(heap_allocator(), the_line.text, the_line.len); +} + + isize ast_node_size(AstKind kind) { return align_formula_isize(gb_size_of(AstCommonStuff) + ast_variant_sizes[kind], gb_align_of(void *)); @@ -241,11 +177,6 @@ Ast *clone_ast(Ast *node) { n->FieldValue.value = clone_ast(n->FieldValue.value); break; - case Ast_TernaryExpr: - n->TernaryExpr.cond = clone_ast(n->TernaryExpr.cond); - n->TernaryExpr.x = clone_ast(n->TernaryExpr.x); - n->TernaryExpr.y = clone_ast(n->TernaryExpr.y); - break; case Ast_TernaryIfExpr: n->TernaryIfExpr.x = clone_ast(n->TernaryIfExpr.x); n->TernaryIfExpr.cond = clone_ast(n->TernaryIfExpr.cond); @@ -438,12 +369,15 @@ Ast *clone_ast(Ast *node) { void error(Ast *node, char const *fmt, ...) { Token token = {}; + TokenPos end_pos = {}; if (node != nullptr) { token = ast_token(node); + end_pos = ast_end_pos(node); } + va_list va; va_start(va, fmt); - error_va(token, fmt, va); + error_va(token.pos, end_pos, fmt, va); va_end(va); if (node != nullptr && node->file != nullptr) { node->file->error_count += 1; @@ -457,7 +391,7 @@ void error_no_newline(Ast *node, char const *fmt, ...) { } va_list va; va_start(va, fmt); - error_no_newline_va(token, fmt, va); + error_no_newline_va(token.pos, fmt, va); va_end(va); if (node != nullptr && node->file != nullptr) { node->file->error_count += 1; @@ -465,16 +399,28 @@ void error_no_newline(Ast *node, char const *fmt, ...) { } void warning(Ast *node, char const *fmt, ...) { + Token token = {}; + TokenPos end_pos = {}; + if (node != nullptr) { + token = ast_token(node); + end_pos = ast_end_pos(node); + } va_list va; va_start(va, fmt); - warning_va(ast_token(node), fmt, va); + warning_va(token.pos, end_pos, fmt, va); va_end(va); } void syntax_error(Ast *node, char const *fmt, ...) { + Token token = {}; + TokenPos end_pos = {}; + if (node != nullptr) { + token = ast_token(node); + end_pos = ast_end_pos(node); + } va_list va; va_start(va, fmt); - syntax_error_va(ast_token(node), fmt, va); + syntax_error_va(token.pos, end_pos, fmt, va); va_end(va); if (node != nullptr && node->file != nullptr) { node->file->error_count += 1; @@ -646,7 +592,7 @@ Ast *ast_basic_lit(AstFile *f, Token basic_lit) { return result; } -Ast *ast_basic_directive(AstFile *f, Token token, String name) { +Ast *ast_basic_directive(AstFile *f, Token token, Token name) { Ast *result = alloc_ast_node(f, Ast_BasicDirective); result->BasicDirective.token = token; result->BasicDirective.name = name; @@ -698,13 +644,6 @@ Ast *ast_compound_lit(AstFile *f, Ast *type, Array<Ast *> const &elems, Token op } -Ast *ast_ternary_expr(AstFile *f, Ast *cond, Ast *x, Ast *y) { - Ast *result = alloc_ast_node(f, Ast_TernaryExpr); - result->TernaryExpr.cond = cond; - result->TernaryExpr.x = x; - result->TernaryExpr.y = y; - return result; -} Ast *ast_ternary_if_expr(AstFile *f, Ast *x, Ast *cond, Ast *y) { Ast *result = alloc_ast_node(f, Ast_TernaryIfExpr); result->TernaryIfExpr.x = x; @@ -1357,6 +1296,7 @@ Token expect_token_after(AstFile *f, TokenKind kind, char const *msg) { bool is_token_range(TokenKind kind) { switch (kind) { case Token_Ellipsis: + case Token_RangeFull: case Token_RangeHalf: return true; } @@ -1587,6 +1527,10 @@ void expect_semicolon(AstFile *f, Ast *s) { return; } + if (f->curr_token.kind == Token_EOF) { + return; + } + if (s != nullptr) { bool insert_semi = (f->tokenizer.flags & TokenizerFlag_InsertSemicolon) != 0; if (insert_semi) { @@ -2007,35 +1951,28 @@ Ast *parse_operand(AstFile *f, bool lhs) { Token name = expect_token(f, Token_Ident); if (name.string == "type") { return ast_helper_type(f, token, parse_type(f)); - } /* else if (name.string == "no_deferred") { - operand = parse_expr(f, false); - if (unparen_expr(operand)->kind != Ast_CallExpr) { - syntax_error(operand, "#no_deferred can only be applied to procedure calls"); - operand = ast_bad_expr(f, token, f->curr_token); - } - operand->state_flags |= StateFlag_no_deferred; - } */ else if (name.string == "file") { - return ast_basic_directive(f, token, name.string); - } else if (name.string == "line") { return ast_basic_directive(f, token, name.string); - } else if (name.string == "procedure") { return ast_basic_directive(f, token, name.string); - } else if (name.string == "caller_location") { return ast_basic_directive(f, token, name.string); + } else if (name.string == "file") { + return ast_basic_directive(f, token, name); + } else if (name.string == "line") { return ast_basic_directive(f, token, name); + } else if (name.string == "procedure") { return ast_basic_directive(f, token, name); + } else if (name.string == "caller_location") { return ast_basic_directive(f, token, name); } else if (name.string == "location") { - Ast *tag = ast_basic_directive(f, token, name.string); + Ast *tag = ast_basic_directive(f, token, name); return parse_call_expr(f, tag); } else if (name.string == "load") { - Ast *tag = ast_basic_directive(f, token, name.string); + Ast *tag = ast_basic_directive(f, token, name); return parse_call_expr(f, tag); } else if (name.string == "assert") { - Ast *tag = ast_basic_directive(f, token, name.string); + Ast *tag = ast_basic_directive(f, token, name); return parse_call_expr(f, tag); } else if (name.string == "defined") { - Ast *tag = ast_basic_directive(f, token, name.string); + Ast *tag = ast_basic_directive(f, token, name); return parse_call_expr(f, tag); } else if (name.string == "config") { - Ast *tag = ast_basic_directive(f, token, name.string); + Ast *tag = ast_basic_directive(f, token, name); return parse_call_expr(f, tag); } else if (name.string == "soa" || name.string == "simd") { - Ast *tag = ast_basic_directive(f, token, name.string); + Ast *tag = ast_basic_directive(f, token, name); Ast *original_type = parse_type(f); Ast *type = unparen_expr(original_type); switch (type->kind) { @@ -2047,7 +1984,7 @@ Ast *parse_operand(AstFile *f, bool lhs) { } return original_type; } else if (name.string == "partial") { - Ast *tag = ast_basic_directive(f, token, name.string); + Ast *tag = ast_basic_directive(f, token, name); Ast *original_type = parse_type(f); Ast *type = unparen_expr(original_type); switch (type->kind) { @@ -2059,6 +1996,10 @@ Ast *parse_operand(AstFile *f, bool lhs) { return original_type; } else if (name.string == "bounds_check") { Ast *operand = parse_expr(f, lhs); + if (operand == nullptr) { + syntax_error(token, "Invalid expresssion for #%.*s", LIT(name.string)); + return nullptr; + } operand->state_flags |= StateFlag_bounds_check; if ((operand->state_flags & StateFlag_no_bounds_check) != 0) { syntax_error(token, "#bounds_check and #no_bounds_check cannot be applied together"); @@ -2066,13 +2007,17 @@ Ast *parse_operand(AstFile *f, bool lhs) { return operand; } else if (name.string == "no_bounds_check") { Ast *operand = parse_expr(f, lhs); + if (operand == nullptr) { + syntax_error(token, "Invalid expresssion for #%.*s", LIT(name.string)); + return nullptr; + } operand->state_flags |= StateFlag_no_bounds_check; if ((operand->state_flags & StateFlag_bounds_check) != 0) { syntax_error(token, "#bounds_check and #no_bounds_check cannot be applied together"); } return operand; } else if (name.string == "relative") { - Ast *tag = ast_basic_directive(f, token, name.string); + Ast *tag = ast_basic_directive(f, token, name); tag = parse_call_expr(f, tag); Ast *type = parse_type(f); return ast_relative_type(f, tag, type); @@ -2158,6 +2103,8 @@ Ast *parse_operand(AstFile *f, bool lhs) { return type; } + skip_possible_newline_for_literal(f); + if (allow_token(f, Token_Undef)) { if (where_token.kind != Token_Invalid) { syntax_error(where_token, "'where' clauses are not allowed on procedure literals without a defined body (replaced with ---)"); @@ -2170,6 +2117,14 @@ Ast *parse_operand(AstFile *f, bool lhs) { body = parse_body(f); f->curr_proc = curr_proc; + // Apply the tags directly to the body rather than the type + if (tags & ProcTag_no_bounds_check) { + body->state_flags |= StateFlag_no_bounds_check; + } + if (tags & ProcTag_bounds_check) { + body->state_flags |= StateFlag_bounds_check; + } + return ast_proc_lit(f, type, body, tags, where_token, where_clauses); } else if (allow_token(f, Token_do)) { Ast *curr_proc = f->curr_proc; @@ -2317,7 +2272,7 @@ Ast *parse_operand(AstFile *f, bool lhs) { f->expr_level = prev_level; } - + skip_possible_newline_for_literal(f); Token open = expect_token_after(f, Token_OpenBrace, "struct"); isize name_count = 0; @@ -2394,6 +2349,7 @@ Ast *parse_operand(AstFile *f, bool lhs) { } + skip_possible_newline_for_literal(f); Token open = expect_token_after(f, Token_OpenBrace, "union"); while (f->curr_token.kind != Token_CloseBrace && @@ -2418,6 +2374,8 @@ Ast *parse_operand(AstFile *f, bool lhs) { if (f->curr_token.kind != Token_OpenBrace) { base_type = parse_type(f); } + + skip_possible_newline_for_literal(f); Token open = expect_token(f, Token_OpenBrace); Array<Ast *> values = parse_element_list(f); @@ -2509,6 +2467,7 @@ Ast *parse_operand(AstFile *f, bool lhs) { } } + skip_possible_newline_for_literal(f); Token open = expect_token(f, Token_OpenBrace); Ast *asm_string = parse_expr(f, false); expect_token(f, Token_Comma); @@ -2673,6 +2632,7 @@ Ast *parse_atom_expr(AstFile *f, Ast *operand, bool lhs) { switch (f->curr_token.kind) { case Token_Ellipsis: + case Token_RangeFull: case Token_RangeHalf: // NOTE(bill): Do not err yet case Token_Colon: @@ -2684,6 +2644,7 @@ Ast *parse_atom_expr(AstFile *f, Ast *operand, bool lhs) { switch (f->curr_token.kind) { case Token_Ellipsis: + case Token_RangeFull: case Token_RangeHalf: syntax_error(f->curr_token, "Expected a colon, not a range"); /* fallthrough */ @@ -2722,6 +2683,16 @@ Ast *parse_atom_expr(AstFile *f, Ast *operand, bool lhs) { } break; + case Token_Increment: + case Token_Decrement: + if (!lhs) { + Token token = advance_token(f); + syntax_error(token, "Postfix '%.*s' operator is not supported", LIT(token.string)); + } else { + loop = false; + } + break; + default: loop = false; break; @@ -2752,16 +2723,26 @@ Ast *parse_unary_expr(AstFile *f, bool lhs) { return ast_auto_cast(f, token, expr); } + case Token_Add: case Token_Sub: - case Token_Not: case Token_Xor: - case Token_And: { + case Token_And: + case Token_Not: { Token token = advance_token(f); Ast *expr = parse_unary_expr(f, lhs); return ast_unary_expr(f, token, expr); } + case Token_Increment: + case Token_Decrement: { + Token token = advance_token(f); + syntax_error(token, "Unary '%.*s' operator is not supported", LIT(token.string)); + Ast *expr = parse_unary_expr(f, lhs); + return ast_unary_expr(f, token, expr); + } + + case Token_Period: { Token token = expect_token(f, Token_Period); Ast *ident = parse_ident(f); @@ -2790,6 +2771,7 @@ i32 token_precedence(AstFile *f, TokenKind t) { case Token_when: return 1; case Token_Ellipsis: + case Token_RangeFull: case Token_RangeHalf: if (!f->allow_range) { return 0; @@ -2857,7 +2839,7 @@ Ast *parse_binary_expr(AstFile *f, bool lhs, i32 prec_in) { Ast *x = parse_expr(f, lhs); Token token_c = expect_token(f, Token_Colon); Ast *y = parse_expr(f, lhs); - expr = ast_ternary_expr(f, cond, x, y); + expr = ast_ternary_if_expr(f, x, cond, y); } else if (op.kind == Token_if) { Ast *x = expr; // Token_if @@ -2979,7 +2961,7 @@ Ast *parse_foreign_block(AstFile *f, Token token) { defer (f->in_foreign_block = prev_in_foreign_block); f->in_foreign_block = true; - + skip_possible_newline_for_literal(f); open = expect_token(f, Token_OpenBrace); while (f->curr_token.kind != Token_CloseBrace && @@ -3151,6 +3133,13 @@ Ast *parse_simple_stmt(AstFile *f, u32 flags) { return ast_bad_stmt(f, token, f->curr_token); } + switch (token.kind) { + case Token_Increment: + case Token_Decrement: + advance_token(f); + syntax_error(token, "Postfix '%.*s' statement is not supported", LIT(token.string)); + break; + } #if 0 @@ -3220,6 +3209,7 @@ ProcCallingConvention string_to_calling_convention(String s) { if (s == "fastcall") return ProcCC_FastCall; if (s == "fast") return ProcCC_FastCall; if (s == "none") return ProcCC_None; + if (s == "naked") return ProcCC_Naked; return ProcCC_Invalid; } @@ -3896,12 +3886,6 @@ Ast *parse_return_stmt(AstFile *f) { while (f->curr_token.kind != Token_Semicolon) { Ast *arg = parse_expr(f, false); - // if (f->curr_token.kind == Token_Eq) { - // Token eq = expect_token(f, Token_Eq); - // Ast *value = parse_value(f); - // arg = ast_field_value(f, arg, value, eq); - // } - array_add(&results, arg); if (f->curr_token.kind != Token_Comma || f->curr_token.kind == Token_EOF) { @@ -3966,7 +3950,7 @@ Ast *parse_for_stmt(AstFile *f) { } } - if (!is_range && allow_token(f, Token_Semicolon)) { + if (!is_range && parse_control_statement_semicolon_separator(f)) { init = cond; cond = nullptr; if (f->curr_token.kind != Token_Semicolon) { @@ -4022,7 +4006,7 @@ Ast *parse_case_clause(AstFile *f, bool is_type) { } f->allow_range = prev_allow_range; f->allow_in_expr = prev_allow_in_expr; - expect_token(f, Token_Colon); // TODO(bill): Is this the best syntax? + expect_token(f, Token_Colon); Array<Ast *> stmts = parse_stmt_list(f); return ast_case_clause(f, token, list, stmts); @@ -4332,6 +4316,16 @@ Ast *parse_unrolled_for_loop(AstFile *f, Token unroll_token) { return ast_unroll_range_stmt(f, unroll_token, for_token, val0, val1, in_token, expr, body); } +void parse_check_directive_for_empty_statement(Ast *s, Token const &name) { + if (s != nullptr && s->kind == Ast_EmptyStmt) { + if (s->EmptyStmt.token.string == "\n") { + syntax_error(name, "#%.*s cannot be followed by a newline", LIT(name.string)); + } else { + syntax_error(name, "#%.*s cannot be applied to an empty statement ';'", LIT(name.string)); + } + } +} + Ast *parse_stmt(AstFile *f) { Ast *s = nullptr; Token token = f->curr_token; @@ -4438,6 +4432,7 @@ Ast *parse_stmt(AstFile *f) { if (tag == "bounds_check") { s = parse_stmt(f); + parse_check_directive_for_empty_statement(s, name); s->state_flags |= StateFlag_bounds_check; if ((s->state_flags & StateFlag_no_bounds_check) != 0) { syntax_error(token, "#bounds_check and #no_bounds_check cannot be applied together"); @@ -4445,27 +4440,12 @@ Ast *parse_stmt(AstFile *f) { return s; } else if (tag == "no_bounds_check") { s = parse_stmt(f); + parse_check_directive_for_empty_statement(s, name); s->state_flags |= StateFlag_no_bounds_check; if ((s->state_flags & StateFlag_bounds_check) != 0) { syntax_error(token, "#bounds_check and #no_bounds_check cannot be applied together"); } return s; - } else if (tag == "complete") { - s = parse_stmt(f); - switch (s->kind) { - case Ast_SwitchStmt: - s->SwitchStmt.partial = false; - syntax_warning(token, "#complete is now the default and has been replaced with its opposite: #partial"); - break; - case Ast_TypeSwitchStmt: - s->TypeSwitchStmt.partial = false; - syntax_warning(token, "#complete is now the default and has been replaced with its opposite: #partial"); - break; - default: - syntax_error(token, "#complete can only be applied to a switch statement"); - break; - } - return s; } else if (tag == "partial") { s = parse_stmt(f); switch (s->kind) { @@ -4475,16 +4455,19 @@ Ast *parse_stmt(AstFile *f) { case Ast_TypeSwitchStmt: s->TypeSwitchStmt.partial = true; break; + case Ast_EmptyStmt: + parse_check_directive_for_empty_statement(s, name); + break; default: syntax_error(token, "#partial can only be applied to a switch statement"); break; } return s; } else if (tag == "assert") { - Ast *t = ast_basic_directive(f, hash_token, tag); + Ast *t = ast_basic_directive(f, hash_token, name); return ast_expr_stmt(f, parse_call_expr(f, t)); } else if (tag == "panic") { - Ast *t = ast_basic_directive(f, hash_token, tag); + Ast *t = ast_basic_directive(f, hash_token, name); return ast_expr_stmt(f, parse_call_expr(f, t)); } else if (name.string == "force_inline" || name.string == "force_no_inline") { @@ -4571,6 +4554,7 @@ ParseFileError init_ast_file(AstFile *f, String fullpath, TokenPos *err_pos) { GB_ASSERT(f != nullptr); f->fullpath = string_trim_whitespace(fullpath); // Just in case set_file_path_string(f->id, fullpath); + set_ast_file_from_id(f->id, f); if (!string_ends_with(f->fullpath, str_lit(".odin"))) { return ParseFile_WrongExtension; } |