about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2004-02-04T17·23+0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2004-02-04T17·23+0000
commitd445da7a7b3cbb4822bcad3904a36f0d914917d3 (patch)
treea44ad1a7ba4679dc49ff9d2197c13e27ae00a3b0
parent9d25466b34a5f7c1c8b1c273976cf59c33961a6c (diff)
* Extended the `inherit' syntax to optionally select attributes from
  other attribute sets, rather than the current scope.  E.g.,
  
    {inherit (pkgs) gcc binutils;}

  is equivalent to

    {gcc = pkgs.gcc; binutils = pkgs.binutils;}

  I am not so happy about the syntax.

-rw-r--r--src/libexpr/parser.cc15
-rw-r--r--src/libexpr/parser.y11
2 files changed, 18 insertions, 8 deletions
diff --git a/src/libexpr/parser.cc b/src/libexpr/parser.cc
index 68b367340acf..c300a0d07bc4 100644
--- a/src/libexpr/parser.cc
+++ b/src/libexpr/parser.cc
@@ -50,11 +50,16 @@ ATerm fixAttrs(int recursive, ATermList as)
     ATermList * is = recursive ? &cs : &bs;
     for (ATermIterator i(as); i; ++i) {
         ATermList names;
-        if (atMatch(m, *i) >> "Inherit" >> names)
-            for (ATermIterator j(names); j; ++j)
-                *is = ATinsert(*is,
-                    ATmake("Bind(<term>, Var(<term>))", *j, *j));
-        else bs = ATinsert(bs, *i);
+        Expr src;
+        if (atMatch(m, *i) >> "Inherit" >> src >> names) {
+            bool fromScope = atMatch(m, src) >> "Scope";
+            for (ATermIterator j(names); j; ++j) {
+                Expr rhs = fromScope
+                    ? ATmake("Var(<term>)", *j)
+                    : ATmake("Select(<term>, <term>)", src, *j);
+                *is = ATinsert(*is, ATmake("Bind(<term>, <term>)", *j, rhs));
+            }
+        } else bs = ATinsert(bs, *i);
     }
     if (recursive)
         return ATmake("Rec(<term>, <term>)", bs, cs);
diff --git a/src/libexpr/parser.y b/src/libexpr/parser.y
index 6c0fdbda25f3..257c0cd38ab2 100644
--- a/src/libexpr/parser.y
+++ b/src/libexpr/parser.y
@@ -33,7 +33,7 @@ void yyerror(YYLTYPE * loc, yyscan_t scanner, void * data, char * s)
 }
 
 %type <t> start expr expr_function expr_assert expr_op
-%type <t> expr_app expr_select expr_simple bind formal
+%type <t> expr_app expr_select expr_simple bind inheritsrc formal
 %type <ts> binds ids expr_list formals
 %token <t> ID INT STR PATH URI
 %token IF THEN ELSE ASSERT LET REC INHERIT EQ NEQ AND OR IMPL
@@ -114,8 +114,13 @@ binds
 bind
   : ID '=' expr ';'
     { $$ = ATmake("Bind(<term>, <term>)", $1, $3); }
-  | INHERIT ids ';'
-    { $$ = ATmake("Inherit(<term>)", $2); }
+  | INHERIT inheritsrc ids ';'
+    { $$ = ATmake("Inherit(<term>, <term>)", $2, $3); }
+  ;
+
+inheritsrc
+  : '(' expr ')' { $$ = $2; }
+  | { $$ = ATmake("Scope"); }
   ;
 
 ids: ids ID { $$ = ATinsert($1, $2); } | { $$ = ATempty; };