about summary refs log tree commit diff
path: root/src/libexpr/parser.y
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2008-08-14T12·53+0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2008-08-14T12·53+0000
commit1b962fc7206bf3134b2a2097d3db0ee6d2863c47 (patch)
tree9e259b7df5f0fa3ca748fa9b9035f2dd35b1a44d /src/libexpr/parser.y
parente8188384129bda7c8cdd5e17023ab05047551e6e (diff)
* @-patterns as in Haskell. For instance, in a function definition
    f = args @ {x, y, z}: ...;

  `args' refers to the argument as a whole, which is further
  pattern-matched against the attribute set pattern {x, y, z}.

Diffstat (limited to 'src/libexpr/parser.y')
-rw-r--r--src/libexpr/parser.y13
1 files changed, 12 insertions, 1 deletions
diff --git a/src/libexpr/parser.y b/src/libexpr/parser.y
index 7713021a909e..c48aa34aaf48 100644
--- a/src/libexpr/parser.y
+++ b/src/libexpr/parser.y
@@ -211,7 +211,8 @@ static void freeAndUnprotect(void * p)
 }
 
 %type <t> start expr expr_function expr_if expr_op
-%type <t> expr_app expr_select expr_simple bind inheritsrc formal pattern
+%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
 %token <t> ID INT STR IND_STR PATH URI
 %token IF THEN ELSE ASSERT WITH LET IN REC INHERIT EQ NEQ AND OR IMPL
@@ -319,6 +320,11 @@ ind_string_parts
   ;
 
 pattern
+  : pattern2 '@' pattern { $$ = makeAtPat($1, $3); }
+  | pattern2
+  ;
+
+pattern2
   : ID { $$ = makeVarPat($1); }
   | '{' formals '}' { $$ = makeAttrsPat($2); }
   ;
@@ -394,6 +400,7 @@ static void checkPatternVars(ATerm pos, ATermMap & map, Pattern pat)
 {
     ATerm name;
     ATermList formals;
+    Pattern pat1, pat2;
     if (matchVarPat(pat, name)) {
         if (map.get(name))
             throw EvalError(format("duplicate formal function argument `%1%' at %2%")
@@ -410,6 +417,10 @@ static void checkPatternVars(ATerm pos, ATermMap & map, Pattern pat)
             map.set(name, name);
         }
     }
+    else if (matchAtPat(pat, pat1, pat2)) {
+        checkPatternVars(pos, map, pat1);
+        checkPatternVars(pos, map, pat2);
+    }
     else abort();
 }