1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-06-27 21:01:16 +02:00

Allow primops to have Markdown documentation

This commit is contained in:
Eelco Dolstra 2020-08-24 13:11:56 +02:00
parent 88d5c9ec58
commit 33b1679d75
No known key found for this signature in database
GPG key ID: 8170B4726D7198DE
6 changed files with 92 additions and 15 deletions

View file

@ -525,6 +525,34 @@ Value * EvalState::addPrimOp(const string & name,
}
Value * EvalState::addPrimOp(PrimOp && primOp)
{
/* Hack to make constants lazy: turn them into a application of
the primop to a dummy value. */
if (primOp.arity == 0) {
primOp.arity = 1;
auto vPrimOp = allocValue();
vPrimOp->type = tPrimOp;
vPrimOp->primOp = new PrimOp(std::move(primOp));
Value v;
mkApp(v, *vPrimOp, *vPrimOp);
return addConstant(primOp.name, v);
}
Symbol envName = primOp.name;
if (hasPrefix(primOp.name, "__"))
primOp.name = symbols.create(std::string(primOp.name, 2));
Value * v = allocValue();
v->type = tPrimOp;
v->primOp = new PrimOp(std::move(primOp));
staticBaseEnv.vars[envName] = baseEnvDispl;
baseEnv.values[baseEnvDispl++] = v;
baseEnv.values[0]->attrs->push_back(Attr(primOp.name, v));
return v;
}
Value & EvalState::getBuiltin(const string & name)
{
return *baseEnv.values[0]->attrs->find(symbols.create(name))->value;

View file

@ -30,6 +30,8 @@ struct PrimOp
PrimOpFun fun;
size_t arity;
Symbol name;
std::vector<std::string> args;
const char * doc = nullptr;
};
@ -240,6 +242,8 @@ private:
Value * addPrimOp(const string & name,
size_t arity, PrimOpFun primOp);
Value * addPrimOp(PrimOp && primOp);
public:
Value & getBuiltin(const string & name);

View file

@ -445,12 +445,19 @@ static void prim_genericClosure(EvalState & state, const Pos & pos, Value * * ar
}
static void prim_abort(EvalState & state, const Pos & pos, Value * * args, Value & v)
{
PathSet context;
string s = state.coerceToString(pos, *args[0], context);
throw Abort("evaluation aborted with the following error message: '%1%'", s);
}
static RegisterPrimOp primop_abort({
.name = "abort",
.args = {"s"},
.doc = R"(
Abort Nix expression evaluation and print the error message *s*.
)",
.fun = [](EvalState & state, const Pos & pos, Value * * args, Value & v)
{
PathSet context;
string s = state.coerceToString(pos, *args[0], context);
throw Abort("evaluation aborted with the following error message: '%1%'", s);
}
});
static void prim_throw(EvalState & state, const Pos & pos, Value * * args, Value & v)
@ -2238,7 +2245,20 @@ RegisterPrimOp::RegisterPrimOp(std::string name, size_t arity, PrimOpFun fun,
std::optional<std::string> requiredFeature)
{
if (!primOps) primOps = new PrimOps;
primOps->push_back({name, arity, fun, requiredFeature});
primOps->push_back({
.name = name,
.args = {},
.arity = arity,
.requiredFeature = std::move(requiredFeature),
.fun = fun
});
}
RegisterPrimOp::RegisterPrimOp(Info && info)
{
if (!primOps) primOps = new PrimOps;
primOps->push_back(std::move(info));
}
@ -2314,7 +2334,6 @@ void EvalState::createBaseEnv()
addPrimOp("__isBool", 1, prim_isBool);
addPrimOp("__isPath", 1, prim_isPath);
addPrimOp("__genericClosure", 1, prim_genericClosure);
addPrimOp("abort", 1, prim_abort);
addPrimOp("__addErrorContext", 2, prim_addErrorContext);
addPrimOp("__tryEval", 1, prim_tryEval);
addPrimOp("__getEnv", 1, prim_getEnv);
@ -2431,7 +2450,13 @@ void EvalState::createBaseEnv()
if (RegisterPrimOp::primOps)
for (auto & primOp : *RegisterPrimOp::primOps)
if (!primOp.requiredFeature || settings.isExperimentalFeatureEnabled(*primOp.requiredFeature))
addPrimOp(primOp.name, primOp.arity, primOp.primOp);
addPrimOp({
.fun = primOp.fun,
.arity = std::max(primOp.args.size(), primOp.arity),
.name = symbols.create(primOp.name),
.args = std::move(primOp.args),
.doc = primOp.doc,
});
/* Now that we've added all primops, sort the `builtins' set,
because attribute lookups expect it to be sorted. */

View file

@ -10,9 +10,11 @@ struct RegisterPrimOp
struct Info
{
std::string name;
size_t arity;
PrimOpFun primOp;
std::vector<std::string> args;
size_t arity = 0;
const char * doc;
std::optional<std::string> requiredFeature;
PrimOpFun fun;
};
typedef std::vector<Info> PrimOps;
@ -26,6 +28,8 @@ struct RegisterPrimOp
size_t arity,
PrimOpFun fun,
std::optional<std::string> requiredFeature = {});
RegisterPrimOp(Info && info);
};
/* These primops are disabled without enableNativeCode, but plugins