about summary refs log tree commit diff
path: root/src/libexpr/primops.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/libexpr/primops.cc')
-rw-r--r--src/libexpr/primops.cc26
1 files changed, 26 insertions, 0 deletions
diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc
index dfc565b431..bc4db2d813 100644
--- a/src/libexpr/primops.cc
+++ b/src/libexpr/primops.cc
@@ -7,6 +7,30 @@
 #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
    argument. */ 
 static Expr primImport(EvalState & state, const ATermVector & args)
@@ -660,6 +684,8 @@ static Expr primRelativise(EvalState & state, const ATermVector & args)
 
 void EvalState::addPrimOps()
 {
+    addPrimOp("builtins", 0, primBuiltins);
+        
     addPrimOp("true", 0, primTrue);
     addPrimOp("false", 0, primFalse);
     addPrimOp("null", 0, primNull);