Allow using RegisterPrimop to define constants.
This enables plugins to add new constants, as well as new primops.
This commit is contained in:
parent
88cd2d41ac
commit
081f14a169
6 changed files with 15 additions and 6 deletions
|
@ -750,7 +750,7 @@ builtins.fetchurl {
|
|||
files will be dlopened by Nix, allowing them to affect
|
||||
execution through static initialization. In particular, these
|
||||
plugins may construct static instances of RegisterPrimOp to
|
||||
add new primops to the expression language,
|
||||
add new primops or constants to the expression language,
|
||||
RegisterStoreImplementation to add new store implementations,
|
||||
and RegisterCommand to add new subcommands to the
|
||||
<literal>nix</literal> command. See the constructors for those
|
||||
|
|
|
@ -404,7 +404,7 @@ Path EvalState::toRealPath(const Path & path, const PathSet & context)
|
|||
};
|
||||
|
||||
|
||||
void EvalState::addConstant(const string & name, Value & v)
|
||||
Value * EvalState::addConstant(const string & name, Value & v)
|
||||
{
|
||||
Value * v2 = allocValue();
|
||||
*v2 = v;
|
||||
|
@ -412,12 +412,18 @@ void EvalState::addConstant(const string & name, Value & v)
|
|||
baseEnv.values[baseEnvDispl++] = v2;
|
||||
string name2 = string(name, 0, 2) == "__" ? string(name, 2) : name;
|
||||
baseEnv.values[0]->attrs->push_back(Attr(symbols.create(name2), v2));
|
||||
return v2;
|
||||
}
|
||||
|
||||
|
||||
Value * EvalState::addPrimOp(const string & name,
|
||||
unsigned int arity, PrimOpFun primOp)
|
||||
{
|
||||
if (arity == 0) {
|
||||
Value v;
|
||||
primOp(*this, noPos, nullptr, v);
|
||||
return addConstant(name, v);
|
||||
}
|
||||
Value * v = allocValue();
|
||||
string name2 = string(name, 0, 2) == "__" ? string(name, 2) : name;
|
||||
Symbol sym = symbols.create(name2);
|
||||
|
|
|
@ -210,7 +210,7 @@ private:
|
|||
|
||||
void createBaseEnv();
|
||||
|
||||
void addConstant(const string & name, Value & v);
|
||||
Value * addConstant(const string & name, Value & v);
|
||||
|
||||
Value * addPrimOp(const string & name,
|
||||
unsigned int arity, PrimOpFun primOp);
|
||||
|
|
|
@ -9,6 +9,9 @@ struct RegisterPrimOp
|
|||
{
|
||||
typedef std::vector<std::tuple<std::string, size_t, PrimOpFun>> PrimOps;
|
||||
static PrimOps * primOps;
|
||||
/* You can register a constant by passing an arity of 0. fun
|
||||
will get called during EvalState initialization, so there
|
||||
may be primops not yet added and builtins is not yet sorted. */
|
||||
RegisterPrimOp(std::string name, size_t arity, PrimOpFun fun);
|
||||
};
|
||||
|
||||
|
|
|
@ -2,6 +2,6 @@ source common.sh
|
|||
|
||||
set -o pipefail
|
||||
|
||||
res=$(nix eval '(builtins.constNull true)' --option plugin-files $PWD/plugins/plugintest.so)
|
||||
res=$(nix eval '(builtins.anotherNull)' --option plugin-files $PWD/plugins/plugintest.so)
|
||||
|
||||
[ "$res"x = "nullx" ]
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
using namespace nix;
|
||||
|
||||
static void prim_constNull (EvalState & state, const Pos & pos, Value ** args, Value & v)
|
||||
static void prim_anotherNull (EvalState & state, const Pos & pos, Value ** args, Value & v)
|
||||
{
|
||||
mkNull(v);
|
||||
}
|
||||
|
||||
static RegisterPrimOp r("constNull", 1, prim_constNull);
|
||||
static RegisterPrimOp r("anotherNull", 0, prim_anotherNull);
|
||||
|
|
Loading…
Reference in a new issue