33
44#include < cassert>
55#include < climits>
6+ #include < span>
67
78#include " symbol-table.hh"
89#include " value/context.hh"
@@ -158,64 +159,72 @@ public:
158159 inline bool isPrimOp () const { return internalType == tPrimOp; };
159160 inline bool isPrimOpApp () const { return internalType == tPrimOpApp; };
160161
161- union
162- {
163- NixInt integer;
164- bool boolean;
162+ /* *
163+ * Strings in the evaluator carry a so-called `context` which
164+ * is a list of strings representing store paths. This is to
165+ * allow users to write things like
166+ *
167+ * "--with-freetype2-library=" + freetype + "/lib"
168+ *
169+ * where `freetype` is a derivation (or a source to be copied
170+ * to the store). If we just concatenated the strings without
171+ * keeping track of the referenced store paths, then if the
172+ * string is used as a derivation attribute, the derivation
173+ * will not have the correct dependencies in its inputDrvs and
174+ * inputSrcs.
175+
176+ * The semantics of the context is as follows: when a string
177+ * with context C is used as a derivation attribute, then the
178+ * derivations in C will be added to the inputDrvs of the
179+ * derivation, and the other store paths in C will be added to
180+ * the inputSrcs of the derivations.
181+
182+ * For canonicity, the store paths should be in sorted order.
183+ */
184+ struct StringWithContext {
185+ const char * c_str;
186+ const char * * context; // must be in sorted order
187+ };
165188
166- /* *
167- * Strings in the evaluator carry a so-called `context` which
168- * is a list of strings representing store paths. This is to
169- * allow users to write things like
189+ struct Path {
190+ InputAccessor * accessor;
191+ const char * path;
192+ };
170193
171- * "--with-freetype2-library=" + freetype + "/lib"
194+ struct ClosureThunk {
195+ Env * env;
196+ Expr * expr;
197+ };
172198
173- * where `freetype` is a derivation (or a source to be copied
174- * to the store). If we just concatenated the strings without
175- * keeping track of the referenced store paths, then if the
176- * string is used as a derivation attribute, the derivation
177- * will not have the correct dependencies in its inputDrvs and
178- * inputSrcs.
199+ struct FunctionApplicationThunk {
200+ Value * left, * right;
201+ };
179202
180- * The semantics of the context is as follows: when a string
181- * with context C is used as a derivation attribute, then the
182- * derivations in C will be added to the inputDrvs of the
183- * derivation, and the other store paths in C will be added to
184- * the inputSrcs of the derivations.
203+ struct Lambda {
204+ Env * env;
205+ ExprLambda * fun;
206+ };
185207
186- * For canonicity, the store paths should be in sorted order.
187- */
188- struct {
189- const char * c_str;
190- const char * * context; // must be in sorted order
191- } string;
208+ union
209+ {
210+ NixInt integer;
211+ bool boolean;
192212
193- struct {
194- InputAccessor * accessor;
195- const char * path;
196- } _path;
213+ StringWithContext string;
214+
215+ Path _path;
197216
198217 Bindings * attrs;
199218 struct {
200219 size_t size;
201220 Value * * elems;
202221 } bigList;
203222 Value * smallList[2 ];
204- struct {
205- Env * env;
206- Expr * expr;
207- } thunk;
208- struct {
209- Value * left, * right;
210- } app;
211- struct {
212- Env * env;
213- ExprLambda * fun;
214- } lambda;
223+ ClosureThunk thunk;
224+ FunctionApplicationThunk app;
225+ Lambda lambda;
215226 PrimOp * primOp;
216- struct {
217- Value * left, * right;
218- } primOpApp;
227+ FunctionApplicationThunk primOpApp;
219228 ExternalValueBase * external;
220229 NixFloat fpoint;
221230 };
@@ -387,7 +396,13 @@ public:
387396 return internalType == tList1 || internalType == tList2 ? smallList : bigList.elems ;
388397 }
389398
390- const Value * const * listElems () const
399+ std::span<Value * const > listItems () const
400+ {
401+ assert (isList ());
402+ return std::span<Value * const >(listElems (), listSize ());
403+ }
404+
405+ Value * const * listElems () const
391406 {
392407 return internalType == tList1 || internalType == tList2 ? smallList : bigList.elems ;
393408 }
@@ -406,34 +421,6 @@ public:
406421 */
407422 bool isTrivial () const ;
408423
409- auto listItems ()
410- {
411- struct ListIterable
412- {
413- typedef Value * const * iterator;
414- iterator _begin, _end;
415- iterator begin () const { return _begin; }
416- iterator end () const { return _end; }
417- };
418- assert (isList ());
419- auto begin = listElems ();
420- return ListIterable { begin, begin + listSize () };
421- }
422-
423- auto listItems () const
424- {
425- struct ConstListIterable
426- {
427- typedef const Value * const * iterator;
428- iterator _begin, _end;
429- iterator begin () const { return _begin; }
430- iterator end () const { return _end; }
431- };
432- assert (isList ());
433- auto begin = listElems ();
434- return ConstListIterable { begin, begin + listSize () };
435- }
436-
437424 SourcePath path () const
438425 {
439426 assert (internalType == tPath);
0 commit comments