From b8d4fb4030eaa4386883e6384d021c4a9acefa9d Mon Sep 17 00:00:00 2001 From: yuyi Date: Sat, 12 Oct 2024 17:27:14 +0800 Subject: [PATCH] parser: implement fn name using keyword --- vlib/v/parser/expr.v | 70 +++++++++++++------ vlib/v/parser/fn.v | 2 +- vlib/v/parser/tests/unexpected_keyword.out | 7 -- vlib/v/parser/tests/unexpected_keyword.vv | 12 ---- vlib/v/tests/fns/fn_name_using_keyword_test.v | 35 ++++++++++ 5 files changed, 85 insertions(+), 41 deletions(-) delete mode 100644 vlib/v/parser/tests/unexpected_keyword.out delete mode 100644 vlib/v/parser/tests/unexpected_keyword.vv create mode 100644 vlib/v/tests/fns/fn_name_using_keyword_test.v diff --git a/vlib/v/parser/expr.v b/vlib/v/parser/expr.v index ae86e5e3a0dd03..a554bc8d813b84 100644 --- a/vlib/v/parser/expr.v +++ b/vlib/v/parser/expr.v @@ -48,13 +48,17 @@ fn (mut p Parser) check_expr(precedence int) !ast.Expr { // Prefix match p.tok.kind { .key_mut, .key_shared, .key_atomic, .key_static, .key_volatile { - ident := p.ident(ast.Language.v) - node = ident - if p.peek_tok.kind != .assign && (p.inside_if_cond || p.inside_match) { - p.mark_var_as_used(ident.name) + if p.peek_tok.kind in [.lpar, .lsbr] && p.peek_tok.is_next_to(p.tok) { + node = p.call_expr(p.language, p.mod) + } else { + ident := p.ident(ast.Language.v) + node = ident + if p.peek_tok.kind != .assign && (p.inside_if_cond || p.inside_match) { + p.mark_var_as_used(ident.name) + } + p.add_defer_var(ident) + p.is_stmt_ident = is_stmt_ident } - p.add_defer_var(ident) - p.is_stmt_ident = is_stmt_ident } .name, .question { if p.peek_tok.kind == .name && p.tok.lit == 'sql' { @@ -131,28 +135,44 @@ fn (mut p Parser) check_expr(precedence int) !ast.Expr { } } .key_go, .key_spawn { - if (p.pref.use_coroutines || p.pref.is_fmt) && p.tok.kind == .key_go { - mut go_expr := p.go_expr() - go_expr.is_expr = true - node = go_expr + if p.peek_tok.kind in [.lpar, .lsbr] && p.peek_tok.is_next_to(p.tok) { + node = p.call_expr(p.language, p.mod) } else { - mut spawn_expr := p.spawn_expr() - spawn_expr.is_expr = true - node = spawn_expr + if (p.pref.use_coroutines || p.pref.is_fmt) && p.tok.kind == .key_go { + mut go_expr := p.go_expr() + go_expr.is_expr = true + node = go_expr + } else { + mut spawn_expr := p.spawn_expr() + spawn_expr.is_expr = true + node = spawn_expr + } } } .key_true, .key_false { - node = ast.BoolLiteral{ - val: p.tok.kind == .key_true - pos: p.tok.pos() + if p.peek_tok.kind in [.lpar, .lsbr] && p.peek_tok.is_next_to(p.tok) { + node = p.call_expr(p.language, p.mod) + } else { + node = ast.BoolLiteral{ + val: p.tok.kind == .key_true + pos: p.tok.pos() + } + p.next() } - p.next() } .key_match { - node = p.match_expr() + if p.peek_tok.kind in [.lpar, .lsbr] && p.peek_tok.is_next_to(p.tok) { + node = p.call_expr(p.language, p.mod) + } else { + node = p.match_expr() + } } .key_select { - node = p.select_expr() + if p.peek_tok.kind in [.lpar, .lsbr] && p.peek_tok.is_next_to(p.tok) { + node = p.call_expr(p.language, p.mod) + } else { + node = p.select_expr() + } } .key_nil { node = ast.Nil{ @@ -177,7 +197,11 @@ fn (mut p Parser) check_expr(precedence int) !ast.Expr { } } .key_if { - node = p.if_expr(false) + if p.peek_tok.kind in [.lpar, .lsbr] && p.peek_tok.is_next_to(p.tok) { + node = p.call_expr(p.language, p.mod) + } else { + node = p.if_expr(false) + } } .key_unsafe { // unsafe { @@ -205,7 +229,11 @@ fn (mut p Parser) check_expr(precedence int) !ast.Expr { } } .key_lock, .key_rlock { - node = p.lock_expr() + if p.peek_tok.kind in [.lpar, .lsbr] && p.peek_tok.is_next_to(p.tok) { + node = p.call_expr(p.language, p.mod) + } else { + node = p.lock_expr() + } } .lsbr { if p.expecting_type { diff --git a/vlib/v/parser/fn.v b/vlib/v/parser/fn.v index cd2398e4d5f3d4..579c27a194bfc0 100644 --- a/vlib/v/parser/fn.v +++ b/vlib/v/parser/fn.v @@ -316,7 +316,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl { mut type_sym := p.table.sym(rec.typ) mut name_pos := p.tok.pos() mut static_type_pos := p.tok.pos() - if p.tok.kind == .name { + if p.tok.kind == .name || is_ident_name(p.tok.lit) { mut check_name := '' // TODO: high order fn is_static_type_method = p.tok.lit.len > 0 && p.tok.lit[0].is_capital() diff --git a/vlib/v/parser/tests/unexpected_keyword.out b/vlib/v/parser/tests/unexpected_keyword.out deleted file mode 100644 index 08adaf7afb77f8..00000000000000 --- a/vlib/v/parser/tests/unexpected_keyword.out +++ /dev/null @@ -1,7 +0,0 @@ -vlib/v/parser/tests/unexpected_keyword.vv:5:12: error: expecting method name - 3 | } - 4 | - 5 | fn (s Abc) import(name string) { - | ~~~~~~ - 6 | println(name) - 7 | } diff --git a/vlib/v/parser/tests/unexpected_keyword.vv b/vlib/v/parser/tests/unexpected_keyword.vv deleted file mode 100644 index 4d603034d6d288..00000000000000 --- a/vlib/v/parser/tests/unexpected_keyword.vv +++ /dev/null @@ -1,12 +0,0 @@ -struct Abc { - x int -} - -fn (s Abc) import(name string) { - println(name) -} - -fn main() { - s := Abc{} - s.import('lib') -} diff --git a/vlib/v/tests/fns/fn_name_using_keyword_test.v b/vlib/v/tests/fns/fn_name_using_keyword_test.v new file mode 100644 index 00000000000000..0c8309aa3afa47 --- /dev/null +++ b/vlib/v/tests/fns/fn_name_using_keyword_test.v @@ -0,0 +1,35 @@ +struct Foo {} + +fn (f Foo) lock() int { + return 22 +} + +fn (f Foo) mut() bool { + return true +} + +fn select() bool { + return true +} + +fn lock[T](t T) T { + return t +} + +fn match() bool { + return true +} + +fn test_fn_name_using_keyword() { + f := Foo{} + assert select() + assert match() + + assert lock[int](22) == 22 + assert lock(22) == 22 + assert lock[string]('hello') == 'hello' + assert lock('hello') == 'hello' + + assert f.lock() == 22 + assert f.mut() +}