Improve error cases in core:odin/parser

This commit is contained in:
gingerBill
2021-08-04 00:23:31 +01:00
parent 57a17a708b
commit af6df7d7c9

View File

@@ -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;