From af6df7d7c91103199f8ef509f9c64677534e352f Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 4 Aug 2021 00:23:31 +0100 Subject: [PATCH] Improve error cases in core:odin/parser --- core/odin/parser/parser.odin | 55 +++++++++++++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 4 deletions(-) diff --git a/core/odin/parser/parser.odin b/core/odin/parser/parser.odin index 1d814f608..db3d84d2b 100644 --- a/core/odin/parser/parser.odin +++ b/core/odin/parser/parser.odin @@ -392,6 +392,30 @@ allow_token :: proc(p: ^Parser, kind: tokenizer.Token_Kind) -> bool { return false; } +end_of_line_pos :: proc(p: ^Parser, tok: tokenizer.Token) -> tokenizer.Pos { + offset := clamp(tok.pos.offset, 0, len(p.tok.src)-1); + s := p.tok.src[offset:]; + pos := tok.pos; + pos.column -= 1; + for len(s) != 0 && s[0] != 0 && s[0] != '\n' { + s = s[1:]; + pos.column += 1; + } + return pos; +} + +expect_closing_brace_of_field_list :: proc(p: ^Parser) -> tokenizer.Token { + token := p.curr_tok; + if allow_token(p, .Close_Brace) { + return token; + } + if allow_token(p, .Semicolon) { + str := tokenizer.token_to_string(token); + error(p, end_of_line_pos(p, p.prev_tok), "expected a comma, got %s", p); + } + return expect_token(p, .Close_Brace); +} + is_blank_ident :: proc{ is_blank_ident_string, @@ -2520,7 +2544,7 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr { skip_possible_newline_for_literal(p); expect_token(p, .Open_Brace); fields, name_count = parse_field_list(p, .Close_Brace, ast.Field_Flags_Struct); - close := expect_token(p, .Close_Brace); + close := expect_closing_brace_of_field_list(p); st := ast.new(ast.Struct_Type, tok.pos, end_pos(close)); st.poly_params = poly_params; @@ -2598,7 +2622,7 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr { } } - close := expect_token(p, .Close_Brace); + close := expect_closing_brace_of_field_list(p); ut := ast.new(ast.Union_Type, tok.pos, end_pos(close)); ut.poly_params = poly_params; @@ -2620,7 +2644,7 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr { skip_possible_newline_for_literal(p); open := expect_token(p, .Open_Brace); fields := parse_elem_list(p); - close := expect_token(p, .Close_Brace); + close := expect_closing_brace_of_field_list(p); et := ast.new(ast.Enum_Type, tok.pos, end_pos(close)); et.base_type = base_type; @@ -2722,7 +2746,7 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr { expect_token(p, .Comma); constraints_string := parse_expr(p, false); allow_token(p, .Comma); - close := expect_token(p, .Close_Brace); + close := expect_closing_brace_of_field_list(p); e := ast.new(ast.Inline_Asm_Expr, tok.pos, end_pos(close)); e.tok = tok; @@ -3047,6 +3071,13 @@ parse_atom_expr :: proc(p: ^Parser, value: ^ast.Expr, lhs: bool) -> (operand: ^a loop = false; } + case .Increment, .Decrement: + if !lhs { + tok := advance_token(p); + error(p, tok.pos, "postfix '%s' operator is not supported", tok.text); + } else { + loop = false; + } } is_lhs = false; @@ -3096,6 +3127,16 @@ parse_unary_expr :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr { ue.expr = expr; return ue; + case .Increment, .Decrement: + op := advance_token(p); + error(p, op.pos, "unary '%s' operator is not supported", op.text); + expr := parse_unary_expr(p, lhs); + + ue := ast.new(ast.Unary_Expr, op.pos, expr.end); + ue.op = op; + ue.expr = expr; + return ue; + case .Period: op := advance_token(p); field := parse_ident(p); @@ -3281,6 +3322,12 @@ parse_simple_stmt :: proc(p: ^Parser, flags: Stmt_Allow_Flags) -> ^ast.Stmt { return ast.new(ast.Bad_Stmt, start_tok.pos, end_pos(p.curr_tok)); } + #partial switch op.kind { + case .Increment, .Decrement: + advance_token(p); + error(p, op.pos, "postfix '%s' statement is not supported", op.text); + } + es := ast.new(ast.Expr_Stmt, lhs[0].pos, lhs[0].end); es.expr = lhs[0]; return es;