diff --git a/core/odin/parser/parser.odin b/core/odin/parser/parser.odin index ad5ee9087..6b0aa2888 100644 --- a/core/odin/parser/parser.odin +++ b/core/odin/parser/parser.odin @@ -1455,7 +1455,7 @@ parse_stmt :: proc(p: ^Parser) -> ^ast.Stmt { case "unroll": return parse_unrolled_for_loop(p, tag) case "reverse": - stmt := parse_for_stmt(p) + stmt := parse_stmt(p) if range, is_range := stmt.derived.(^ast.Range_Stmt); is_range { if range.reverse { @@ -3515,6 +3515,25 @@ parse_simple_stmt :: proc(p: ^Parser, flags: Stmt_Allow_Flags) -> ^ast.Stmt { case op.kind == .Colon: expect_token_after(p, .Colon, "identifier list") if .Label in flags && len(lhs) == 1 { + is_partial := false + is_reverse := false + + partial_token: tokenizer.Token + if p.curr_tok.kind == .Hash { + name := peek_token(p) + if name.kind == .Ident && name.text == "partial" && + peek_token(p, 1).kind == .Switch { + partial_token = expect_token(p, .Hash) + expect_token(p, .Ident) + is_partial = true + } else if name.kind == .Ident && name.text == "reverse" && + peek_token(p, 1).kind == .For { + partial_token = expect_token(p, .Hash) + expect_token(p, .Ident) + is_reverse = true + } + } + #partial switch p.curr_tok.kind { case .Open_Brace, .If, .For, .Switch: label := lhs[0] @@ -3529,6 +3548,22 @@ parse_simple_stmt :: proc(p: ^Parser, flags: Stmt_Allow_Flags) -> ^ast.Stmt { case ^ast.Type_Switch_Stmt: n.label = label case ^ast.Range_Stmt: n.label = label } + + if is_partial { + #partial switch n in stmt.derived_stmt { + case ^ast.Switch_Stmt: n.partial = true + case ^ast.Type_Switch_Stmt: n.partial = true + case: + error(p, partial_token.pos, "incorrect use of directive, use '%s: #partial switch'", partial_token.text) + } + } + if is_reverse { + #partial switch n in stmt.derived_stmt { + case ^ast.Range_Stmt: n.reverse = true + case: + error(p, partial_token.pos, "incorrect use of directive, use '%s: #reverse for'", partial_token.text) + } + } } return stmt diff --git a/src/parser.cpp b/src/parser.cpp index eff5e0c6c..2cdcea417 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -3747,8 +3747,10 @@ gb_internal Ast *parse_simple_stmt(AstFile *f, u32 flags) { case Ast_TypeSwitchStmt: stmt->TypeSwitchStmt.partial = true; break; + default: + syntax_error(partial_token, "Incorrect use of directive, use '%.*s: #partial switch'", LIT(ast_token(name).string)); + break; } - syntax_error(partial_token, "Incorrect use of directive, use '#partial %.*s: switch'", LIT(ast_token(name).string)); } else if (is_reverse) { switch (stmt->kind) { case Ast_RangeStmt: @@ -5176,7 +5178,7 @@ gb_internal Ast *parse_stmt(AstFile *f) { } else if (tag == "unroll") { return parse_unrolled_for_loop(f, name); } else if (tag == "reverse") { - Ast *for_stmt = parse_for_stmt(f); + Ast *for_stmt = parse_stmt(f); if (for_stmt->kind == Ast_RangeStmt) { if (for_stmt->RangeStmt.reverse) { syntax_error(token, "#reverse already applied to a 'for in' statement");