guix-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

288/376: Add functors (callable attribute sets).


From: Ludovic Courtès
Subject: 288/376: Add functors (callable attribute sets).
Date: Wed, 28 Jan 2015 22:05:40 +0000

civodul pushed a commit to tag 1.8
in repository guix.

commit 997defa16617caf5fd869924558389639d1c8caf
Author: Shea Levy <address@hidden>
Date:   Wed Oct 15 22:04:48 2014 -0400

    Add functors (callable attribute sets).
    
    With this, attribute sets with a `__functor` attribute can be applied
    just like normal functions. This can be used to attach arbitrary
    metadata to a function without callers needing to treat it specially.
---
 src/libexpr/eval.cc                     |   12 ++++++++++++
 src/libexpr/eval.hh                     |    2 +-
 tests/lang/eval-okay-callable-attrs.exp |    1 +
 tests/lang/eval-okay-callable-attrs.nix |    1 +
 4 files changed, 15 insertions(+), 1 deletions(-)

diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index 8bc992d..8177497 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -180,6 +180,7 @@ EvalState::EvalState(const Strings & _searchPath)
     , sFile(symbols.create("file"))
     , sLine(symbols.create("line"))
     , sColumn(symbols.create("column"))
+    , sFunctor(symbols.create("__functor"))
     , repair(false)
     , baseEnv(allocEnv(128))
     , staticBaseEnv(false, 0)
@@ -885,6 +886,17 @@ void EvalState::callFunction(Value & fun, Value & arg, 
Value & v, const Pos & po
         return;
     }
 
+    if (fun.type == tAttrs) {
+      auto found = fun.attrs->find(sFunctor);
+      if (found != fun.attrs->end()) {
+        forceValue(*found->value);
+        Value * v2 = allocValue();
+        callFunction(*found->value, fun, *v2, pos);
+        forceValue(*v2);
+        return callFunction(*v2, arg, v, pos);
+      }
+    }
+
     if (fun.type != tLambda)
         throwTypeError("attempt to call something which is not a function but 
%1%, at %2%", fun, pos);
 
diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh
index 51ab1b1..d066f7f 100644
--- a/src/libexpr/eval.hh
+++ b/src/libexpr/eval.hh
@@ -126,7 +126,7 @@ public:
 
     const Symbol sWith, sOutPath, sDrvPath, sType, sMeta, sName, sValue,
         sSystem, sOverrides, sOutputs, sOutputName, sIgnoreNulls,
-        sFile, sLine, sColumn;
+        sFile, sLine, sColumn, sFunctor;
     Symbol sDerivationNix;
 
     /* If set, force copying files to the Nix store even if they
diff --git a/tests/lang/eval-okay-callable-attrs.exp 
b/tests/lang/eval-okay-callable-attrs.exp
new file mode 100644
index 0000000..27ba77d
--- /dev/null
+++ b/tests/lang/eval-okay-callable-attrs.exp
@@ -0,0 +1 @@
+true
diff --git a/tests/lang/eval-okay-callable-attrs.nix 
b/tests/lang/eval-okay-callable-attrs.nix
new file mode 100644
index 0000000..310a030
--- /dev/null
+++ b/tests/lang/eval-okay-callable-attrs.nix
@@ -0,0 +1 @@
+({ __functor = self: x: self.foo && x; foo = false; } // { foo = true; }) true



reply via email to

[Prev in Thread] Current Thread [Next in Thread]