10#include "lix/libexpr/gc-alloc.hh"
15#include "lix/libutil/checked-arithmetic.hh"
16#include "lix/libutil/concepts.hh"
17#include "lix/libutil/json-fwd.hh"
77using NixInt = checked::Checked<int64_t>;
78using NixFloat = double;
86 friend std::ostream & operator << (std::ostream & str,
const ExternalValueBase & v);
92 virtual std::ostream &
print(std::ostream & str)
const = 0;
109 virtual std::string
coerceToString(
EvalState & state,
const PosIdx & pos, NixStringContext & context,
bool copyMore,
bool copyToStore)
const;
121 NixStringContext & context,
bool copyToStore =
true)
const;
127 XMLWriter & doc, NixStringContext & context, PathSet & drvsSeen,
135std::ostream & operator << (std::ostream & str,
const ExternalValueBase & v);
139extern Expr *eBlackHoleAddr;
156 constexpr static path_t path{};
159 constexpr static list_t list{};
162 constexpr static attrs_t attrs{};
165 constexpr static thunk_t thunk{};
168 constexpr static null_t null{};
171 constexpr static app_t app{};
192 InternalType internalType;
194 friend std::string showType(
const Value & v);
205#define USING_VALUETYPE(name) using name = NewValueAs::name
206 USING_VALUETYPE(integer_t);
207 USING_VALUETYPE(floating_t);
208 USING_VALUETYPE(boolean_t);
209 USING_VALUETYPE(string_t);
210 USING_VALUETYPE(path_t);
211 USING_VALUETYPE(list_t);
212 USING_VALUETYPE(attrs_t);
213 USING_VALUETYPE(thunk_t);
214 USING_VALUETYPE(primop_t);
215 USING_VALUETYPE(app_t);
216 USING_VALUETYPE(null_t);
217 USING_VALUETYPE(primOpApp_t);
218 USING_VALUETYPE(lambda_t);
219 USING_VALUETYPE(external_t);
220 USING_VALUETYPE(blackhole_t);
221#undef USING_VALUETYPE
226 : internalType(static_cast<InternalType>(0))
246 : internalType(tFloat)
254 : internalType(tBool)
266 Value(string_t,
char const * strPtr,
char const ** contextPtr =
nullptr)
267 : internalType(tString)
268 ,
string({ .s = strPtr, .context = contextPtr })
276 Value(string_t, std::string_view copyFrom, NixStringContext
const & context = {})
277 : internalType(tString)
278 ,
string({ .s = gcCopyStringIfNeeded(copyFrom), .context =
nullptr })
280 if (context.empty()) {
286 this->
string.context = gcAllocType<char const *>(context.size() + 1);
289 for (NixStringContextElem
const & contextElem : context) {
290 this->
string.context[n] = gcCopyStringIfNeeded(contextElem.to_string());
295 this->
string.context[n] =
nullptr;
307 Value(string_t,
char const * strPtr, NixStringContext
const & context)
308 : internalType(tString)
309 ,
string({ .s = strPtr, .context =
nullptr })
311 if (context.empty()) {
317 this->
string.context = gcAllocType<char const *>(context.size() + 1);
320 for (NixStringContextElem
const & contextElem : context) {
321 this->
string.context[n] = gcCopyStringIfNeeded(contextElem.to_string());
326 this->
string.context[n] =
nullptr;
336 : internalType(tPath)
347 : internalType(tPath)
348 , _path(gcCopyStringIfNeeded(path.canonical().abs()))
364 Value(list_t, std::span<Value *> items)
366 if (items.size() == 1) {
367 this->internalType = tList1;
368 this->smallList[0] = items[0];
369 this->smallList[1] =
nullptr;
370 }
else if (items.size() == 2) {
371 this->internalType = tList2;
372 this->smallList[0] = items[0];
373 this->smallList[1] = items[1];
375 this->internalType = tListN;
376 this->bigList.size = items.size();
377 this->bigList.elems = items.data();
389 std::ranges::sized_range SizedIterableT,
392 Value(list_t, SizedIterableT & items, TransformerT
const & transformer)
394 if (items.size() == 1) {
395 this->internalType = tList1;
396 this->smallList[0] = transformer(*items.begin());
397 this->smallList[1] =
nullptr;
398 }
else if (items.size() == 2) {
399 this->internalType = tList2;
400 auto it = items.begin();
401 this->smallList[0] = transformer(*it);
403 this->smallList[1] = transformer(*it);
405 this->internalType = tListN;
406 this->bigList.size = items.size();
407 this->bigList.elems = gcAllocType<Value *>(items.size());
408 auto it = items.begin();
409 for (
size_t i = 0; i < items.size(); i++, it++) {
410 this->bigList.elems[i] = transformer(*it);
417 : internalType(tNull)
427 : internalType(tAttrs)
437 : internalType(tThunk)
438 , thunk({ .env = &env, .expr = &expr })
444 Value(primop_t, PrimOp & primop);
449 : internalType(tPrimOpApp)
450 , primOpApp({ .left = &lhs, .right = &rhs })
457 , app({ .left = &lhs, .right = &rhs })
463 : internalType(tExternal)
464 , external(&external)
475 : internalType(tLambda)
476 , lambda({ .env = &env, .fun = &lambda })
481 : internalType(tThunk)
482 , thunk({ .env =
nullptr, .expr = eBlackHoleAddr })
490 : internalType(rhs.internalType)
493 *
this = std::move(rhs);
496 Value & operator=(
Value const & rhs) =
default;
503 *
this =
static_cast<const Value &
>(rhs);
506 rhs.internalType =
static_cast<InternalType
>(0);
520 inline bool isThunk()
const {
return internalType == tThunk; };
521 inline bool isApp()
const {
return internalType == tApp; };
522 inline bool isBlackhole()
const
524 return internalType == tThunk && thunk.expr == eBlackHoleAddr;
528 inline bool isLambda()
const {
return internalType == tLambda; };
529 inline bool isPrimOp()
const {
return internalType == tPrimOp; };
530 inline bool isPrimOpApp()
const {
return internalType == tPrimOpApp; };
568 const char * * context;
577 uintptr_t _attrs_pad;
583 Value * smallList[2];
589 Value * left, * right;
597 uintptr_t _primop_pad;
600 Value * left, * right;
603 ExternalValueBase * external;
604 uintptr_t _external_pad;
608 uintptr_t _float_pad;
621 switch (internalType) {
622 case tInt:
return nInt;
623 case tBool:
return nBool;
624 case tString:
return nString;
625 case tPath:
return nPath;
626 case tNull:
return nNull;
627 case tAttrs:
return nAttrs;
628 case tList1:
case tList2:
case tListN:
return nList;
629 case tLambda:
case tPrimOp:
case tPrimOpApp:
return nFunction;
630 case tExternal:
return nExternal;
631 case tFloat:
return nFloat;
632 case tThunk:
case tApp:
return nThunk;
646 app.left = app.right = 0;
649 inline void mkInt(NixInt::Inner n)
654 inline void mkInt(NixInt n)
661 inline void mkBool(
bool b)
664 internalType = tBool;
668 inline void mkString(
const char * s,
const char * * context = 0)
670 internalType = tString;
672 string.context = context;
675 void mkString(std::string_view s);
677 void mkString(std::string_view s,
const NixStringContext & context);
679 void mkStringMove(
const char * s,
const NixStringContext & context);
681 void mkPath(
const SourcePath & path);
683 inline void mkPath(
const char * path)
686 internalType = tPath;
693 internalType = tNull;
696 inline void mkAttrs(Bindings * a)
699 internalType = tAttrs;
703 Value & mkAttrs(BindingsBuilder & bindings);
705 inline void mkList(
size_t size)
709 internalType = tList1;
711 internalType = tList2;
713 internalType = tListN;
718 inline void mkThunk(Env * e, Expr & ex)
720 internalType = tThunk;
732 inline void mkLambda(Env * e, ExprLambda * f)
734 internalType = tLambda;
739 inline void mkBlackhole()
741 internalType = tThunk;
742 thunk.expr = eBlackHoleAddr;
745 void mkPrimOp(PrimOp * p);
749 internalType = tPrimOpApp;
759 inline void mkExternal(ExternalValueBase * e)
762 internalType = tExternal;
766 inline void mkFloat(NixFloat n)
769 internalType = tFloat;
775 return internalType == tList1 || internalType == tList2 || internalType == tListN;
778 Value * * listElems()
780 return internalType == tList1 || internalType == tList2 ? smallList : bigList.elems;
783 Value *
const * listElems()
const
785 return internalType == tList1 || internalType == tList2 ? smallList : bigList.elems;
788 size_t listSize()
const
790 return internalType == tList1 ? 1 : internalType == tList2 ? 2 : bigList.size;
804 typedef Value *
const * iterator;
805 iterator _begin, _end;
806 iterator begin()
const {
return _begin; }
807 iterator end()
const {
return _end; }
810 auto begin = listElems();
811 return ListIterable { begin, begin + listSize() };
814 auto listItems()
const
816 struct ConstListIterable
818 typedef const Value *
const * iterator;
819 iterator _begin, _end;
820 iterator begin()
const {
return _begin; }
821 iterator end()
const {
return _end; }
824 auto begin = listElems();
825 return ConstListIterable { begin, begin + listSize() };
828 SourcePath path()
const
830 assert(internalType == tPath);
831 return SourcePath{CanonPath(_path)};
834 std::string_view str()
const
836 assert(internalType == tString);
837 return std::string_view(
string.s);
841using ValueVector = GcVector<Value *>;
842using ValueMap = GcMap<Symbol, Value *>;
843using ValueVectorMap = std::map<Symbol, ValueVector>;
Definition attr-set.hh:128
Definition attr-set.hh:48
virtual JSON printValueAsJSON(EvalState &state, bool strict, NixStringContext &context, bool copyToStore=true) const
Definition value-to-json.cc:117
virtual std::string showType() const =0
virtual bool operator==(const ExternalValueBase &b) const
Definition eval.cc:2898
virtual std::string typeOf() const =0
virtual std::ostream & print(std::ostream &str) const =0
virtual std::string coerceToString(EvalState &state, const PosIdx &pos, NixStringContext &context, bool copyMore, bool copyToStore) const
Definition eval.cc:2890
virtual void printValueAsXML(EvalState &state, bool strict, bool location, XMLWriter &doc, NixStringContext &context, PathSet &drvsSeen, const PosIdx pos) const
Definition value-to-xml.cc:165
Definition xml-writer.hh:17
Definition concepts.hh:20
Options for printing Nix values.
Definition nixexpr.hh:446
Definition nixexpr.hh:104
Definition print-options.hh:39
Definition source-path.hh:23
Value(path_t, SourcePath const &path)
Definition value.hh:346
Value(floating_t, NixFloat f)
Definition value.hh:245
uintptr_t _empty[2]
Definition value.hh:536
static Value EMPTY_LIST
Definition value.hh:201
Value(boolean_t, bool b)
Definition value.hh:253
Value(string_t, char const *strPtr, char const **contextPtr=nullptr)
Definition value.hh:266
Value(null_t)
Constructs a nix language value of the singleton type "null".
Definition value.hh:416
Value(Value &&rhs)
Definition value.hh:489
Value(external_t, ExternalValueBase &external)
Definition value.hh:462
Value(path_t, char const *strPtr)
Definition value.hh:335
Value(list_t, std::span< Value * > items)
Definition value.hh:364
Value(integer_t, NixInt i)
Definition value.hh:232
Value & operator=(Value &&rhs)
Definition value.hh:501
Value()
Definition value.hh:225
Value(thunk_t, Env &env, Expr &expr)
Definition value.hh:436
Value(blackhole_t)
Constructs an evil thunk, whose evaluation represents infinite recursion.
Definition value.hh:480
Value(string_t, std::string_view copyFrom, NixStringContext const &context={})
Definition value.hh:276
ValueType type(bool invalidIsThunk=false) const
Definition value.hh:619
Value(lambda_t, Env &env, ExprLambda &lambda)
Definition value.hh:474
void clearValue()
Definition value.hh:644
Value(attrs_t, Bindings *bindings)
Definition value.hh:426
struct nix::Value::@131353355017135142023021222140250366363001142156::@053163235026302364354361147001043243051215073166 string
Value(list_t, SizedIterableT &items, TransformerT const &transformer)
Definition value.hh:392
Value(string_t, char const *strPtr, NixStringContext const &context)
Definition value.hh:307
Value(primOpApp_t, Value &lhs, Value &rhs)
Definition value.hh:448
PrimOp * primOpAppPrimOp() const
Definition value.cc:50
Value(app_t, Value &lhs, Value &rhs)
Definition value.hh:455
bool isTrivial() const
Definition value.cc:38
ValueType
Definition value.hh:48
std::shared_ptr< Value * > RootValue
Definition value.hh:848