aboutsummaryrefslogtreecommitdiff
path: root/src/libexpr/value.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/libexpr/value.cc')
-rw-r--r--src/libexpr/value.cc106
1 files changed, 106 insertions, 0 deletions
diff --git a/src/libexpr/value.cc b/src/libexpr/value.cc
new file mode 100644
index 000000000..7e172f989
--- /dev/null
+++ b/src/libexpr/value.cc
@@ -0,0 +1,106 @@
+#include "value.hh"
+
+#include <ostream>
+
+#include "eval.hh"
+#include "print.hh"
+
+
+namespace nix
+{
+
+static void copyContextToValue(Value & v, const NixStringContext & context)
+{
+ if (!context.empty()) {
+ size_t n = 0;
+ v.string.context = gcAllocType<char const *>(context.size() + 1);
+ for (auto & i : context)
+ v.string.context[n++] = gcCopyStringIfNeeded(i.to_string());
+ v.string.context[n] = 0;
+ }
+}
+
+Value::Value(primop_t, PrimOp & primop)
+ : internalType(tPrimOp)
+ , primOp(&primop)
+ , _primop_pad(0)
+{
+ primop.check();
+}
+
+
+void Value::print(EvalState & state, std::ostream & str, PrintOptions options)
+{
+ printValue(state, str, *this, options);
+}
+
+PosIdx Value::determinePos(const PosIdx pos) const
+{
+ // Allow selecting a subset of enum values
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wswitch-enum"
+ switch (internalType) {
+ case tAttrs: return attrs->pos;
+ case tLambda: return lambda.fun->pos;
+ case tApp: return app.left->determinePos(pos);
+ default: return pos;
+ }
+ #pragma GCC diagnostic pop
+}
+
+bool Value::isTrivial() const
+{
+ return
+ internalType != tApp
+ && internalType != tPrimOpApp
+ && (internalType != tThunk
+ || (dynamic_cast<ExprAttrs *>(thunk.expr)
+ && static_cast<ExprAttrs *>(thunk.expr)->dynamicAttrs.empty())
+ || dynamic_cast<ExprLambda *>(thunk.expr)
+ || dynamic_cast<ExprList *>(thunk.expr));
+}
+
+PrimOp * Value::primOpAppPrimOp() const
+{
+ Value * left = primOpApp.left;
+ while (left && !left->isPrimOp()) {
+ left = left->primOpApp.left;
+ }
+
+ if (!left)
+ return nullptr;
+ return left->primOp;
+}
+
+void Value::mkPrimOp(PrimOp * p)
+{
+ p->check();
+ clearValue();
+ internalType = tPrimOp;
+ primOp = p;
+}
+
+void Value::mkString(std::string_view s)
+{
+ mkString(gcCopyStringIfNeeded(s));
+}
+
+void Value::mkString(std::string_view s, const NixStringContext & context)
+{
+ mkString(s);
+ copyContextToValue(*this, context);
+}
+
+void Value::mkStringMove(const char * s, const NixStringContext & context)
+{
+ mkString(s);
+ copyContextToValue(*this, context);
+}
+
+
+void Value::mkPath(const SourcePath & path)
+{
+ mkPath(gcCopyStringIfNeeded(path.path.abs()));
+}
+
+}