diff --git a/src/parser.cpp b/src/parser.cpp index cdf3c239c..37fd61e07 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -1361,6 +1361,22 @@ gb_internal Token peek_token(AstFile *f) { return {}; } +gb_internal Token peek_token_n(AstFile *f, isize n) { + Token found = {}; + for (isize i = f->curr_token_index+1; i < f->tokens.count; i++) { + Token tok = f->tokens[i]; + if (tok.kind == Token_Comment) { + continue; + } + found = tok; + if (n-- == 0) { + return found; + } + } + return {}; +} + + gb_internal bool skip_possible_newline(AstFile *f) { if (token_is_newline(f->curr_token)) { advance_token(f); @@ -2206,6 +2222,10 @@ gb_internal Ast *parse_operand(AstFile *f, bool lhs) { Ast *tag = ast_basic_directive(f, token, name); Ast *original_expr = parse_expr(f, lhs); Ast *expr = unparen_expr(original_expr); + if (expr == nullptr) { + syntax_error(name, "Expected a compound literal after #%.*s", LIT(name.string)); + return ast_bad_expr(f, token, name); + } switch (expr->kind) { case Ast_ArrayType: syntax_error(expr, "#partial has been replaced with #sparse for non-contiguous enumerated array types"); @@ -3419,6 +3439,18 @@ gb_internal Ast *parse_simple_stmt(AstFile *f, u32 flags) { case Token_Colon: expect_token_after(f, Token_Colon, "identifier list"); if ((flags&StmtAllowFlag_Label) && lhs.count == 1) { + bool is_partial = false; + Token partial_token = {}; + if (f->curr_token.kind == Token_Hash) { + // NOTE(bill): This is purely for error messages + Token name = peek_token_n(f, 0); + if (name.kind == Token_Ident && name.string == "partial" && + peek_token_n(f, 1).kind == Token_switch) { + partial_token = expect_token(f, Token_Hash); + expect_token(f, Token_Ident); + is_partial = true; + } + } switch (f->curr_token.kind) { case Token_OpenBrace: // block statement case Token_if: @@ -3440,6 +3472,19 @@ gb_internal Ast *parse_simple_stmt(AstFile *f, u32 flags) { break; } #undef _SET_LABEL + + if (is_partial) { + switch (stmt->kind) { + case Ast_SwitchStmt: + stmt->SwitchStmt.partial = true; + break; + case Ast_TypeSwitchStmt: + stmt->TypeSwitchStmt.partial = true; + break; + } + syntax_error(partial_token, "Incorrect use of directive, use '#partial %.*s: switch'", LIT(ast_token(name).string)); + } + return stmt; } break; }