about summary refs log tree commit diff
path: root/src/libexpr/parser.y
diff options
context:
space:
mode:
Diffstat (limited to 'src/libexpr/parser.y')
-rw-r--r--src/libexpr/parser.y33
1 files changed, 24 insertions, 9 deletions
diff --git a/src/libexpr/parser.y b/src/libexpr/parser.y
index 9c941bb7d446..067a0f8d54da 100644
--- a/src/libexpr/parser.y
+++ b/src/libexpr/parser.y
@@ -237,9 +237,9 @@ expr: expr_function;
 
 expr_function
   : '{' formals '}' ':' expr_function
-    { $$ = makeFunction($2, $5, CUR_POS); }
+    { $$ = makeFunction(makeAttrsPat($2), $5, CUR_POS); }
   | ID ':' expr_function
-    { $$ = makeFunction1($1, $3, CUR_POS); }
+    { $$ = makeFunction(makeVarPat($1), $3, CUR_POS); }
   | ASSERT expr ';' expr_function
     { $$ = makeAssert($2, $4, CUR_POS); }
   | WITH expr ';' expr_function
@@ -387,22 +387,37 @@ static void checkAttrs(ATermMap & names, ATermList bnds)
 }
 
 
-static void checkAttrSets(ATerm e)
+static void checkPatternVars(ATerm pos, ATermMap & map, Pattern pat)
 {
+    ATerm name;
     ATermList formals;
-    ATerm body, pos;
-    if (matchFunction(e, formals, body, pos)) {
-        ATermMap names(ATgetLength(formals));
+    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)) { 
         for (ATermIterator i(formals); i; ++i) {
-            ATerm name;
             ATerm d1;
             if (!matchFormal(*i, name, d1)) abort();
-            if (names.get(name))
+            if (map.get(name))
                 throw EvalError(format("duplicate formal function argument `%1%' at %2%")
                     % aterm2String(name) % showPos(pos));
-            names.set(name, name);
+            map.set(name, name);
         }
     }
+    else abort();
+}
+
+
+static void checkAttrSets(ATerm e)
+{
+    ATerm pat, body, pos;
+    if (matchFunction(e, pat, body, pos)) {
+        ATermMap map(16);
+        checkPatternVars(pos, map, pat);
+    }
 
     ATermList bnds;
     if (matchAttrs(e, bnds)) {