From 3d139740db63f771dfc4197a69f557f3418af820 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aksh=C4=81nsh?= <53227127+akshanshbhatt@users.noreply.github.com> Date: Sat, 30 Jul 2022 13:08:56 +0530 Subject: [PATCH 1/4] Initial support for parsing `*` in function defintion. --- src/lpython/parser/parser.yy | 7 +++++++ src/lpython/parser/semantics.h | 16 ++++++++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/lpython/parser/parser.yy b/src/lpython/parser/parser.yy index d9faa67c0c..42bd03ad7d 100644 --- a/src/lpython/parser/parser.yy +++ b/src/lpython/parser/parser.yy @@ -615,6 +615,13 @@ parameter_list_starargs | defparameter_list "," "/" "," defparameter_list "," "*" parameter "," defparameter_list "," "**" parameter { $$ = STAR_ARGS_20($1, $5, $8, $10, $13, @$); } + | defparameter_list "," "/" "," "*" "," defparameter_list { + $$ = STAR_ARGS_21($1, $7, @$); } + | defparameter_list "," "/" "," defparameter_list "," + "*" "," defparameter_list { $$ = STAR_ARGS_22($1, $5, $9, @$); } + | defparameter_list "," "*" "," defparameter_list { + $$ = STAR_ARGS_23($1, $5, @$); } + | "*" "," defparameter_list { $$ = STAR_ARGS_24($3, @$); } ; parameter_list_opt diff --git a/src/lpython/parser/semantics.h b/src/lpython/parser/semantics.h index ecd19c5f3a..e4ebfea209 100644 --- a/src/lpython/parser/semantics.h +++ b/src/lpython/parser/semantics.h @@ -397,6 +397,8 @@ static inline Args *FUNC_ARGS(Allocator &al, Location &l, Args *r = al.allocate(); Vec defaults; defaults.reserve(al, 4); + Vec kw_defaults; + kw_defaults.reserve(al, 4); FUNC_ARGS_(posonlyargs); FUNC_ARGS_(args); @@ -413,8 +415,8 @@ static inline Args *FUNC_ARGS(Allocator &al, Location &l, r->arguments.n_vararg = _m_vararg.n; r->arguments.m_kwonlyargs = _m_kwonlyargs.p; r->arguments.n_kwonlyargs = _m_kwonlyargs.n; - r->arguments.m_kw_defaults = nullptr; - r->arguments.n_kw_defaults = 0; + r->arguments.m_kw_defaults = kw_defaults.p; + r->arguments.n_kw_defaults = kw_defaults.n; r->arguments.m_kwarg = _m_kwarg.p; r->arguments.n_kwarg = _m_kwarg.n; r->arguments.m_defaults = defaults.p; @@ -498,6 +500,16 @@ static inline void ADD_TYPE_COMMENT_(LFortran::Parser &p, Location l, FUNC_ARGS(p.m_a, l, posonlyargs.p, posonlyargs.n, \ args.p, args.n, ARG2LIST(p.m_a, vararg), 1, \ kwonlyargs.p, kwonlyargs.n, ARG2LIST(p.m_a, kwarg), 1) +#define STAR_ARGS_21(posonlyargs, kwonlyargs, l) FUNC_ARGS(p.m_a, l, \ + posonlyargs.p, posonlyargs.n, nullptr, 0, nullptr, 0, \ + kwonlyargs.p, kwonlyargs.n, nullptr, 0) +#define STAR_ARGS_22(posonlyargs, args, kwonlyargs, l) FUNC_ARGS(p.m_a, l, \ + posonlyargs.p, posonlyargs.n, args.p, args.n, nullptr, 0, \ + kwonlyargs.p, kwonlyargs.n, nullptr, 0) +#define STAR_ARGS_23(args, kwonlyargs, l) FUNC_ARGS(p.m_a, l, nullptr, 0, \ + args.p, args.n, nullptr, 0, kwonlyargs.p, kwonlyargs.n, nullptr, 0) +#define STAR_ARGS_24(kwonlyargs, l) FUNC_ARGS(p.m_a, l, nullptr, 0, \ + nullptr, 0, nullptr, 0, kwonlyargs.p, kwonlyargs.n, nullptr, 0) #define FUNC_ARG_LIST_01(args, l) FUNC_ARGS(p.m_a, l, nullptr, 0, \ args.p, args.n, nullptr, 0, nullptr, 0, nullptr, 0) From 78946c0672172e3c359b860d53f75f30191ada79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aksh=C4=81nsh?= <53227127+akshanshbhatt@users.noreply.github.com> Date: Sat, 30 Jul 2022 13:09:20 +0530 Subject: [PATCH 2/4] Add tests and update refs. --- tests/parser/function_def3.py | 25 +++++++++++++++++++ .../ast_new-function_def3-f66064a.json | 4 +-- .../ast_new-function_def3-f66064a.stdout | 2 +- 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/tests/parser/function_def3.py b/tests/parser/function_def3.py index d7c1de9746..4eca08a908 100644 --- a/tests/parser/function_def3.py +++ b/tests/parser/function_def3.py @@ -47,3 +47,28 @@ def test_01(a, # type:int def test_02(a, # type:int b): pass + + +# TODO: Make the commented out example work. + +def quantiles(dist, /, *, n): + ... + +# def quantiles(dist, /, *, n=4, method='exclusive'): +# ... + +def func(self, param1, param2, /, param3, *, param4, param5): + ... + +# def func(self, param1, param2, /, param3=7, *, param4, param5): +# ... + +# def func(self, param1, param2, /, param3, param3_1=2, *, param4, param5): +# ... + + +def add(a, b, *, c, d): + ... + +def func(*, param4, param5): + ... diff --git a/tests/reference/ast_new-function_def3-f66064a.json b/tests/reference/ast_new-function_def3-f66064a.json index 45b3780547..c18b15d11e 100644 --- a/tests/reference/ast_new-function_def3-f66064a.json +++ b/tests/reference/ast_new-function_def3-f66064a.json @@ -2,11 +2,11 @@ "basename": "ast_new-function_def3-f66064a", "cmd": "lpython --show-ast --new-parser --no-color {infile} -o {outfile}", "infile": "tests/parser/function_def3.py", - "infile_hash": "92f1995802c2cf446ff865c20616ac65d9c3bd2c52357710d970db4f", + "infile_hash": "79fb58198269d957ba2c41c73e063be2ea15ec7aacc1e71c01a52bc9", "outfile": null, "outfile_hash": null, "stdout": "ast_new-function_def3-f66064a.stdout", - "stdout_hash": "05191d8dc81986b7c1eec58c9415d3a78e08543fc621fb873afbd6f1", + "stdout_hash": "cf8836b917795c14543a318aeb2a1d7546d9d0807efd50ca80c4d9ab", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/ast_new-function_def3-f66064a.stdout b/tests/reference/ast_new-function_def3-f66064a.stdout index 61d85ac014..69851c906d 100644 --- a/tests/reference/ast_new-function_def3-f66064a.stdout +++ b/tests/reference/ast_new-function_def3-f66064a.stdout @@ -1 +1 @@ -(Module [(FunctionDef main0 ([] [(i () ())] [] [] [] [] []) [(Pass)] [] () ()) (FunctionDef example ([] [(text () ()) (width () ()) (fill_char () ())] [] [] [] [] [(ConstantInt 80 ()) (ConstantStr "-" ())]) [(Return ())] [] () "(...) -> str") (Expr (Call (Name example Load) [(Name text Load)] [(width (ConstantInt 80 ())) (fill_char (ConstantStr "-" ()))])) (FunctionDef test_1 ([] [(x () ())] [] [] [] [] []) [(Pass)] [] () ()) (FunctionDef test_2 ([] [(y () ())] [] [] [] [] []) [(Pass)] [] () ()) (FunctionDef func ([] [(a () "str") (b () "int") (c (Name str Load) "str")] [] [] [] [] [(ConstantInt 80 ()) (ConstantStr "-" ())]) [(Pass)] [] () ()) (FunctionDef abc ([] [(a () ()) (b () "int") (c () "list[str]")] [] [] [] [] [(List [(ConstantStr "-" ())] Load)]) [(Return ())] [] () "(...) -> str") (FunctionDef test_01 ([] [(a () "int") (b () ())] [] [] [] [] [(ConstantInt 0 ())]) [(Pass)] [] () ()) (FunctionDef test_02 ([] [(a () "int") (b () ())] [] [] [] [] []) [(Pass)] [] () ())] [(TypeIgnore 0 "[misc]") (TypeIgnore 0 "")]) +(Module [(FunctionDef main0 ([] [(i () ())] [] [] [] [] []) [(Pass)] [] () ()) (FunctionDef example ([] [(text () ()) (width () ()) (fill_char () ())] [] [] [] [] [(ConstantInt 80 ()) (ConstantStr "-" ())]) [(Return ())] [] () "(...) -> str") (Expr (Call (Name example Load) [(Name text Load)] [(width (ConstantInt 80 ())) (fill_char (ConstantStr "-" ()))])) (FunctionDef test_1 ([] [(x () ())] [] [] [] [] []) [(Pass)] [] () ()) (FunctionDef test_2 ([] [(y () ())] [] [] [] [] []) [(Pass)] [] () ()) (FunctionDef func ([] [(a () "str") (b () "int") (c (Name str Load) "str")] [] [] [] [] [(ConstantInt 80 ()) (ConstantStr "-" ())]) [(Pass)] [] () ()) (FunctionDef abc ([] [(a () ()) (b () "int") (c () "list[str]")] [] [] [] [] [(List [(ConstantStr "-" ())] Load)]) [(Return ())] [] () "(...) -> str") (FunctionDef test_01 ([] [(a () "int") (b () ())] [] [] [] [] [(ConstantInt 0 ())]) [(Pass)] [] () ()) (FunctionDef test_02 ([] [(a () "int") (b () ())] [] [] [] [] []) [(Pass)] [] () ()) (FunctionDef quantiles ([(dist () ())] [] [] [(n () ())] [] [] []) [(Expr (ConstantEllipsis ()))] [] () ()) (FunctionDef func ([(self () ()) (param1 () ()) (param2 () ())] [(param3 () ())] [] [(param4 () ()) (param5 () ())] [] [] []) [(Expr (ConstantEllipsis ()))] [] () ()) (FunctionDef add ([] [(a () ()) (b () ())] [] [(c () ()) (d () ())] [] [] []) [(Expr (ConstantEllipsis ()))] [] () ()) (FunctionDef func ([] [] [] [(param4 () ()) (param5 () ())] [] [] []) [(Expr (ConstantEllipsis ()))] [] () ())] [(TypeIgnore 0 "[misc]") (TypeIgnore 0 "")]) From 15045ae4c0595501a20cf018ad8afb4c0ee4daa0 Mon Sep 17 00:00:00 2001 From: Thirumalai-Shaktivel Date: Sun, 31 Jul 2022 11:28:34 +0530 Subject: [PATCH 3/4] Store the kw_default values separately --- src/lpython/parser/semantics.h | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/lpython/parser/semantics.h b/src/lpython/parser/semantics.h index e4ebfea209..f92eda59e4 100644 --- a/src/lpython/parser/semantics.h +++ b/src/lpython/parser/semantics.h @@ -376,14 +376,16 @@ Arg** ARG2LIST(Allocator &al, Arg *x) { return v; } -#define FUNC_ARGS_(x) \ +#define FUNC_ARGS_(x, kw) \ Vec _m_##x; \ _m_##x.reserve(al, 4); \ if(n_##x > 0) { \ for(size_t i = 0; i < n_##x; i++) { \ _m_##x.push_back(al, m_##x[i]->_arg); \ - if(m_##x[i]->default_value) { \ + if(m_##x[i]->default_value && !kw) { \ defaults.push_back(al, m_##x[i]->defaults); \ + } else if (m_##x[i]->default_value){ \ + kw_defaults.push_back(al, m_##x[i]->defaults); \ } \ } \ } @@ -400,11 +402,11 @@ static inline Args *FUNC_ARGS(Allocator &al, Location &l, Vec kw_defaults; kw_defaults.reserve(al, 4); - FUNC_ARGS_(posonlyargs); - FUNC_ARGS_(args); - FUNC_ARGS_(vararg); - FUNC_ARGS_(kwonlyargs); - FUNC_ARGS_(kwarg); + FUNC_ARGS_(posonlyargs, false); + FUNC_ARGS_(args, false); + FUNC_ARGS_(vararg, false); + FUNC_ARGS_(kwonlyargs, true); + FUNC_ARGS_(kwarg, true); r->arguments.loc = l; r->arguments.m_posonlyargs = _m_posonlyargs.p; @@ -701,7 +703,7 @@ static inline ast_t *PREFIX_STRING(Allocator &al, Location &l, char *prefix, cha for (size_t i = 0; i < strlen(prefix); i++) { prefix[i] = tolower(prefix[i]); } - if (strcmp(prefix, "f") == 0 || strcmp(prefix, "fr") == 0 + if (strcmp(prefix, "f") == 0 || strcmp(prefix, "fr") == 0 || strcmp(prefix, "rf") == 0) { std::string str = std::string(s); std::string s1 = "\""; @@ -746,7 +748,7 @@ static inline ast_t *PREFIX_STRING(Allocator &al, Location &l, char *prefix, cha } } tmp = make_JoinedStr_t(al, l, exprs.p, exprs.size()); - } else if (strcmp(prefix, "b") == 0 || strcmp(prefix, "br") == 0 + } else if (strcmp(prefix, "b") == 0 || strcmp(prefix, "br") == 0 || strcmp(prefix, "rb") == 0) { std::string str = std::string(s); size_t start_pos = 0; From 8cd2b17002cc8fa2750e218fa694eeddd833b3fd Mon Sep 17 00:00:00 2001 From: Thirumalai-Shaktivel Date: Sun, 31 Jul 2022 11:29:57 +0530 Subject: [PATCH 4/4] Update tests --- tests/parser/function_def3.py | 15 ++++++--------- .../reference/ast_new-function_def3-f66064a.json | 4 ++-- .../ast_new-function_def3-f66064a.stdout | 2 +- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/tests/parser/function_def3.py b/tests/parser/function_def3.py index 4eca08a908..a1bdcde756 100644 --- a/tests/parser/function_def3.py +++ b/tests/parser/function_def3.py @@ -48,23 +48,20 @@ def test_02(a, # type:int b): pass - -# TODO: Make the commented out example work. - def quantiles(dist, /, *, n): ... -# def quantiles(dist, /, *, n=4, method='exclusive'): -# ... +def quantiles(dist, /, *, n=4, method='exclusive'): + ... def func(self, param1, param2, /, param3, *, param4, param5): ... -# def func(self, param1, param2, /, param3=7, *, param4, param5): -# ... +def func(self, param1, param2, /, param3=7, *, param4, param5): + ... -# def func(self, param1, param2, /, param3, param3_1=2, *, param4, param5): -# ... +def func(self, param1, param2, /, param3, param3_1=2, *, param4, param5): + ... def add(a, b, *, c, d): diff --git a/tests/reference/ast_new-function_def3-f66064a.json b/tests/reference/ast_new-function_def3-f66064a.json index c18b15d11e..7f6ff04f02 100644 --- a/tests/reference/ast_new-function_def3-f66064a.json +++ b/tests/reference/ast_new-function_def3-f66064a.json @@ -2,11 +2,11 @@ "basename": "ast_new-function_def3-f66064a", "cmd": "lpython --show-ast --new-parser --no-color {infile} -o {outfile}", "infile": "tests/parser/function_def3.py", - "infile_hash": "79fb58198269d957ba2c41c73e063be2ea15ec7aacc1e71c01a52bc9", + "infile_hash": "b5e4acc3d99fc5138d53737183c77f69cc9233435673ff1119cb21df", "outfile": null, "outfile_hash": null, "stdout": "ast_new-function_def3-f66064a.stdout", - "stdout_hash": "cf8836b917795c14543a318aeb2a1d7546d9d0807efd50ca80c4d9ab", + "stdout_hash": "45c49bce6580785f59584280023443fcd850c772c5fe6bd2ba414b7b", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/ast_new-function_def3-f66064a.stdout b/tests/reference/ast_new-function_def3-f66064a.stdout index 69851c906d..46f49ddb59 100644 --- a/tests/reference/ast_new-function_def3-f66064a.stdout +++ b/tests/reference/ast_new-function_def3-f66064a.stdout @@ -1 +1 @@ -(Module [(FunctionDef main0 ([] [(i () ())] [] [] [] [] []) [(Pass)] [] () ()) (FunctionDef example ([] [(text () ()) (width () ()) (fill_char () ())] [] [] [] [] [(ConstantInt 80 ()) (ConstantStr "-" ())]) [(Return ())] [] () "(...) -> str") (Expr (Call (Name example Load) [(Name text Load)] [(width (ConstantInt 80 ())) (fill_char (ConstantStr "-" ()))])) (FunctionDef test_1 ([] [(x () ())] [] [] [] [] []) [(Pass)] [] () ()) (FunctionDef test_2 ([] [(y () ())] [] [] [] [] []) [(Pass)] [] () ()) (FunctionDef func ([] [(a () "str") (b () "int") (c (Name str Load) "str")] [] [] [] [] [(ConstantInt 80 ()) (ConstantStr "-" ())]) [(Pass)] [] () ()) (FunctionDef abc ([] [(a () ()) (b () "int") (c () "list[str]")] [] [] [] [] [(List [(ConstantStr "-" ())] Load)]) [(Return ())] [] () "(...) -> str") (FunctionDef test_01 ([] [(a () "int") (b () ())] [] [] [] [] [(ConstantInt 0 ())]) [(Pass)] [] () ()) (FunctionDef test_02 ([] [(a () "int") (b () ())] [] [] [] [] []) [(Pass)] [] () ()) (FunctionDef quantiles ([(dist () ())] [] [] [(n () ())] [] [] []) [(Expr (ConstantEllipsis ()))] [] () ()) (FunctionDef func ([(self () ()) (param1 () ()) (param2 () ())] [(param3 () ())] [] [(param4 () ()) (param5 () ())] [] [] []) [(Expr (ConstantEllipsis ()))] [] () ()) (FunctionDef add ([] [(a () ()) (b () ())] [] [(c () ()) (d () ())] [] [] []) [(Expr (ConstantEllipsis ()))] [] () ()) (FunctionDef func ([] [] [] [(param4 () ()) (param5 () ())] [] [] []) [(Expr (ConstantEllipsis ()))] [] () ())] [(TypeIgnore 0 "[misc]") (TypeIgnore 0 "")]) +(Module [(FunctionDef main0 ([] [(i () ())] [] [] [] [] []) [(Pass)] [] () ()) (FunctionDef example ([] [(text () ()) (width () ()) (fill_char () ())] [] [] [] [] [(ConstantInt 80 ()) (ConstantStr "-" ())]) [(Return ())] [] () "(...) -> str") (Expr (Call (Name example Load) [(Name text Load)] [(width (ConstantInt 80 ())) (fill_char (ConstantStr "-" ()))])) (FunctionDef test_1 ([] [(x () ())] [] [] [] [] []) [(Pass)] [] () ()) (FunctionDef test_2 ([] [(y () ())] [] [] [] [] []) [(Pass)] [] () ()) (FunctionDef func ([] [(a () "str") (b () "int") (c (Name str Load) "str")] [] [] [] [] [(ConstantInt 80 ()) (ConstantStr "-" ())]) [(Pass)] [] () ()) (FunctionDef abc ([] [(a () ()) (b () "int") (c () "list[str]")] [] [] [] [] [(List [(ConstantStr "-" ())] Load)]) [(Return ())] [] () "(...) -> str") (FunctionDef test_01 ([] [(a () "int") (b () ())] [] [] [] [] [(ConstantInt 0 ())]) [(Pass)] [] () ()) (FunctionDef test_02 ([] [(a () "int") (b () ())] [] [] [] [] []) [(Pass)] [] () ()) (FunctionDef quantiles ([(dist () ())] [] [] [(n () ())] [] [] []) [(Expr (ConstantEllipsis ()))] [] () ()) (FunctionDef quantiles ([(dist () ())] [] [] [(n () ()) (method () ())] [(ConstantInt 4 ()) (ConstantStr "exclusive" ())] [] []) [(Expr (ConstantEllipsis ()))] [] () ()) (FunctionDef func ([(self () ()) (param1 () ()) (param2 () ())] [(param3 () ())] [] [(param4 () ()) (param5 () ())] [] [] []) [(Expr (ConstantEllipsis ()))] [] () ()) (FunctionDef func ([(self () ()) (param1 () ()) (param2 () ())] [(param3 () ())] [] [(param4 () ()) (param5 () ())] [] [] [(ConstantInt 7 ())]) [(Expr (ConstantEllipsis ()))] [] () ()) (FunctionDef func ([(self () ()) (param1 () ()) (param2 () ())] [(param3 () ()) (param3_1 () ())] [] [(param4 () ()) (param5 () ())] [] [] [(ConstantInt 2 ())]) [(Expr (ConstantEllipsis ()))] [] () ()) (FunctionDef add ([] [(a () ()) (b () ())] [] [(c () ()) (d () ())] [] [] []) [(Expr (ConstantEllipsis ()))] [] () ()) (FunctionDef func ([] [] [] [(param4 () ()) (param5 () ())] [] [] []) [(Expr (ConstantEllipsis ()))] [] () ())] [(TypeIgnore 0 "[misc]") (TypeIgnore 0 "")])