aboutsummaryrefslogtreecommitdiff
path: root/src/libexpr/parser.y
diff options
context:
space:
mode:
Diffstat (limited to 'src/libexpr/parser.y')
-rw-r--r--src/libexpr/parser.y24
1 files changed, 18 insertions, 6 deletions
diff --git a/src/libexpr/parser.y b/src/libexpr/parser.y
index c48aa34aa..b7624df7e 100644
--- a/src/libexpr/parser.y
+++ b/src/libexpr/parser.y
@@ -208,16 +208,22 @@ static void freeAndUnprotect(void * p)
%union {
ATerm t;
ATermList ts;
+ struct {
+ ATermList formals;
+ bool ellipsis;
+ } formals;
}
%type <t> start expr expr_function expr_if expr_op
%type <t> expr_app expr_select expr_simple bind inheritsrc formal
%type <t> pattern pattern2
-%type <ts> binds ids expr_list formals string_parts ind_string_parts
+%type <ts> binds ids expr_list string_parts ind_string_parts
+%type <formals> formals
%token <t> ID INT STR IND_STR PATH URI
%token IF THEN ELSE ASSERT WITH LET IN REC INHERIT EQ NEQ AND OR IMPL
%token DOLLAR_CURLY /* == ${ */
%token IND_STRING_OPEN IND_STRING_CLOSE
+%token ELLIPSIS
%nonassoc IMPL
%left OR
@@ -326,7 +332,7 @@ pattern
pattern2
: ID { $$ = makeVarPat($1); }
- | '{' formals '}' { $$ = makeAttrsPat($2); }
+ | '{' formals '}' { $$ = makeAttrsPat($2.formals, $2.ellipsis ? eTrue : eFalse); }
;
binds
@@ -357,9 +363,14 @@ expr_list
;
formals
- : formal ',' formals { $$ = ATinsert($3, $1); } /* idem - right recursive */
- | formal { $$ = ATinsert(ATempty, $1); }
- | { $$ = ATempty; }
+ : formal ',' formals /* idem - right recursive */
+ { $$.formals = ATinsert($3.formals, $1); $$.ellipsis = $3.ellipsis; }
+ | formal
+ { $$.formals = ATinsert(ATempty, $1); $$.ellipsis = false; }
+ |
+ { $$.formals = ATempty; $$.ellipsis = false; }
+ | ELLIPSIS
+ { $$.formals = ATempty; $$.ellipsis = true; }
;
formal
@@ -401,13 +412,14 @@ static void checkPatternVars(ATerm pos, ATermMap & map, Pattern pat)
ATerm name;
ATermList formals;
Pattern pat1, pat2;
+ ATermBool ellipsis;
if (matchVarPat(pat, name)) {
if (map.get(name))
throw EvalError(format("duplicate formal function argument `%1%' at %2%")
% aterm2String(name) % showPos(pos));
map.set(name, name);
}
- else if (matchAttrsPat(pat, formals)) {
+ else if (matchAttrsPat(pat, formals, ellipsis)) {
for (ATermIterator i(formals); i; ++i) {
ATerm d1;
if (!matchFormal(*i, name, d1)) abort();