about summary refs log tree commit diff
path: root/src/libexpr
diff options
context:
space:
mode:
authorShea Levy <shea@shealevy.com>2018-02-08T18·00-0500
committerShea Levy <shea@shealevy.com>2018-02-08T19·35-0500
commit081f14a169d36243f97263acb41fb108af243619 (patch)
tree563a1287be33bff5b2d36d38a9e77338425d45b4 /src/libexpr
parent88cd2d41acb994684a3e4ead1b1676019f43b4b6 (diff)
Allow using RegisterPrimop to define constants.
This enables plugins to add new constants, as well as new primops.
Diffstat (limited to 'src/libexpr')
-rw-r--r--src/libexpr/eval.cc8
-rw-r--r--src/libexpr/eval.hh2
-rw-r--r--src/libexpr/primops.hh3
3 files changed, 11 insertions, 2 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index 0b0a0f7b1790..1f3bbc0a53bd 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -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);
diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh
index 9e3d30d95f49..51905d7e1c62 100644
--- a/src/libexpr/eval.hh
+++ b/src/libexpr/eval.hh
@@ -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);
diff --git a/src/libexpr/primops.hh b/src/libexpr/primops.hh
index 39d23b04a5ce..31bf3f84f6c7 100644
--- a/src/libexpr/primops.hh
+++ b/src/libexpr/primops.hh
@@ -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);
 };