1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

parser: improve error for prefix inc/dec statement --a/++mp["id"] (#17090)

This commit is contained in:
Makhnev Petr 2023-01-24 12:08:35 +04:00 committed by GitHub
parent 91799a1742
commit 5aad0db0f7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 76 additions and 7 deletions

View File

@ -422,6 +422,14 @@ pub fn (mut p Parser) check_expr(precedence int) !ast.Expr {
return node
}
}
.inc, .dec {
same_line_with_next := p.tok.line_nr == p.peek_tok.line_nr
next_tok_name := p.peek_tok.kind == .name
if next_tok_name && same_line_with_next {
p.prefix_inc_dec_error()
}
}
else {
if p.tok.kind == .key_struct && p.peek_tok.kind == .lcbr {
// Anonymous struct
@ -535,10 +543,33 @@ pub fn (mut p Parser) expr_with_left(left ast.Expr, precedence int, is_stmt_iden
p.tok.pos())
}
}
if p.tok.kind in [.inc, .dec] && p.prev_tok.line_nr != p.tok.line_nr {
inc_dec_tok := p.tok.kind in [.inc, .dec]
same_line_with_prev := p.tok.line_nr == p.prev_tok.line_nr
same_line_with_next := p.tok.line_nr == p.peek_tok.line_nr
next_tok_name := p.peek_tok.kind == .name
// 1. name
// 2. ++
// ^^ current token
if inc_dec_tok && !same_line_with_prev && !next_tok_name {
p.error_with_pos('${p.tok} must be on the same line as the previous token',
p.tok.pos())
}
// a++ a--
// ^^ current token
// a[i]++ a--
// ^^ current token
// check if op attached to previous name
prev_name_or_rsbr := p.prev_tok.kind in [.name, .rsbr]
// 1. ++name
// ^^ current token
if inc_dec_tok && same_line_with_next && next_tok_name
&& (!prev_name_or_rsbr || !same_line_with_prev) {
p.prefix_inc_dec_error()
}
if mut node is ast.IndexExpr {
node.recursive_mapset_is_setter(true)
}
@ -708,3 +739,17 @@ fn (mut p Parser) recast_as_pointer(mut cast_expr ast.CastExpr, pos token.Pos) {
cast_expr.typname = p.table.sym(cast_expr.typ).name
cast_expr.pos = pos.extend(cast_expr.pos)
}
// prefix_inc_dec_error reports an error for a prefix increment or decrement.
// prefix increments and decrements are not allowed in V.
fn (mut p Parser) prefix_inc_dec_error() {
op := if p.tok.kind == .inc { '++' } else { '--' }
op_pos := p.tok.pos()
p.next()
expr := p.expr(0) // expression `mp["name"]` after `--` in `--mp["name"]`
full_expr_pos := op_pos.extend(expr.pos()) // position of full `--mp["name"]`
p.error_with_pos('prefix `${op}${expr}` is unsupported, use suffix form `${expr}${op}`',
full_expr_pos)
}

View File

@ -1,5 +0,0 @@
vlib/v/parser/tests/postfix_inc.vv:3:1: error: token `++` must be on the same line as the previous token
1 | mut v := 4
2 | _ = v
3 | ++v
| ~~

View File

@ -0,0 +1,5 @@
vlib/v/parser/tests/prefix_dec_bare_err.vv:3:1: error: token `--` must be on the same line as the previous token
1 | mut v := 4
2 | _ = v
3 | --
| ~~

View File

@ -1,3 +1,3 @@
mut v := 4
_ = v
++v
--

View File

@ -0,0 +1,5 @@
vlib/v/parser/tests/prefix_dec_err.vv:3:1: error: prefix `--v` is unsupported, use suffix form `v--`
1 | mut v := 4
2 | _ = v
3 | --v
| ~~~

View File

@ -0,0 +1,3 @@
mut v := 4
_ = v
--v

View File

@ -0,0 +1,5 @@
vlib/v/parser/tests/prefix_dec_expr_err.vv:3:9: error: prefix `--v` is unsupported, use suffix form `v--`
1 | mut v := 4
2 | _ = v
3 | println(--v)
| ~~~

View File

@ -0,0 +1,3 @@
mut v := 4
_ = v
println(--v)

View File

@ -0,0 +1,5 @@
vlib/v/parser/tests/prefix_inc_err.vv:3:1: error: prefix `--mp['a']` is unsupported, use suffix form `mp['a']--`
1 | mut mp := map[string]int{}
2 | mp["a"] = 1
3 | --mp["a"]
| ~~~~~~~~~

View File

@ -0,0 +1,3 @@
mut mp := map[string]int{}
mp["a"] = 1
--mp["a"]