Nix 2.93.3
Lix: A modern, delicious implementation of the Nix package manager; unstable internal interfaces
Loading...
Searching...
No Matches
nixexpr.hh
Go to the documentation of this file.
1#pragma once
3
4#include <map>
5#include <memory>
6#include <vector>
7
10#include "lix/libutil/json.hh"
14
15namespace nix {
16
17struct Env;
18struct Value;
19class Evaluator;
20struct ExprWith;
21struct StaticEnv;
22
23
27struct AttrName
28{
29 PosIdx pos;
30 Symbol symbol;
31 std::unique_ptr<Expr> expr;
32 AttrName(PosIdx pos, Symbol s);
33 AttrName(PosIdx pos, std::unique_ptr<Expr> e);
34};
35
36typedef std::vector<AttrName> AttrPath;
37
38std::string showAttrPath(const SymbolTable & symbols, const AttrPath & attrPath);
39JSON printAttrPathToJson(const SymbolTable & symbols, const AttrPath & attrPath);
40
41
42/* Abstract syntax of Nix expressions. */
43
44struct ExprDebugFrame;
45struct ExprLiteral;
46struct ExprString;
47struct ExprPath;
48struct ExprVar;
49struct ExprInheritFrom;
50struct ExprSelect;
51struct ExprOpHasAttr;
52struct ExprSet;
53struct ExprList;
54struct ExprLambda;
55struct ExprCall;
56struct ExprLet;
57struct ExprWith;
58struct ExprIf;
59struct ExprAssert;
60struct ExprOpNot;
61struct ExprOpEq;
62struct ExprOpNEq;
63struct ExprOpAnd;
64struct ExprOpOr;
65struct ExprOpImpl;
66struct ExprOpUpdate;
67struct ExprOpConcatLists;
68struct ExprConcatStrings;
69struct ExprPos;
70struct ExprBlackHole;
71
73{
74 virtual void visit(ExprDebugFrame & e, std::unique_ptr<Expr> & ptr) = 0;
75 virtual void visit(ExprLiteral & e, std::unique_ptr<Expr> & ptr) = 0;
76 virtual void visit(ExprVar & e, std::unique_ptr<Expr> & ptr) = 0;
77 virtual void visit(ExprInheritFrom & e, std::unique_ptr<Expr> & ptr) = 0;
78 virtual void visit(ExprSelect & e, std::unique_ptr<Expr> & ptr) = 0;
79 virtual void visit(ExprOpHasAttr & e, std::unique_ptr<Expr> & ptr) = 0;
80 virtual void visit(ExprSet & e, std::unique_ptr<Expr> & ptr) = 0;
81 virtual void visit(ExprList & e, std::unique_ptr<Expr> & ptr) = 0;
82 virtual void visit(ExprLambda & e, std::unique_ptr<Expr> & ptr) = 0;
83 virtual void visit(ExprCall & e, std::unique_ptr<Expr> & ptr) = 0;
84 virtual void visit(ExprLet & e, std::unique_ptr<Expr> & ptr) = 0;
85 virtual void visit(ExprWith & e, std::unique_ptr<Expr> & ptr) = 0;
86 virtual void visit(ExprIf & e, std::unique_ptr<Expr> & ptr) = 0;
87 virtual void visit(ExprAssert & e, std::unique_ptr<Expr> & ptr) = 0;
88 virtual void visit(ExprOpNot & e, std::unique_ptr<Expr> & ptr) = 0;
89 virtual void visit(ExprOpEq & e, std::unique_ptr<Expr> & ptr) = 0;
90 virtual void visit(ExprOpNEq & e, std::unique_ptr<Expr> & ptr) = 0;
91 virtual void visit(ExprOpAnd & e, std::unique_ptr<Expr> & ptr) = 0;
92 virtual void visit(ExprOpOr & e, std::unique_ptr<Expr> & ptr) = 0;
93 virtual void visit(ExprOpImpl & e, std::unique_ptr<Expr> & ptr) = 0;
94 virtual void visit(ExprOpUpdate & e, std::unique_ptr<Expr> & ptr) = 0;
95 virtual void visit(ExprOpConcatLists & e, std::unique_ptr<Expr> & ptr) = 0;
96 virtual void visit(ExprConcatStrings & e, std::unique_ptr<Expr> & ptr) = 0;
97 virtual void visit(ExprPos & e, std::unique_ptr<Expr> & ptr) = 0;
98 virtual void visit(ExprBlackHole & e, std::unique_ptr<Expr> & ptr) = 0;
99
100 void visit(std::unique_ptr<Expr> & ptr);
101};
102
103struct Expr
104{
105protected:
106 Expr(Expr &&) = default;
107 Expr & operator=(Expr &&) = default;
108 Expr(const PosIdx pos) : pos(pos) {};
109
110public:
111 struct AstSymbols {
112 Symbol sub, lessThan, mul, div, or_, findFile, nixPath, body, overrides;
113 };
114
115 PosIdx pos;
116
117 Expr() = default;
118 Expr(const Expr &) = delete;
119 Expr & operator=(const Expr &) = delete;
120 virtual ~Expr() { };
121
122 static std::unique_ptr<Expr> finalize(
123 std::unique_ptr<Expr> parsed, Evaluator & es, const std::shared_ptr<const StaticEnv> & env
124 );
125
126 virtual JSON toJSON(const SymbolTable & symbols) const;
127 virtual void accept(ExprVisitor & ev, std::unique_ptr<Expr> & ptr) = 0;
128 virtual void eval(EvalState & state, Env & env, Value & v);
129 virtual Value * maybeThunk(EvalState & state, Env & env);
130 virtual void setName(Symbol name);
131 PosIdx getPos() const { return pos; }
132
133 template<typename E>
134 E & cast()
135 {
136 return dynamic_cast<E &>(*this);
137 }
138
139 template<typename E>
140 E * try_cast()
141 {
142 return dynamic_cast<E *>(this);
143 }
144};
145
146inline void ExprVisitor::visit(std::unique_ptr<Expr> & ptr)
147{
148 ptr->accept(*this, ptr);
149}
150
151struct ExprDebugFrame : Expr
152{
153 std::unique_ptr<Expr> inner;
154 std::string message;
155
156 ExprDebugFrame(PosIdx pos, std::unique_ptr<Expr> inner, std::string message)
157 : Expr(pos)
158 , inner(std::move(inner))
159 , message(std::move(message))
160 {
161 }
162
163 JSON toJSON(const SymbolTable & symbols) const override
164 {
165 return inner->toJSON(symbols);
166 }
167 void eval(EvalState & state, Env & env, Value & v) override;
168 void accept(ExprVisitor & ev, std::unique_ptr<Expr> & ptr) override { ev.visit(*this, ptr); }
169};
170
171struct ExprLiteral : Expr
172{
173protected:
174 Value v;
175 ExprLiteral(const PosIdx pos) : Expr(pos) {};
176public:
177
178 ExprLiteral(const PosIdx pos, NewValueAs::integer_t, NixInt n) : Expr(pos) { v.mkInt(n); };
179 ExprLiteral(const PosIdx pos, NewValueAs::integer_t, NixInt::Inner n) : Expr(pos) { v.mkInt(n); };
180 ExprLiteral(const PosIdx pos, NewValueAs::floating_t, NixFloat nf) : Expr(pos) { v.mkFloat(nf); };
181 Value * maybeThunk(EvalState & state, Env & env) override;
182 JSON toJSON(const SymbolTable & symbols) const override;
183 void eval(EvalState & state, Env & env, Value & v) override;
184 void accept(ExprVisitor & ev, std::unique_ptr<Expr> & ptr) override { ev.visit(*this, ptr); }
185};
186
187struct ExprString : ExprLiteral
188{
189 std::string s;
190 ExprString(const PosIdx pos, std::string &&s) : ExprLiteral(pos), s(std::move(s)) { v.mkString(this->s.data()); };
191};
192
193struct ExprPath : ExprLiteral
194{
195 std::string s;
196 ExprPath(const PosIdx pos, std::string s) : ExprLiteral(pos), s(std::move(s)) { v.mkPath(this->s.c_str()); };
197};
198
199typedef uint32_t Level;
200typedef uint32_t Displacement;
201
202struct ExprVar : Expr
203{
204 Symbol name;
205
206 /* Whether the variable comes from an environment (e.g. a rec, let
207 or function argument) or from a "with".
208
209 `nullptr`: Not from a `with`.
210 Valid pointer: the nearest, innermost `with` expression to query first. */
211 ExprWith * fromWith;
212
213 /* In the former case, the value is obtained by going `level`
214 levels up from the current environment and getting the
215 `displ`th value in that environment. In the latter case, the
216 value is obtained by getting the attribute named `name` from
217 the set stored in the environment that is `level` levels up
218 from the current one.*/
219 Level level;
220 Displacement displ;
221
222 /* Variables like `__sub` as generated from expressions like `5 - 3` shouldn't be overridden.
223 * This is implemented by having a blessed "root" env that contains the definitions (usually `builtins`)
224 * and checking that this var only binds against that env.
225 */
226 bool needsRoot;
227
228 ExprVar(Symbol name) : name(name), needsRoot(false) { };
229 ExprVar(const PosIdx & pos, Symbol name, bool needsRoot = false) : Expr(pos), name(name), needsRoot(needsRoot) { };
230 Value * maybeThunk(EvalState & state, Env & env) override;
231 JSON toJSON(const SymbolTable & symbols) const override;
232 void eval(EvalState & state, Env & env, Value & v) override;
233 void accept(ExprVisitor & ev, std::unique_ptr<Expr> & ptr) override { ev.visit(*this, ptr); }
234};
235
241struct ExprInheritFrom : Expr
242{
243 Expr & fromExpr;
244 Displacement displ;
245
246 ExprInheritFrom(PosIdx pos, Displacement displ, Expr & fromExpr)
247 : Expr(pos), fromExpr(fromExpr), displ(displ)
248 {
249 }
250
251 JSON toJSON(const SymbolTable & symbols) const override;
252 void eval(EvalState & state, Env & env, Value & v) override;
253 void accept(ExprVisitor & ev, std::unique_ptr<Expr> & ptr) override { ev.visit(*this, ptr); }
254};
255
256struct ExprSelect : Expr
257{
259 std::unique_ptr<Expr> e;
260
264 std::unique_ptr<Expr> def;
265
267 AttrPath attrPath;
268
269 ExprSelect(const PosIdx & pos, std::unique_ptr<Expr> e, AttrPath attrPath, std::unique_ptr<Expr> def) : Expr(pos), e(std::move(e)), def(std::move(def)), attrPath(std::move(attrPath)) { };
270 ExprSelect(const PosIdx & pos, std::unique_ptr<Expr> e, const PosIdx namePos, Symbol name) : Expr(pos), e(std::move(e)) { attrPath.push_back(AttrName(namePos, name)); };
271 JSON toJSON(const SymbolTable & symbols) const override;
272 void eval(EvalState & state, Env & env, Value & v) override;
273 void accept(ExprVisitor & ev, std::unique_ptr<Expr> & ptr) override { ev.visit(*this, ptr); }
274};
275
276struct ExprOpHasAttr : Expr
277{
278 std::unique_ptr<Expr> e;
279 AttrPath attrPath;
280 ExprOpHasAttr(const PosIdx & pos, std::unique_ptr<Expr> e, AttrPath attrPath) : Expr(pos), e(std::move(e)), attrPath(std::move(attrPath)) { };
281 JSON toJSON(const SymbolTable & symbols) const override;
282 void eval(EvalState & state, Env & env, Value & v) override;
283 void accept(ExprVisitor & ev, std::unique_ptr<Expr> & ptr) override { ev.visit(*this, ptr); }
284};
285
286/* Helper struct to contain the data shared across lets and sets */
287struct ExprAttrs
288{
289 ExprAttrs() = default;
290 ExprAttrs(const ExprAttrs &) = delete;
291 ExprAttrs & operator=(const ExprAttrs &) = delete;
292 ExprAttrs(ExprAttrs &&) = default;
293 ExprAttrs & operator=(ExprAttrs &&) = default;
294 virtual ~ExprAttrs() = default;
295
296 struct AttrDef {
305
306 Kind kind;
307 std::unique_ptr<Expr> e;
308 PosIdx pos;
309 Displacement displ; // displacement
310 AttrDef(std::unique_ptr<Expr> e, const PosIdx & pos, Kind kind = Kind::Plain)
311 : kind(kind), e(std::move(e)), pos(pos) { };
312 AttrDef() { };
313
314 template<typename T>
315 T chooseByKind(const T & plain, const T & inherited, const T & inheritedFrom) const
316 {
317 switch (kind) {
318 case Kind::Plain:
319 return plain;
320 case Kind::Inherited:
321 return inherited;
322 default:
324 return inheritedFrom;
325 }
326 }
327 };
328 typedef std::map<Symbol, AttrDef> AttrDefs;
329 AttrDefs attrs;
330 std::unique_ptr<std::list<std::unique_ptr<Expr>>> inheritFromExprs;
331 struct DynamicAttrDef {
332 std::unique_ptr<Expr> nameExpr, valueExpr;
333 PosIdx pos;
334 DynamicAttrDef(std::unique_ptr<Expr> nameExpr, std::unique_ptr<Expr> valueExpr, const PosIdx & pos)
335 : nameExpr(std::move(nameExpr)), valueExpr(std::move(valueExpr)), pos(pos) { };
336 };
337 typedef std::vector<DynamicAttrDef> DynamicAttrDefs;
338 DynamicAttrDefs dynamicAttrs;
339
340 std::shared_ptr<const StaticEnv> buildRecursiveEnv(const std::shared_ptr<const StaticEnv> & env);
341 std::shared_ptr<const StaticEnv> bindInheritSources(ExprVisitor & e, const StaticEnv & env);
342 Env * buildInheritFromEnv(EvalState & state, Env & up);
343 void addBindingsToJSON(JSON & out, const SymbolTable & symbols) const;
344};
345
346struct ExprSet : Expr, ExprAttrs {
347 bool recursive = false;
348
349 ExprSet(const PosIdx &pos, bool recursive = false) : Expr(pos), recursive(recursive) { };
350 ExprSet() { };
351 JSON toJSON(const SymbolTable & symbols) const override;
352 void eval(EvalState & state, Env & env, Value & v) override;
353 void accept(ExprVisitor & ev, std::unique_ptr<Expr> & ptr) override { ev.visit(*this, ptr); }
354};
355
357 std::map<Symbol, std::unique_ptr<Expr>> symbols;
358
359 void finalize(Evaluator & es, const std::shared_ptr<const StaticEnv> & env) {
360 for (auto & [_, e] : symbols)
361 e = Expr::finalize(std::move(e), es, env);
362 }
363};
364
365struct ExprList : Expr
366{
367 std::vector<std::unique_ptr<Expr>> elems;
368 ExprList(PosIdx pos) : Expr(pos) { };
369 JSON toJSON(const SymbolTable & symbols) const override;
370 void eval(EvalState & state, Env & env, Value & v) override;
371 void accept(ExprVisitor & ev, std::unique_ptr<Expr> & ptr) override { ev.visit(*this, ptr); }
372 Value * maybeThunk(EvalState & state, Env & env) override;
373};
374
375struct Pattern {
379
380 Pattern() = default;
381 explicit Pattern(Symbol name) : name(name) { }
382 virtual ~Pattern() = default;
383
384 virtual std::shared_ptr<const StaticEnv> buildEnv(const StaticEnv * up) = 0;
385 virtual void accept(ExprVisitor & ev) = 0;
386 virtual Env & match(ExprLambda & lambda, EvalState & state, Env & up, Value * arg, const PosIdx pos) = 0;
387
388 virtual void addBindingsToJSON(JSON & out, const SymbolTable & symbols) const = 0;
389};
390
392struct SimplePattern : Pattern
393{
394 SimplePattern() = default;
395 SimplePattern(Symbol name) : Pattern(name) {
396 assert(name);
397 }
398
399 virtual std::shared_ptr<const StaticEnv> buildEnv(const StaticEnv * up) override;
400 virtual void accept(ExprVisitor & ev) override;
401 virtual Env & match(ExprLambda & lambda, EvalState & state, Env & up, Value * arg, const PosIdx pos) override;
402
403 virtual void addBindingsToJSON(JSON & out, const SymbolTable & symbols) const override;
404};
405
407struct AttrsPattern : Pattern
408{
409 struct Formal
410 {
411 PosIdx pos;
412 Symbol name;
413 std::unique_ptr<Expr> def;
414 };
415
416 typedef std::vector<Formal> Formals_;
417 Formals_ formals;
418 bool ellipsis;
419
420 virtual std::shared_ptr<const StaticEnv> buildEnv(const StaticEnv * up) override;
421 virtual void accept(ExprVisitor & ev) override;
422 virtual Env & match(ExprLambda & lambda, EvalState & state, Env & up, Value * arg, const PosIdx pos) override;
423
424 virtual void addBindingsToJSON(JSON & out, const SymbolTable & symbols) const override;
425
426 bool has(Symbol arg) const
427 {
428 auto it = std::lower_bound(formals.begin(), formals.end(), arg,
429 [] (const Formal & f, const Symbol & sym) { return f.name < sym; });
430 return it != formals.end() && it->name == arg;
431 }
432
433 std::vector<std::reference_wrapper<const Formal>> lexicographicOrder(const SymbolTable & symbols) const
434 {
435 std::vector<std::reference_wrapper<const Formal>> result(formals.begin(), formals.end());
436 std::sort(result.begin(), result.end(),
437 [&] (const Formal & a, const Formal & b) {
438 std::string_view sa = symbols[a.name], sb = symbols[b.name];
439 return sa < sb;
440 });
441 return result;
442 }
443};
444
445struct ExprLambda : Expr
446{
451 std::unique_ptr<Pattern> pattern;
452 std::unique_ptr<Expr> body;
453 ExprLambda(PosIdx pos, std::unique_ptr<Pattern> pattern, std::unique_ptr<Expr> body)
454 : Expr(pos), pattern(std::move(pattern)), body(std::move(body))
455 {
456 }
457 void setName(Symbol name) override;
458 std::string showNamePos(const EvalState & state) const;
459
463 inline std::string getName(SymbolTable const & symbols) const
464 {
465 if (this->name) {
466 return symbols[this->name];
467 }
468
469 return "anonymous lambda";
470 }
471
475 inline std::string getQuotedName(SymbolTable const & symbols) const
476 {
477 if (this->name) {
478 return concatStrings("'", symbols[this->name], "'");
479 }
480
481 return "anonymous lambda";
482 }
483
484 JSON toJSON(const SymbolTable & symbols) const override;
485 void eval(EvalState & state, Env & env, Value & v) override;
486 void accept(ExprVisitor & ev, std::unique_ptr<Expr> & ptr) override { ev.visit(*this, ptr); }
487};
488
489struct ExprCall : Expr
490{
491 std::unique_ptr<Expr> fun;
492 std::vector<std::unique_ptr<Expr>> args;
493 ExprCall(const PosIdx & pos, std::unique_ptr<Expr> fun, std::vector<std::unique_ptr<Expr>> && args)
494 : Expr(pos), fun(std::move(fun)), args(std::move(args))
495 { }
496 JSON toJSON(const SymbolTable & symbols) const override;
497 void eval(EvalState & state, Env & env, Value & v) override;
498 void accept(ExprVisitor & ev, std::unique_ptr<Expr> & ptr) override { ev.visit(*this, ptr); }
499};
500
501struct ExprLet : Expr, ExprAttrs
502{
503 std::unique_ptr<Expr> body;
504 JSON toJSON(const SymbolTable & symbols) const override;
505 void eval(EvalState & state, Env & env, Value & v) override;
506 void accept(ExprVisitor & ev, std::unique_ptr<Expr> & ptr) override { ev.visit(*this, ptr); }
507};
508
509struct ExprWith : Expr
510{
511 std::unique_ptr<Expr> attrs, body;
512 size_t prevWith;
513 ExprWith * parentWith;
514 ExprWith(const PosIdx & pos, std::unique_ptr<Expr> attrs, std::unique_ptr<Expr> body) : Expr(pos), attrs(std::move(attrs)), body(std::move(body)) { };
515 JSON toJSON(const SymbolTable & symbols) const override;
516 void eval(EvalState & state, Env & env, Value & v) override;
517 void accept(ExprVisitor & ev, std::unique_ptr<Expr> & ptr) override { ev.visit(*this, ptr); }
518};
519
520struct ExprIf : Expr
521{
522 std::unique_ptr<Expr> cond, then, else_;
523 ExprIf(const PosIdx & pos, std::unique_ptr<Expr> cond, std::unique_ptr<Expr> then, std::unique_ptr<Expr> else_) : Expr(pos), cond(std::move(cond)), then(std::move(then)), else_(std::move(else_)) { };
524 JSON toJSON(const SymbolTable & symbols) const override;
525 void eval(EvalState & state, Env & env, Value & v) override;
526 void accept(ExprVisitor & ev, std::unique_ptr<Expr> & ptr) override { ev.visit(*this, ptr); }
527};
528
529struct ExprAssert : Expr
530{
531 std::unique_ptr<Expr> cond, body;
532 ExprAssert(const PosIdx & pos, std::unique_ptr<Expr> cond, std::unique_ptr<Expr> body) : Expr(pos), cond(std::move(cond)), body(std::move(body)) { };
533 JSON toJSON(const SymbolTable & symbols) const override;
534 void eval(EvalState & state, Env & env, Value & v) override;
535 void accept(ExprVisitor & ev, std::unique_ptr<Expr> & ptr) override { ev.visit(*this, ptr); }
536};
537
538struct ExprOpNot : Expr
539{
540 std::unique_ptr<Expr> e;
541 ExprOpNot(const PosIdx & pos, std::unique_ptr<Expr> e) : Expr(pos), e(std::move(e)) { };
542 JSON toJSON(const SymbolTable & symbols) const override;
543 void eval(EvalState & state, Env & env, Value & v) override;
544 void accept(ExprVisitor & ev, std::unique_ptr<Expr> & ptr) override { ev.visit(*this, ptr); }
545};
546
547#define MakeBinOp(name, s) \
548 struct name : Expr \
549 { \
550 std::unique_ptr<Expr> e1, e2; \
551 name(std::unique_ptr<Expr> e1, std::unique_ptr<Expr> e2) : e1(std::move(e1)), e2(std::move(e2)) { }; \
552 name(const PosIdx & pos, std::unique_ptr<Expr> e1, std::unique_ptr<Expr> e2) : Expr(pos), e1(std::move(e1)), e2(std::move(e2)) { }; \
553 JSON toJSON(const SymbolTable & symbols) const override \
554 { \
555 return { \
556 {"_type", #name}, \
557 {"e1", e1->toJSON(symbols)}, \
558 {"e2", e2->toJSON(symbols)} \
559 };\
560 } \
561 void accept(ExprVisitor & ev, std::unique_ptr<Expr> & ptr) override { ev.visit(*this, ptr); } \
562 void eval(EvalState & state, Env & env, Value & v) override; \
563 };
564
565MakeBinOp(ExprOpEq, "==")
566MakeBinOp(ExprOpNEq, "!=")
567MakeBinOp(ExprOpAnd, "&&")
568MakeBinOp(ExprOpOr, "||")
569MakeBinOp(ExprOpImpl, "->")
570MakeBinOp(ExprOpUpdate, "//")
571MakeBinOp(ExprOpConcatLists, "++")
572
573struct ExprConcatStrings : Expr
574{
575 bool forceString;
576 std::vector<std::pair<PosIdx, std::unique_ptr<Expr>>> es;
577 ExprConcatStrings(const PosIdx & pos, bool forceString, std::vector<std::pair<PosIdx, std::unique_ptr<Expr>>> es)
578 : Expr(pos), forceString(forceString), es(std::move(es)) { };
579 JSON toJSON(const SymbolTable & symbols) const override;
580 void eval(EvalState & state, Env & env, Value & v) override;
581 void accept(ExprVisitor & ev, std::unique_ptr<Expr> & ptr) override { ev.visit(*this, ptr); }
582};
583
584struct ExprPos : Expr
585{
586 ExprPos(const PosIdx & pos) : Expr(pos) { };
587 JSON toJSON(const SymbolTable & symbols) const override;
588 void eval(EvalState & state, Env & env, Value & v) override;
589 void accept(ExprVisitor & ev, std::unique_ptr<Expr> & ptr) override { ev.visit(*this, ptr); }
590};
591
592/* only used to mark thunks as black holes. */
593struct ExprBlackHole : Expr
594{
595 void eval(EvalState & state, Env & env, Value & v) override;
596 void accept(ExprVisitor & ev, std::unique_ptr<Expr> & ptr) override { ev.visit(*this, ptr); }
597};
598
599extern ExprBlackHole eBlackHole;
600
601
602/* Static environments are used to map variable names onto (level,
603 displacement) pairs used to obtain the value of the variable at
604 runtime. */
605struct StaticEnv
606{
607 ExprWith * isWith;
608 const StaticEnv * up;
609
610 // Note: these must be in sorted order.
611 typedef std::vector<std::pair<Symbol, Displacement>> Vars;
612 Vars vars;
613
614 /* See ExprVar::needsRoot */
615 bool isRoot = false;
616
617 StaticEnv(ExprWith * isWith, const StaticEnv * up, size_t expectedSize = 0) : isWith(isWith), up(up) {
618 vars.reserve(expectedSize);
619 };
620
621 void sort()
622 {
623 std::stable_sort(vars.begin(), vars.end(),
624 [](const Vars::value_type & a, const Vars::value_type & b) { return a.first < b.first; });
625 }
626
627 void deduplicate()
628 {
629 auto it = vars.begin(), jt = it, end = vars.end();
630 while (jt != end) {
631 *it = *jt++;
632 while (jt != end && it->first == jt->first) *it = *jt++;
633 it++;
634 }
635 vars.erase(it, end);
636 }
637
638 Vars::const_iterator find(Symbol name) const
639 {
640 Vars::value_type key(name, 0);
641 auto i = std::lower_bound(vars.begin(), vars.end(), key);
642 if (i != vars.end() && i->first == name) return i;
643 return vars.end();
644 }
645};
646
647
648}
Definition eval.hh:685
Definition eval.hh:533
Definition pos-idx.hh:9
Definition symbol-table.hh:73
Definition symbol-table.hh:50
Definition nixexpr.hh:28
Definition nixexpr.hh:410
Definition nixexpr.hh:408
virtual Env & match(ExprLambda &lambda, EvalState &state, Env &up, Value *arg, const PosIdx pos) override
Definition eval.cc:1487
Definition eval.hh:112
Definition nixexpr.hh:530
Definition nixexpr.hh:296
Kind
Definition nixexpr.hh:297
@ Plain
Definition nixexpr.hh:299
@ Inherited
Definition nixexpr.hh:301
@ InheritedFrom
Definition nixexpr.hh:303
Definition nixexpr.hh:594
Definition nixexpr.hh:490
Definition nixexpr.hh:152
Definition nixexpr.hh:521
Definition nixexpr.hh:242
Definition nixexpr.hh:446
Symbol name
Definition nixexpr.hh:450
std::string getQuotedName(SymbolTable const &symbols) const
Definition nixexpr.hh:475
std::string getName(SymbolTable const &symbols) const
Definition nixexpr.hh:463
Definition nixexpr.hh:502
Definition nixexpr.hh:366
Definition nixexpr.hh:172
Definition nixexpr.hh:277
Definition nixexpr.hh:539
Definition nixexpr.hh:194
Definition nixexpr.hh:585
Definition nixexpr.hh:356
Definition nixexpr.hh:257
std::unique_ptr< Expr > e
Definition nixexpr.hh:259
AttrPath attrPath
Definition nixexpr.hh:267
std::unique_ptr< Expr > def
Definition nixexpr.hh:264
Definition nixexpr.hh:346
Definition nixexpr.hh:188
Definition nixexpr.hh:203
Definition nixexpr.hh:73
Definition nixexpr.hh:510
Definition nixexpr.hh:111
Definition nixexpr.hh:104
Definition value.hh:146
Definition value.hh:143
Definition nixexpr.hh:375
Symbol name
Definition nixexpr.hh:378
Definition nixexpr.hh:606
Definition value.hh:190