mirror of
https://github.com/privatevoid-net/nix-super.git
synced 2024-11-22 14:06:16 +02:00
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.
This commit is contained in:
parent
8cfe939b0f
commit
997defa166
4 changed files with 15 additions and 1 deletions
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
1
tests/lang/eval-okay-callable-attrs.exp
Normal file
1
tests/lang/eval-okay-callable-attrs.exp
Normal file
|
@ -0,0 +1 @@
|
|||
true
|
1
tests/lang/eval-okay-callable-attrs.nix
Normal file
1
tests/lang/eval-okay-callable-attrs.nix
Normal file
|
@ -0,0 +1 @@
|
|||
({ __functor = self: x: self.foo && x; foo = false; } // { foo = true; }) true
|
Loading…
Reference in a new issue