mirror of
https://github.com/odin-lang/Odin.git
synced 2026-06-08 11:34:20 +00:00
Improve parsing for label: #reverse for and label: #partial switch
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user