forked from lix-project/lix
* A new primop `builtins', which returns an attribute set containing
all the primops. This allows Nix expressions to test for new primops and take appropriate action if they're not available. For instance, rather than calling a primop `foo' directly, they could say `if builtins ? foo then builtins.foo ... else ...'.
This commit is contained in:
parent
68515b5a96
commit
4a053bfdfd
|
@ -7,6 +7,30 @@
|
||||||
#include "nixexpr-ast.hh"
|
#include "nixexpr-ast.hh"
|
||||||
|
|
||||||
|
|
||||||
|
static Expr primBuiltins(EvalState & state, const ATermVector & args)
|
||||||
|
{
|
||||||
|
/* Return an attribute set containing all primops. This allows
|
||||||
|
Nix expressions to test for new primops and take appropriate
|
||||||
|
action if they're not available. For instance, rather than
|
||||||
|
calling a primop `foo' directly, they could say `if builtins ?
|
||||||
|
foo then builtins.foo ... else ...'. */
|
||||||
|
|
||||||
|
ATermMap builtins(128);
|
||||||
|
|
||||||
|
for (ATermMap::const_iterator i = state.primOps.begin();
|
||||||
|
i != state.primOps.end(); ++i)
|
||||||
|
{
|
||||||
|
string name = aterm2String(i->key);
|
||||||
|
if (string(name, 0, 2) == "__")
|
||||||
|
name = string(name, 2);
|
||||||
|
/* !!! should use makePrimOp here, I guess. */
|
||||||
|
builtins.set(toATerm(name), makeAttrRHS(makeVar(i->key), makeNoPos()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return makeAttrs(builtins);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Load and evaluate an expression from path specified by the
|
/* Load and evaluate an expression from path specified by the
|
||||||
argument. */
|
argument. */
|
||||||
static Expr primImport(EvalState & state, const ATermVector & args)
|
static Expr primImport(EvalState & state, const ATermVector & args)
|
||||||
|
@ -660,6 +684,8 @@ static Expr primRelativise(EvalState & state, const ATermVector & args)
|
||||||
|
|
||||||
void EvalState::addPrimOps()
|
void EvalState::addPrimOps()
|
||||||
{
|
{
|
||||||
|
addPrimOp("builtins", 0, primBuiltins);
|
||||||
|
|
||||||
addPrimOp("true", 0, primTrue);
|
addPrimOp("true", 0, primTrue);
|
||||||
addPrimOp("false", 0, primFalse);
|
addPrimOp("false", 0, primFalse);
|
||||||
addPrimOp("null", 0, primNull);
|
addPrimOp("null", 0, primNull);
|
||||||
|
|
1
tests/lang/eval-okay-builtins.exp
Normal file
1
tests/lang/eval-okay-builtins.exp
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Path("/foo")
|
12
tests/lang/eval-okay-builtins.nix
Normal file
12
tests/lang/eval-okay-builtins.nix
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
assert builtins ? currentSystem;
|
||||||
|
assert !builtins ? __currentSystem;
|
||||||
|
|
||||||
|
let {
|
||||||
|
|
||||||
|
x = if builtins ? dirOf then builtins.dirOf /foo/bar else "";
|
||||||
|
|
||||||
|
y = if builtins ? fnord then builtins.fnord "foo" else "";
|
||||||
|
|
||||||
|
body = x + y;
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue