diff options
author | Shea Levy <shea@shealevy.com> | 2014-10-16T02·04-0400 |
---|---|---|
committer | Shea Levy <shea@shealevy.com> | 2014-11-15T21·12-0500 |
commit | 997defa16617caf5fd869924558389639d1c8caf (patch) | |
tree | ba286d246324da0066c8528639e43bd26c986cdb | |
parent | 8cfe939b0f222e3b27493a3c62e0b1088b12e110 (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.
-rw-r--r-- | src/libexpr/eval.cc | 12 | ||||
-rw-r--r-- | src/libexpr/eval.hh | 2 | ||||
-rw-r--r-- | tests/lang/eval-okay-callable-attrs.exp | 1 | ||||
-rw-r--r-- | 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 8bc992d0350b..81774974a90c 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 51ab1b1e8012..d066f7fd5815 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 000000000000..27ba77ddaf61 --- /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 000000000000..310a030df004 --- /dev/null +++ b/tests/lang/eval-okay-callable-attrs.nix @@ -0,0 +1 @@ +({ __functor = self: x: self.foo && x; foo = false; } // { foo = true; }) true |