aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2016-04-13 11:15:45 +0200
committerEelco Dolstra <eelco.dolstra@logicblox.com>2016-04-14 12:50:01 +0200
commit12b257f045fcaf8f5c42fe6d153419242c11a6d6 (patch)
treec3349ac973a1965d0a280c2cbebc0b049a24075b
parent96515b0c0d8c515fff60ef3b72cd7cc9837142c3 (diff)
Make primop registration pluggable
This way we don't have to put all primops in one giant file.
-rw-r--r--src/libexpr/eval.hh4
-rw-r--r--src/libexpr/local.mk2
-rw-r--r--src/libexpr/primops.cc15
-rw-r--r--src/libexpr/primops.hh15
4 files changed, 33 insertions, 3 deletions
diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh
index 40e05712b..50093d3fc 100644
--- a/src/libexpr/eval.hh
+++ b/src/libexpr/eval.hh
@@ -26,9 +26,9 @@ typedef void (* PrimOpFun) (EvalState & state, const Pos & pos, Value * * args,
struct PrimOp
{
PrimOpFun fun;
- unsigned int arity;
+ size_t arity;
Symbol name;
- PrimOp(PrimOpFun fun, unsigned int arity, Symbol name)
+ PrimOp(PrimOpFun fun, size_t arity, Symbol name)
: fun(fun), arity(arity), name(name) { }
};
diff --git a/src/libexpr/local.mk b/src/libexpr/local.mk
index 5de9ccc6d..620050a13 100644
--- a/src/libexpr/local.mk
+++ b/src/libexpr/local.mk
@@ -4,7 +4,7 @@ libexpr_NAME = libnixexpr
libexpr_DIR := $(d)
-libexpr_SOURCES := $(wildcard $(d)/*.cc) $(d)/lexer-tab.cc $(d)/parser-tab.cc
+libexpr_SOURCES := $(wildcard $(d)/*.cc) $(wildcard $(d)/primops/*.cc) $(d)/lexer-tab.cc $(d)/parser-tab.cc
libexpr_CXXFLAGS := -Wno-deprecated-register
diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc
index aaef467c0..816827d6a 100644
--- a/src/libexpr/primops.cc
+++ b/src/libexpr/primops.cc
@@ -10,6 +10,7 @@
#include "util.hh"
#include "value-to-json.hh"
#include "value-to-xml.hh"
+#include "primops.hh"
#include <sys/types.h>
#include <sys/stat.h>
@@ -1725,6 +1726,16 @@ static void prim_fetchTarball(EvalState & state, const Pos & pos, Value * * args
*************************************************************/
+RegisterPrimOp::PrimOps * RegisterPrimOp::primOps;
+
+
+RegisterPrimOp::RegisterPrimOp(std::string name, size_t arity, PrimOpFun fun)
+{
+ if (!primOps) primOps = new PrimOps;
+ primOps->emplace_back(name, arity, fun);
+}
+
+
void EvalState::createBaseEnv()
{
baseEnv.up = 0;
@@ -1889,6 +1900,10 @@ void EvalState::createBaseEnv()
}
addConstant("__nixPath", v);
+ if (RegisterPrimOp::primOps)
+ for (auto & primOp : *RegisterPrimOp::primOps)
+ addPrimOp(std::get<0>(primOp), std::get<1>(primOp), std::get<2>(primOp));
+
/* Now that we've added all primops, sort the `builtins' set,
because attribute lookups expect it to be sorted. */
baseEnv.values[0]->attrs->sort();
diff --git a/src/libexpr/primops.hh b/src/libexpr/primops.hh
new file mode 100644
index 000000000..39d23b04a
--- /dev/null
+++ b/src/libexpr/primops.hh
@@ -0,0 +1,15 @@
+#include "eval.hh"
+
+#include <tuple>
+#include <vector>
+
+namespace nix {
+
+struct RegisterPrimOp
+{
+ typedef std::vector<std::tuple<std::string, size_t, PrimOpFun>> PrimOps;
+ static PrimOps * primOps;
+ RegisterPrimOp(std::string name, size_t arity, PrimOpFun fun);
+};
+
+}