From 997defa16617caf5fd869924558389639d1c8caf Mon Sep 17 00:00:00 2001 From: Shea Levy Date: Wed, 15 Oct 2014 22:04:48 -0400 Subject: 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 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'src/libexpr/eval.cc') 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); -- cgit 1.4.1