Skip to content

Commit

Permalink
parser: improve token detection and error messages for unexpected EOF…
Browse files Browse the repository at this point in the history
…s, add tests (#21110)
  • Loading branch information
ttytm committed Mar 27, 2024
1 parent df9a815 commit 8997c51
Show file tree
Hide file tree
Showing 14 changed files with 76 additions and 9 deletions.
2 changes: 1 addition & 1 deletion vlib/v/checker/tests/like_operator_outside_orm_error.out
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
vlib/v/checker/tests/like_operator_outside_orm_error.vv:4:15: error: unexpected name `like`, expecting `,`
vlib/v/checker/tests/like_operator_outside_orm_error.vv:4:15: error: only `c`, `r`, `js` are recognized string prefixes, but you tried to use `like`
2 | name := 'Luke'
3 |
4 | println(name like 'L%')
Expand Down
29 changes: 21 additions & 8 deletions vlib/v/parser/fn.v
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ fn (mut p Parser) call_expr(language ast.Language, mod string) ast.CallExpr {
'JS.${name}'
} else if language == .wasm {
'WASM.${name}'
} else if mod.len > 0 {
} else if mod != '' {
'${mod}.${name}'
} else {
name
Expand Down Expand Up @@ -52,8 +52,23 @@ fn (mut p Parser) call_expr(language ast.Language, mod string) ast.CallExpr {
}
p.check(.lpar)
args := p.call_args()
if p.tok.kind != .rpar {
params := p.table.fns[fn_name] or { unsafe { p.table.fns['${p.mod}.${fn_name}'] } }.params
if args.len < params.len && p.prev_tok.kind != .comma {
p.unexpected_with_pos(p.prev_tok.pos(), expecting: '`,`')
} else if args.len > params.len {
ok_arg_pos := (args[params.len - 1] or { args[0] }).pos
pos := token.Pos{
...ok_arg_pos
col: ok_arg_pos.col + ok_arg_pos.len
}
p.unexpected_with_pos(pos.extend(p.tok.pos()), expecting: '`)`')
} else {
p.unexpected_with_pos(p.prev_tok.pos(), expecting: '`)`')
}
}
last_pos := p.tok.pos()
p.check(.rpar)
p.next()
mut pos := first_pos.extend(last_pos)
mut or_stmts := []ast.Stmt{} // TODO: remove unnecessary allocations by just using .absent
mut or_pos := p.tok.pos()
Expand Down Expand Up @@ -104,11 +119,9 @@ fn (mut p Parser) call_args() []ast.CallArg {
p.inside_call_args = prev_inside_call_args
}
mut args := []ast.CallArg{}
start_pos := p.tok.pos()
for p.tok.kind != .rpar {
for p.tok.kind != .rpar && p.tok.kind != .comma {
if p.tok.kind == .eof {
p.error_with_pos('unexpected eof reached, while parsing call argument', start_pos)
return []
return args
}
is_shared := p.tok.kind == .key_shared
is_atomic := p.tok.kind == .key_atomic
Expand Down Expand Up @@ -149,8 +162,8 @@ fn (mut p Parser) call_args() []ast.CallArg {
comments: comments
pos: pos
}
if p.tok.kind != .rpar {
p.check(.comma)
if p.tok.kind == .comma {
p.next()
}
}
return args
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
vlib/v/parser/tests/fn_call_unexpected_eof_comma_multi_arg_err.vv:5:14: error: unexpected eof, expecting `,`
3 | fn foo(i i64, s string) {}
4 |
5 | foo(time.now()
| ^
6 |
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import time

fn foo(i i64, s string) {}

foo(time.now()

Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
vlib/v/parser/tests/fn_call_unexpected_eof_rpar_after_fn_arg_err.vv:3:36: error: unexpected eof, expecting `)`
1 | import os
2 |
3 | println(os.file_last_mod_unix('x.v')
| ^
4 |
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import os

println(os.file_last_mod_unix('x.v')

4 changes: 4 additions & 0 deletions vlib/v/parser/tests/fn_call_unexpected_eof_rpar_err.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
vlib/v/parser/tests/fn_call_unexpected_eof_rpar_err.vv:1:12: error: unexpected eof, expecting `)`
1 | println('a',
| ^
2 |
2 changes: 2 additions & 0 deletions vlib/v/parser/tests/fn_call_unexpected_eof_rpar_err.vv
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
println('a',

Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
vlib/v/parser/tests/fn_call_unexpected_eof_rpar_multi_arg_too_many_err.vv:5:22: error: unexpected eof, expecting `)`
3 | fn foo(i i64, s string) {}
4 |
5 | foo(time.now(), 'foo',
| ^
6 |
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import time

fn foo(i i64, s string) {}

foo(time.now(), 'foo',

Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
vlib/v/parser/tests/fn_call_unexpected_eof_rpar_multi_line_err.vv:1:14: error: unexpected eof, expecting `)`
1 | println('foo' bar
| ~~~~
2 | println('baz')
3 |
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
println('foo' bar
println('baz')

Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
vlib/v/parser/tests/fn_call_unexpected_eof_rpar_too_many_err.vv:1:12: error: unexpected eof, expecting `)`
1 | println('a', 'b'
| ~~~~~
2 |
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
println('a', 'b'

0 comments on commit 8997c51

Please sign in to comment.