aboutsummaryrefslogtreecommitdiff
path: root/src/libexpr
diff options
context:
space:
mode:
authorShea Levy <shea@shealevy.com>2014-10-15 22:04:48 -0400
committerShea Levy <shea@shealevy.com>2014-11-15 16:12:05 -0500
commit997defa16617caf5fd869924558389639d1c8caf (patch)
treeba286d246324da0066c8528639e43bd26c986cdb /src/libexpr
parent8cfe939b0f222e3b27493a3c62e0b1088b12e110 (diff)
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.
Diffstat (limited to 'src/libexpr')
-rw-r--r--src/libexpr/eval.cc12
-rw-r--r--src/libexpr/eval.hh2
2 files changed, 13 insertions, 1 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index 8bc992d03..81774974a 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 51ab1b1e8..d066f7fd5 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