Skip to content

Commit aa8d4e8

Browse files
committed
Merge branch 'fmtarg2' into 'master'
AST: Implement keyword arguments and array sections Closes #217 See merge request lfortran/lfortran!638
2 parents 6deaffb + cf5bda4 commit aa8d4e8

File tree

59 files changed

+386
-211
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+386
-211
lines changed

grammar/AST.asdl

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ unit_decl2
5353
stmt
5454
= Assignment(expr target, expr value)
5555
| Associate(expr target, expr value)
56-
| SubroutineCall(identifier name, expr* args)
56+
| SubroutineCall(identifier name, fnarg* args, keyword* keywords)
5757
| BuiltinCall(identifier name, expr* args)
5858
| If(expr test, stmt* body, stmt* orelse)
5959
| Where(expr test, stmt* body, stmt* orelse)
@@ -75,8 +75,8 @@ expr
7575
| BinOp(expr left, operator op, expr right)
7676
| UnaryOp(unaryop op, expr operand)
7777
| Compare(expr left, cmpop op, expr right)
78-
| FuncCall(identifier func, expr* args, keyword* keywords)
79-
| FuncCallOrArray(identifier func, expr* args, keyword* keywords)
78+
| FuncCall(identifier func, fnarg* args, keyword* keywords)
79+
| FuncCallOrArray(identifier func, fnarg* args, keyword* keywords)
8080
| Array(identifier name, array_index* args)
8181
| ArrayInitializer(expr* args)
8282
| Num(object n)
@@ -112,7 +112,24 @@ fn_mod = FnMod(string s)
112112

113113
arg = (identifier arg)
114114

115-
keyword = (identifier? arg, expr value)
115+
116+
-- Encoding of array elements and sections in fnarg:
117+
-- start end step
118+
-- element:
119+
-- X(i) () i ()
120+
-- section:
121+
-- X(:) () () 1
122+
-- X(a:) a () 1
123+
-- X(:b) () b 1
124+
-- X(a:b) a b 1
125+
-- X(::c) () () c
126+
-- X(a::c) a () c
127+
-- X(:b:c) () b c
128+
-- X(a:b:c) a b c
129+
--
130+
fnarg = (expr? start, expr? end, expr? step)
131+
132+
keyword = (identifier arg, expr value)
116133

117134
tbind = Bind(keyword* args)
118135

src/lfortran/ast_to_cpp.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,7 @@ class ASTToCPPVisitor : public BaseVisitor<ASTToCPPVisitor>
344344
r.append(x.m_name);
345345
r.append("(");
346346
for (size_t i=0; i<x.n_args; i++) {
347-
this->visit_expr(*x.m_args[i]);
347+
this->visit_expr(*x.m_args[i].m_end);
348348
r.append(s);
349349
if (i < x.n_args-1) r.append(" ");
350350
}
@@ -758,7 +758,7 @@ class ASTToCPPVisitor : public BaseVisitor<ASTToCPPVisitor>
758758
s.append(" ");
759759
s.append("[");
760760
for (size_t i=0; i<x.n_args; i++) {
761-
this->visit_expr(*x.m_args[i]);
761+
this->visit_expr(*x.m_args[i].m_end);
762762
if (i < x.n_args-1) s.append(" ");
763763
}
764764
s.append("]");
@@ -782,7 +782,7 @@ class ASTToCPPVisitor : public BaseVisitor<ASTToCPPVisitor>
782782
r.append(x.m_func);
783783
r.append("[");
784784
for (size_t i=0; i<x.n_args; i++) {
785-
this->visit_expr(*x.m_args[i]);
785+
this->visit_expr(*x.m_args[i].m_end);
786786
r.append(s);
787787
if (i < x.n_args-1) s.append(", ");
788788
}

src/lfortran/ast_to_cpp_hip.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ class ASTToCPPHIPVisitor : public BaseVisitor<ASTToCPPHIPVisitor>
350350
r.append(x.m_name);
351351
r.append("(");
352352
for (size_t i=0; i<x.n_args; i++) {
353-
this->visit_expr(*x.m_args[i]);
353+
this->visit_expr(*x.m_args[i].m_end);
354354
r.append(s);
355355
if (i < x.n_args-1) r.append(" ");
356356
}
@@ -847,7 +847,7 @@ class ASTToCPPHIPVisitor : public BaseVisitor<ASTToCPPHIPVisitor>
847847
s.append(" ");
848848
s.append("[");
849849
for (size_t i=0; i<x.n_args; i++) {
850-
this->visit_expr(*x.m_args[i]);
850+
this->visit_expr(*x.m_args[i].m_end);
851851
if (i < x.n_args-1) s.append(" ");
852852
}
853853
s.append("]");
@@ -874,7 +874,7 @@ class ASTToCPPHIPVisitor : public BaseVisitor<ASTToCPPHIPVisitor>
874874
vars.push_back(x.m_func);
875875
r.append("[");
876876
for (size_t i=0; i<x.n_args; i++) {
877-
this->visit_expr(*x.m_args[i]);
877+
this->visit_expr(*x.m_args[i].m_end);
878878
r.append(s);
879879
if (i < x.n_args-1) s.append(", ");
880880
}

src/lfortran/ast_to_openmp.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ class ASTToOPENMPVisitor : public BaseVisitor<ASTToOPENMPVisitor>
323323
r.append(x.m_name);
324324
r.append("(");
325325
for (size_t i=0; i<x.n_args; i++) {
326-
this->visit_expr(*x.m_args[i]);
326+
this->visit_expr(*x.m_args[i].m_end);
327327
r.append(s);
328328
if (i < x.n_args-1) r.append(" ");
329329
}
@@ -738,7 +738,7 @@ class ASTToOPENMPVisitor : public BaseVisitor<ASTToOPENMPVisitor>
738738
s.append(" ");
739739
s.append("[");
740740
for (size_t i=0; i<x.n_args; i++) {
741-
this->visit_expr(*x.m_args[i]);
741+
this->visit_expr(*x.m_args[i].m_end);
742742
if (i < x.n_args-1) s.append(" ");
743743
}
744744
s.append("]");
@@ -756,7 +756,7 @@ class ASTToOPENMPVisitor : public BaseVisitor<ASTToOPENMPVisitor>
756756
r.append(x.m_func);
757757
r.append("(");
758758
for (size_t i=0; i<x.n_args; i++) {
759-
this->visit_expr(*x.m_args[i]);
759+
this->visit_expr(*x.m_args[i].m_end);
760760
r.append(s);
761761
if (i < x.n_args-1) s.append(", ");
762762
}

src/lfortran/ast_to_src.cpp

Lines changed: 54 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -424,8 +424,12 @@ class ASTToSRCVisitor : public BaseVisitor<ASTToSRCVisitor>
424424
r.append(x.m_name);
425425
r.append("(");
426426
for (size_t i=0; i<x.n_args; i++) {
427-
this->visit_expr(*x.m_args[i]);
428-
r.append(s);
427+
if (x.m_args[i].m_end) {
428+
this->visit_expr(*x.m_args[i].m_end);
429+
r.append(s);
430+
} else {
431+
r += ":";
432+
}
429433
if (i < x.n_args-1) r.append(", ");
430434
}
431435
r.append(")\n");
@@ -742,10 +746,15 @@ class ASTToSRCVisitor : public BaseVisitor<ASTToSRCVisitor>
742746
r.append(x.m_func);
743747
r.append("(");
744748
for (size_t i=0; i<x.n_args; i++) {
745-
this->visit_expr(*x.m_args[i]);
746-
r.append(s);
747-
if (i < x.n_args-1) s.append(", ");
749+
if (x.m_args[i].m_end) {
750+
this->visit_expr(*x.m_args[i].m_end);
751+
r.append(s);
752+
} else {
753+
r += ":";
754+
}
755+
if (i < x.n_args-1) r.append(", ");
748756
}
757+
if (x.n_keywords > 0) r.append(", ");
749758
for (size_t i=0; i<x.n_keywords; i++) {
750759
this->visit_keyword(x.m_keywords[i]);
751760
r.append(s);
@@ -760,10 +769,11 @@ class ASTToSRCVisitor : public BaseVisitor<ASTToSRCVisitor>
760769
r.append(x.m_func);
761770
r.append("(");
762771
for (size_t i=0; i<x.n_args; i++) {
763-
this->visit_expr(*x.m_args[i]);
772+
this->visit_fnarg(x.m_args[i]);
764773
r.append(s);
765774
if (i < x.n_args-1) r.append(", ");
766775
}
776+
if (x.n_keywords > 0) r.append(", ");
767777
for (size_t i=0; i<x.n_keywords; i++) {
768778
this->visit_keyword(x.m_keywords[i]);
769779
r.append(s);
@@ -780,7 +790,7 @@ class ASTToSRCVisitor : public BaseVisitor<ASTToSRCVisitor>
780790
for (size_t i=0; i<x.n_args; i++) {
781791
this->visit_array_index(*x.m_args[i]);
782792
r.append(s);
783-
if (i < x.n_args-1) s.append(", ");
793+
if (i < x.n_args-1) r.append(", ");
784794
}
785795
r.append(")");
786796
s = r;
@@ -970,8 +980,43 @@ class ASTToSRCVisitor : public BaseVisitor<ASTToSRCVisitor>
970980
s = std::string(x.m_arg);
971981
}
972982

973-
void visit_keyword(const keyword_t &/*x*/) {
974-
throw LFortranException("keyword not implemented");
983+
void visit_keyword(const keyword_t &x) {
984+
std::string r;
985+
r += x.m_arg;
986+
r += "=";
987+
this->visit_expr(*x.m_value);
988+
r += s;
989+
s = r;
990+
}
991+
992+
void visit_fnarg(const fnarg_t &x) {
993+
std::string r;
994+
if (x.m_step) {
995+
// Array section
996+
if (x.m_start) {
997+
this->visit_expr(*x.m_start);
998+
r += s;
999+
}
1000+
r += ":";
1001+
if (x.m_end) {
1002+
this->visit_expr(*x.m_end);
1003+
r += s;
1004+
}
1005+
if (is_a<Num_t>(*x.m_step) && down_cast<Num_t>(x.m_step)->m_n == 1) {
1006+
// Nothing, a:b:1 is printed as a:b
1007+
} else {
1008+
r += ":";
1009+
this->visit_expr(*x.m_step);
1010+
r += s;
1011+
}
1012+
} else {
1013+
// Array element
1014+
LFORTRAN_ASSERT(x.m_end);
1015+
LFORTRAN_ASSERT(!x.m_start);
1016+
this->visit_expr(*x.m_end);
1017+
r = s;
1018+
}
1019+
s = r;
9751020
}
9761021

9771022
void visit_Bind(const Bind_t &x) {

src/lfortran/containers.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,20 +36,34 @@ class VecIterator
3636
size_t m_index;
3737
};
3838

39+
#ifdef WITH_LFORTRAN_ASSERT
40+
static int vec_called_const = 0xdeadbeef;
41+
#endif
3942

4043
template <typename T>
4144
struct Vec {
4245
size_t n, max;
4346
T* p;
47+
#ifdef WITH_LFORTRAN_ASSERT
48+
int reserve_called;
49+
#endif
4450

4551
// reserve() must be called before calling push_back()
4652
void reserve(Allocator &al, size_t max) {
4753
n = 0;
4854
this->max = max;
4955
p = al.allocate<T>(max);
56+
#ifdef WITH_LFORTRAN_ASSERT
57+
reserve_called = vec_called_const;
58+
#endif
5059
}
5160

5261
void push_back(Allocator &al, T x) {
62+
// This can pass by accident even if reserve() is not called (if
63+
// reserve_called happens to be equal to vec_called_const when Vec is
64+
// allocated in memory), but the chance is small. It catches such bugs
65+
// in practice.
66+
LFORTRAN_ASSERT(reserve_called == vec_called_const);
5367
if (n == max) {
5468
size_t max2 = 2*max;
5569
T* p2 = al.allocate<T>(max2);

src/lfortran/parser/parser.yy

Lines changed: 26 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -288,11 +288,9 @@ void yyerror(YYLTYPE *yyloc, LFortran::Parser &p, const std::string &msg)
288288
%type <ast> var_decl
289289
%type <decl> var_sym_decl
290290
%type <vec_dim> array_comp_decl_list
291-
%type <dim> fnarray_arg
292-
%type <vec_dim> fnarray_arg_list
293-
%type <vec_dim> fnarray_arg_list_opt
291+
%type <fnarg> fnarray_arg
292+
%type <vec_fnarg> fnarray_arg_list_opt
294293
%type <dim> array_comp_decl
295-
%type <dim> array_comp_call
296294
%type <var_type> var_type
297295
%type <ast> fn_mod
298296
%type <vec_ast> fn_mod_plus
@@ -861,27 +859,13 @@ array_comp_decl_list
861859
;
862860

863861
array_comp_decl
864-
: expr { $$ = ARRAY_COMP_DECL1($1, @$); }
865-
| expr ":" expr { $$ = ARRAY_COMP_DECL2($1, $3, @$); }
866-
| expr ":" { $$ = ARRAY_COMP_DECL3($1, @$); }
867-
| ":" expr { $$ = ARRAY_COMP_DECL4($2, @$); }
868-
| ":" { $$ = ARRAY_COMP_DECL5(@$); }
869-
| "*" { $$ = ARRAY_COMP_DECL5(@$); } // TODO
870-
| expr ":" "*" { $$ = ARRAY_COMP_DECL5(@$); } // TODO
871-
;
872-
873-
array_comp_call
874-
: expr { $$ = ARRAY_COMP_DECL1($1, @$); }
875-
| expr ":" expr { $$ = ARRAY_COMP_DECL2($1, $3, @$); }
876-
| expr ":" { $$ = ARRAY_COMP_DECL3($1, @$); }
877-
| ":" expr { $$ = ARRAY_COMP_DECL4($2, @$); }
878-
| ":" { $$ = ARRAY_COMP_DECL5(@$); }
879-
| expr ":" expr ":" expr { $$ = ARRAY_COMP_DECL2($1, $3, @$); } // TODO
880-
| expr "::" expr { $$ = ARRAY_COMP_DECL3($1, @$); } // TODO
881-
| expr ":" ":" expr { $$ = ARRAY_COMP_DECL3($1, @$); } // TODO
882-
| ":" expr ":" expr { $$ = ARRAY_COMP_DECL4($2, @$); } // TODO
883-
| "::" expr { $$ = ARRAY_COMP_DECL5(@$); } // TODO
884-
| ":" ":" expr { $$ = ARRAY_COMP_DECL5(@$); } // TODO
862+
: expr { $$ = ARRAY_COMP_DECL1d($1, @$); }
863+
| expr ":" expr { $$ = ARRAY_COMP_DECL2d($1, $3, @$); }
864+
| expr ":" { $$ = ARRAY_COMP_DECL3d($1, @$); }
865+
| ":" expr { $$ = ARRAY_COMP_DECL4d($2, @$); }
866+
| ":" { $$ = ARRAY_COMP_DECL5d(@$); }
867+
| "*" { $$ = ARRAY_COMP_DECL5d(@$); } // TODO
868+
| expr ":" "*" { $$ = ARRAY_COMP_DECL5d(@$); } // TODO
885869
;
886870

887871

@@ -1362,21 +1346,27 @@ struct_member
13621346
;
13631347

13641348
fnarray_arg_list_opt
1365-
: fnarray_arg_list
1349+
: fnarray_arg_list_opt "," fnarray_arg { $$ = $1; PLIST_ADD($$, $3); }
1350+
| fnarray_arg { LIST_NEW($$); PLIST_ADD($$, $1); }
13661351
| %empty { LIST_NEW($$); }
13671352
;
13681353

1369-
fnarray_arg_list
1370-
: fnarray_arg_list "," fnarray_arg {$$ = $1; LIST_ADD($$, $3); }
1371-
| fnarray_arg { LIST_NEW($$); LIST_ADD($$, $1); }
1372-
;
1373-
13741354
fnarray_arg
1375-
: array_comp_call
1376-
// TODO: extend "dim" to also include the keyword argument "id"
1377-
// This can be done by adding a flag "keyword",
1378-
// and encoding start=id, end=expr
1379-
| id "=" expr { $$ = ARRAY_COMP_DECL1($3, @$); }
1355+
// array element / function argument
1356+
: expr { $$ = ARRAY_COMP_DECL_0i0($1, @$); }
1357+
// array section
1358+
| ":" { $$ = ARRAY_COMP_DECL_001(@$); }
1359+
| expr ":" { $$ = ARRAY_COMP_DECL_a01($1, @$); }
1360+
| ":" expr { $$ = ARRAY_COMP_DECL_0b1($2, @$); }
1361+
| expr ":" expr { $$ = ARRAY_COMP_DECL_ab1($1, $3, @$); }
1362+
| "::" expr { $$ = ARRAY_COMP_DECL_00c($2, @$); }
1363+
| ":" ":" expr { $$ = ARRAY_COMP_DECL_00c($3, @$); }
1364+
| expr "::" expr { $$ = ARRAY_COMP_DECL_a0c($1, $3, @$); }
1365+
| expr ":" ":" expr { $$ = ARRAY_COMP_DECL_a0c($1, $4, @$); }
1366+
| ":" expr ":" expr { $$ = ARRAY_COMP_DECL_0bc($2, $4, @$); }
1367+
| expr ":" expr ":" expr { $$ = ARRAY_COMP_DECL_abc($1, $3, $5, @$); }
1368+
// keyword function argument
1369+
| id "=" expr { $$ = ARRAY_COMP_DECL1k($1, $3, @$); }
13801370
;
13811371

13821372
id_list_opt

0 commit comments

Comments
 (0)