* 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:
Eelco Dolstra 2006-08-23 14:39:11 +00:00
parent 68515b5a96
commit 4a053bfdfd
3 changed files with 39 additions and 0 deletions

View file

@ -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);

View file

@ -0,0 +1 @@
Path("/foo")

View 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;
}