Skip to content

Commit 395b7b3

Browse files
authored
Merge pull request lcompilers#1058 from Thirumalai-Shaktivel/func_call
Refactor Func_call `arguement_list` grammar definition
2 parents 37b1cdc + 4f6de24 commit 395b7b3

6 files changed

Lines changed: 119 additions & 90 deletions

File tree

src/lpython/parser/parser.yy

Lines changed: 40 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,6 @@ void yyerror(YYLTYPE *yyloc, LFortran::Parser &p, const std::string &msg)
180180
%type <ast> id
181181
%type <ast> expr
182182
%type <vec_ast> expr_list
183-
%type <vec_ast> func_call_expr_list
184183
%type <vec_ast> expr_list_opt
185184
%type <ast> tuple_list
186185
%type <ast> statement
@@ -240,10 +239,11 @@ void yyerror(YYLTYPE *yyloc, LFortran::Parser &p, const std::string &msg)
240239
%type <ast> async_func_def
241240
%type <ast> async_for_stmt
242241
%type <ast> async_with_stmt
243-
%type <keyword> keyword_item
244-
%type <vec_keyword> keyword_items
242+
%type <vec_kw_or_star> positional_items
243+
%type <kw_or_star> starred_and_keyword
244+
%type <vec_keyword> keywords_arguments
245245
%type <ast> function_call
246-
%type <vec_ast> call_arguement_list
246+
%type <call_arg> call_arguement_list
247247
%type <ast> primary
248248
%type <ast> while_statement
249249
%type <vec_ast> sep
@@ -714,14 +714,8 @@ function_def
714714
class_def
715715
: decorators_opt KW_CLASS id ":" body_stmts {
716716
$$ = CLASS_01($1, $3, $5, @$); }
717-
| decorators_opt KW_CLASS id "(" expr_list_opt ")" ":" body_stmts {
717+
| decorators_opt KW_CLASS id "(" call_arguement_list ")" ":" body_stmts {
718718
$$ = CLASS_02($1, $3, $5, $8, @$); }
719-
| decorators_opt KW_CLASS id "(" expr_list "," keyword_items comma_opt ")"
720-
":" body_stmts { $$ = CLASS_03($1, $3, $5, $7, $11, @$); }
721-
| decorators_opt KW_CLASS id "(" keyword_items "," expr_list ")"
722-
":" body_stmts { $$ = CLASS_03($1, $3, $7, $5, $10, @$); }
723-
| decorators_opt KW_CLASS id "(" keyword_items comma_opt ")" ":" body_stmts
724-
{ $$ = CLASS_04($1, $3, $5, $9, @$); }
725719
;
726720

727721
async_func_def
@@ -819,22 +813,6 @@ id_item
819813
| "[" id_list "," "]" { $$ = LIST(SET_EXPR_CTX_02($2, Store), @$); }
820814
;
821815

822-
keyword_item
823-
: id "=" expr { $$ = CALL_KEYWORD_01($1, $3, @$); }
824-
| "**" expr { $$ = CALL_KEYWORD_02($2, @$); }
825-
;
826-
827-
keyword_items
828-
: keyword_items "," keyword_item { $$ = $1; PLIST_ADD($$, $3); }
829-
| keyword_item { LIST_NEW($$); PLIST_ADD($$, $1); }
830-
;
831-
832-
primary
833-
: id { $$ = $1; }
834-
| string { $$ = $1; }
835-
| expr "." id { $$ = ATTRIBUTE_REF($1, $3, @$); }
836-
;
837-
838816
comp_if_items
839817
: comp_if_items KW_IF expr { $$ = $1; LIST_ADD($$, $3); }
840818
| KW_IF expr { LIST_NEW($$); LIST_ADD($$, $2); }
@@ -856,40 +834,50 @@ comp_for_items
856834
| comp_for { LIST_NEW($$); PLIST_ADD($$, $1); }
857835
;
858836

859-
func_call_expr_list
860-
: func_call_expr_list "," expr { $$ = $1; LIST_ADD($$, $3); }
861-
| func_call_expr_list "," TK_TYPE_IGNORE expr { $$ = $1; LIST_ADD($$, $4);
862-
extract_type_comment(p, @$, $3); }
863-
| expr { LIST_NEW($$); LIST_ADD($$, $1); }
837+
keywords_arguments
838+
: keywords_arguments "," "**" expr { $$ = $1;
839+
PLIST_ADD($$, CALL_EXPR_01($4, @$)); }
840+
| keywords_arguments "," id "=" expr { $$ = $1;
841+
PLIST_ADD($$, CALL_KW_01($3, $5, @$)); }
842+
| "**" expr { LIST_NEW($$); PLIST_ADD($$, CALL_EXPR_01($2, @$));}
843+
;
844+
845+
starred_and_keyword
846+
: expr { $$ = CALL_EXPR_02($1, @$); }
847+
| id "=" expr { $$ = CALL_KW_02($1, $3, @$);}
848+
;
849+
850+
positional_items
851+
: positional_items "," starred_and_keyword { $$ = $1; PLIST_ADD($$, $3); }
852+
| positional_items "," TK_TYPE_IGNORE starred_and_keyword { $$ = $1;
853+
PLIST_ADD($$, $4); extract_type_comment(p, @$, $3); }
854+
| starred_and_keyword { LIST_NEW($$); PLIST_ADD($$, $1); }
864855
;
865856

866857
call_arguement_list
867-
: %empty { LIST_NEW($$); }
868-
| func_call_expr_list type_ignore_opt { $$ = $1; }
869-
| expr comp_for_items { $$ = A2LIST(p.m_a, GENERATOR_EXPR($1, $2, @$)); }
858+
: %empty { $$ = CALL_ARG_00(); }
859+
| positional_items type_ignore_opt { $$ = CALL_ARG_01($1); }
860+
| keywords_arguments type_ignore_opt { $$ = CALL_ARG_02($1); }
861+
| positional_items "," keywords_arguments type_ignore_opt {
862+
$$ = CALL_ARG_03($1, $3); }
863+
;
864+
865+
primary
866+
: id { $$ = $1; }
867+
| string { $$ = $1; }
868+
| expr "." id { $$ = ATTRIBUTE_REF($1, $3, @$); }
870869
;
871870

872871
function_call
873872
: primary "(" call_arguement_list ")" { $$ = CALL_01($1, $3, @$); }
874-
| primary "(" func_call_expr_list "," keyword_items type_ignore_opt ")" {
875-
$$ = CALL_02($1, $3, $5, @$); }
876-
| primary "(" keyword_items "," func_call_expr_list type_ignore_opt ")" {
877-
$$ = CALL_02($1, $5, $3, @$); }
878-
| primary "(" keyword_items type_ignore_opt ")" { $$ = CALL_03($1, $3, @$); }
873+
| primary "(" expr comp_for_items ")" {
874+
$$ = CALL_02($1, A2LIST(p.m_a, GENERATOR_EXPR($3, $4, @$)), @$); }
879875
| function_call "(" call_arguement_list ")" { $$ = CALL_01($1, $3, @$); }
880-
| function_call "(" func_call_expr_list "," keyword_items type_ignore_opt ")"
881-
{ $$ = CALL_02($1, $3, $5, @$); }
882-
| function_call "(" keyword_items "," func_call_expr_list type_ignore_opt ")"
883-
{ $$ = CALL_02($1, $5, $3, @$); }
884-
| function_call "(" keyword_items type_ignore_opt ")" {
885-
$$ = CALL_03($1, $3, @$); }
876+
| function_call "(" expr comp_for_items ")" {
877+
$$ = CALL_02($1, A2LIST(p.m_a, GENERATOR_EXPR($3, $4, @$)), @$); }
886878
| subscript "(" call_arguement_list ")" { $$ = CALL_01($1, $3, @$); }
887-
| subscript "(" func_call_expr_list "," keyword_items type_ignore_opt ")" {
888-
$$ = CALL_02($1, $3, $5, @$); }
889-
| subscript "(" keyword_items "," func_call_expr_list type_ignore_opt ")" {
890-
$$ = CALL_02($1, $5, $3, @$); }
891-
| subscript "(" keyword_items type_ignore_opt ")" {
892-
$$ = CALL_03($1, $3, @$); }
879+
| subscript "(" expr comp_for_items ")" {
880+
$$ = CALL_02($1, A2LIST(p.m_a, GENERATOR_EXPR($3, $4, @$)), @$); }
893881
| "(" expr ")" "(" call_arguement_list ")" { $$ = CALL_01($2, $5, @$); }
894882
;
895883

src/lpython/parser/parser_stype.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,16 @@ struct Fn_Arg {
4343
Args_ *args;
4444
};
4545

46+
struct Kw_or_Star_Arg {
47+
LPython::AST::expr_t *star_arg;
48+
LPython::AST::keyword_t *kw_arg;
49+
};
50+
51+
struct Call_Arg {
52+
Vec<LPython::AST::expr_t*> expr;
53+
Vec<LPython::AST::keyword_t> kw;
54+
};
55+
4656
union YYSTYPE {
4757
int64_t n;
4858
double f;
@@ -73,6 +83,11 @@ union YYSTYPE {
7383
LPython::AST::keyword_t* keyword;
7484
Vec<LPython::AST::keyword_t> vec_keyword;
7585

86+
Kw_or_Star_Arg* kw_or_star;
87+
Vec<Kw_or_Star_Arg> vec_kw_or_star;
88+
89+
Call_Arg *call_arg;
90+
7691
LPython::AST::comprehension_t* comp;
7792
Vec<LPython::AST::comprehension_t> vec_comp;
7893

src/lpython/parser/semantics.h

Lines changed: 57 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ using LFortran::Arg;
2727
using LFortran::Fn_Arg;
2828
using LFortran::Args_;
2929
using LFortran::Var_Kw;
30+
using LFortran::Kw_or_Star_Arg;
31+
using LFortran::Call_Arg;
3032

3133
static inline char* name2char(const ast_t *n) {
3234
return down_cast2<Name_t>(n)->m_id;
@@ -546,32 +548,9 @@ static inline Var_Kw *VAR_KW(Allocator &al,
546548
STMTS(stmts), stmts.size(), \
547549
EXPRS(decorator), decorator.size())
548550
#define CLASS_02(decorator, id, args, stmts, l) make_ClassDef_t(p.m_a, l, \
549-
name2char(id), EXPRS(args), args.size(), nullptr, 0, \
551+
name2char(id), args->expr.p, args->expr.n, args->kw.p, args->kw.n, \
550552
STMTS(stmts), stmts.size(), \
551553
EXPRS(decorator), decorator.size())
552-
#define CLASS_03(decorator, id, args, keywords, stmts, l) \
553-
make_ClassDef_t(p.m_a, l, name2char(id), EXPRS(args), args.size(), \
554-
keywords.p, keywords.n, STMTS(stmts), stmts.size(), \
555-
EXPRS(decorator), decorator.size())
556-
#define CLASS_04(decorator, id, keywords, stmts, l) make_ClassDef_t(p.m_a, l, \
557-
name2char(id), nullptr, 0, keywords.p, keywords.n, \
558-
STMTS(stmts), stmts.size(), \
559-
EXPRS(decorator), decorator.size())
560-
#define CLASS_05(decorator, id, args, tc, stmts, l) make_ClassDef_t(p.m_a, l, \
561-
name2char(id), EXPRS(args), args.size(), nullptr, 0, \
562-
STMTS(stmts), stmts.size(), \
563-
EXPRS(decorator), decorator.size()); \
564-
extract_type_comment(p, l, tc)
565-
#define CLASS_06(decorator, id, args, keywords, tc, stmts, l) \
566-
make_ClassDef_t(p.m_a, l, name2char(id), EXPRS(args), args.size(), \
567-
keywords.p, keywords.n, STMTS(stmts), stmts.size(), \
568-
EXPRS(decorator), decorator.size()); \
569-
extract_type_comment(p, l, tc)
570-
#define CLASS_07(decorator, id, keywords, tc, stmts, l) make_ClassDef_t(p.m_a, l, \
571-
name2char(id), nullptr, 0, keywords.p, keywords.n, \
572-
STMTS(stmts), stmts.size(), \
573-
EXPRS(decorator), decorator.size()); \
574-
extract_type_comment(p, l, tc)
575554

576555
#define ASYNC_FUNCTION_01(decorator, id, args, stmts, l) \
577556
make_AsyncFunctionDef_t(p.m_a, l, name2char(id), args->arguments, \
@@ -841,14 +820,67 @@ static inline ast_t *PREFIX_STRING(Allocator &al, Location &l, char *prefix, cha
841820
return tmp;
842821
}
843822

844-
static inline keyword_t *CALL_KW(Allocator &al, Location &l,
823+
static inline keyword_t *CALL_ARG_KW(Allocator &al, Location &l,
845824
char *arg, expr_t* val) {
846825
keyword_t *r = al.allocate<keyword_t>();
847826
r->loc = l;
848827
r->m_arg = arg;
849828
r->m_value = val;
850829
return r;
851830
}
831+
#define CALL_KW_01(arg, val, l) CALL_ARG_KW(p.m_a, l, \
832+
name2char(arg), EXPR(val))
833+
#define CALL_EXPR_01(val, l) CALL_ARG_KW(p.m_a, l, nullptr, EXPR(val))
834+
835+
static inline Kw_or_Star_Arg *KW_OR_EXPR(Allocator &al,
836+
expr_t *expr, keyword_t *kw_arg) {
837+
Kw_or_Star_Arg *r = al.allocate<Kw_or_Star_Arg>();
838+
r->star_arg = expr;
839+
r->kw_arg = kw_arg;
840+
return r;
841+
}
842+
#define CALL_KW_02(id, e, l) KW_OR_EXPR(p.m_a, nullptr, CALL_KW_01(id, e, l))
843+
#define CALL_EXPR_02(e, l) KW_OR_EXPR(p.m_a, EXPR(e), nullptr)
844+
845+
static inline Call_Arg *CALL_ARG(
846+
Allocator &al,
847+
Kw_or_Star_Arg *m_expr_or_kw, size_t n_expr_or_kw,
848+
keyword_t *m_kw, size_t n_kw
849+
) {
850+
Call_Arg *r = al.allocate<Call_Arg>();
851+
Vec<expr_t*> exprs;
852+
exprs.reserve(al, n_expr_or_kw);
853+
Vec<keyword_t> kws;
854+
kws.reserve(al, n_kw);
855+
856+
for (size_t i=0; i<n_expr_or_kw; i++) {
857+
if (m_expr_or_kw[i].star_arg != nullptr) {
858+
exprs.push_back(al, m_expr_or_kw[i].star_arg);
859+
} else if (m_expr_or_kw[i].kw_arg != nullptr) {
860+
kws.push_back(al, *m_expr_or_kw[i].kw_arg);
861+
}
862+
}
863+
for (size_t i=0; i<n_kw; i++) {
864+
kws.push_back(al, m_kw[i]);
865+
}
866+
867+
r->expr.p = exprs.p;
868+
r->expr.n = exprs.n;
869+
r->kw.p = kws.p;
870+
r->kw.n = kws.n;
871+
return r;
872+
}
873+
874+
#define CALL_ARG_00() CALL_ARG(p.m_a, nullptr, 0, nullptr, 0)
875+
#define CALL_ARG_01(exprs) CALL_ARG(p.m_a, exprs.p, exprs.n, nullptr, 0)
876+
#define CALL_ARG_02(kwargs) CALL_ARG(p.m_a, nullptr, 0, kwargs.p, kwargs.n)
877+
#define CALL_ARG_03(exprs, kwargs) CALL_ARG(p.m_a, exprs.p, exprs.n, \
878+
kwargs.p, kwargs.n)
879+
880+
#define CALL_01(func, args, l) make_Call_t(p.m_a, l, \
881+
EXPR(func), args->expr.p, args->expr.n, args->kw.p, args->kw.n)
882+
#define CALL_02(func, comp, l) make_Call_t(p.m_a, l, \
883+
EXPR(func), EXPRS(comp), comp.size(), nullptr, 0)
852884

853885
static inline comprehension_t *COMP(Allocator &al, Location &l,
854886
expr_t *target, expr_t* iter, expr_t **ifs, size_t ifs_size,
@@ -862,16 +894,6 @@ static inline comprehension_t *COMP(Allocator &al, Location &l,
862894
r->m_is_async = is_async;
863895
return r;
864896
}
865-
866-
#define CALL_KEYWORD_01(arg, val, l) CALL_KW(p.m_a, l, name2char(arg), EXPR(val))
867-
#define CALL_KEYWORD_02(val, l) CALL_KW(p.m_a, l, nullptr, EXPR(val))
868-
#define CALL_01(func, args, l) make_Call_t(p.m_a, l, \
869-
EXPR(func), EXPRS(args), args.size(), nullptr, 0)
870-
#define CALL_02(func, args, keywords, l) make_Call_t(p.m_a, l, \
871-
EXPR(func), EXPRS(args), args.size(), keywords.p, keywords.size())
872-
#define CALL_03(func, keywords, l) make_Call_t(p.m_a, l, \
873-
EXPR(func), nullptr, 0, keywords.p, keywords.size())
874-
875897
#define COMP_FOR_01(target, iter, l) COMP(p.m_a, l, \
876898
EXPR(SET_EXPR_CTX_01(target, Store)), EXPR(iter), nullptr, 0, 0)
877899
#define COMP_FOR_02(target, iter, ifs, l) COMP(p.m_a, l, \

tests/parser/function_def2.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,9 @@ def test_33(a, /, b, *, c, **d):
106106
test(*x, y)
107107
test(*x, *y)
108108
test(**x, **y)
109+
test(*x, y = 1, z = 2, **a, b = 1)
110+
test(*x, **a, b = "1")
111+
test(x = 1, *y, z = 2, **a, b = "1")
109112
lp.test()
110113
lp.test(x, y)
111114
lp.test(x, y = 1, z = '123')
@@ -120,3 +123,4 @@ def test_33(a, /, b, *, c, **d):
120123
x[func](*args, **kwargs)
121124
test[0](*test[1:])
122125
(obj*self._arr.ndim)(*self._arr.shape)
126+
traverse((index, value), visit, result=result, *args, **kwargs)

tests/reference/ast_new-function_def2-52c4587.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22
"basename": "ast_new-function_def2-52c4587",
33
"cmd": "lpython --show-ast --new-parser --no-color {infile} -o {outfile}",
44
"infile": "tests/parser/function_def2.py",
5-
"infile_hash": "e364a83df399e2a4f74d2b57fb0846a04803c5378750fb0c38ff2ba7",
5+
"infile_hash": "7530fc0c8839061b935134cf72ca1ed46d0f2e5ec1b7053ef68b011b",
66
"outfile": null,
77
"outfile_hash": null,
88
"stdout": "ast_new-function_def2-52c4587.stdout",
9-
"stdout_hash": "874f51742f065edc73fda15183027472622153c57634b8b2481a22c8",
9+
"stdout_hash": "f94b525c239bede5185c86dbf285f82e9a4ec3708e307c191f6270eb",
1010
"stderr": null,
1111
"stderr_hash": null,
1212
"returncode": 0

0 commit comments

Comments
 (0)