@@ -59,6 +59,7 @@ Expr * parseExprFromBuf(
5959 size_t length,
6060 Pos::Origin origin,
6161 const SourcePath & basePath,
62+ std::pmr::polymorphic_allocator<char > & alloc,
6263 SymbolTable & symbols,
6364 const EvalSettings & settings,
6465 PosTable & positions,
@@ -135,6 +136,7 @@ static Expr * makeCall(PosIdx pos, Expr * fn, Expr * arg) {
135136 std::vector<nix::AttrName> * attrNames;
136137 std::vector<std::pair<nix::AttrName, nix::PosIdx>> * inheritAttrs;
137138 std::vector<std::pair<nix::PosIdx, nix::Expr *>> * string_parts;
139+ std::variant<nix::Expr *, std::string_view> * to_be_string;
138140 std::vector<std::pair<nix::PosIdx, std::variant<nix::Expr *, nix::StringToken>>> * ind_string_parts;
139141}
140142
@@ -149,7 +151,8 @@ static Expr * makeCall(PosIdx pos, Expr * fn, Expr * arg) {
149151%type <inheritAttrs> attrs
150152%type <string_parts> string_parts_interpolated
151153%type <ind_string_parts> ind_string_parts
152- %type <e> path_start string_parts string_attr
154+ %type <e> path_start
155+ %type <to_be_string> string_parts string_attr
153156%type <id> attr
154157%token <id> ID
155158%token <str> STR IND_STR
@@ -304,7 +307,13 @@ expr_simple
304307 }
305308 | INT_LIT { $$ = new ExprInt($1); }
306309 | FLOAT_LIT { $$ = new ExprFloat($1); }
307- | '"' string_parts '"' { $$ = $2; }
310+ | '"' string_parts '"' {
311+ std ::visit (overloaded {
312+ [&](std::string_view str) { $$ = new ExprString(state->alloc, str); },
313+ [&](Expr * expr) { $$ = expr; }},
314+ *$2);
315+ delete $2;
316+ }
308317 | IND_STRING_OPEN ind_string_parts IND_STRING_CLOSE {
309318 $$ = state->stripIndentation(CUR_POS, std::move(*$2));
310319 delete $2;
@@ -315,11 +324,11 @@ expr_simple
315324 $$ = new ExprConcatStrings(CUR_POS, false, $2);
316325 }
317326 | SPATH {
318- std ::string path ($1.p + 1, $1.l - 2);
327+ std ::string_view path ($1.p + 1, $1.l - 2);
319328 $$ = new ExprCall(CUR_POS,
320329 new ExprVar(state->s.findFile),
321330 {new ExprVar(state->s.nixPath),
322- new ExprString(std::move( path) )});
331+ new ExprString(state->alloc, path)});
323332 }
324333 | URI {
325334 static bool noURLLiterals = experimentalFeatureSettings.isEnabled(Xp::NoUrlLiterals);
@@ -328,7 +337,7 @@ expr_simple
328337 .msg = HintFmt("URL literals are disabled"),
329338 .pos = state->positions[CUR_POS]
330339 });
331- $$ = new ExprString(std::string($1) );
340+ $$ = new ExprString(state->alloc, $1 );
332341 }
333342 | '(' expr ')' { $$ = $2; }
334343 /* Let expressions `let {..., body = ...}' are just desugared
@@ -345,19 +354,19 @@ expr_simple
345354 ;
346355
347356string_parts
348- : STR { $$ = new ExprString( std::string ($1) ); }
349- | string_parts_interpolated { $$ = new ExprConcatStrings(CUR_POS, true, $1); }
350- | { $$ = new ExprString("" ); }
357+ : STR { $$ = new std::variant<Expr *, std::string_view> ($1); }
358+ | string_parts_interpolated { $$ = new std::variant<Expr *, std::string_view>(new ExprConcatStrings(CUR_POS, true, $1) ); }
359+ | { $$ = new std::variant<Expr *, std::string_view>(std::string_view() ); }
351360 ;
352361
353362string_parts_interpolated
354363 : string_parts_interpolated STR
355- { $$ = $1; $1->emplace_back(state->at(@2), new ExprString(std::string($2) )); }
364+ { $$ = $1; $1->emplace_back(state->at(@2), new ExprString(state->alloc, $2 )); }
356365 | string_parts_interpolated DOLLAR_CURLY expr '}' { $$ = $1; $1->emplace_back(state->at(@2), $3); }
357366 | DOLLAR_CURLY expr '}' { $$ = new std::vector<std::pair<PosIdx, Expr *>>; $$->emplace_back(state->at(@1), $2); }
358367 | STR DOLLAR_CURLY expr '}' {
359368 $$ = new std::vector<std::pair<PosIdx, Expr *>>;
360- $$->emplace_back(state->at(@1), new ExprString(std::string($1) ));
369+ $$->emplace_back(state->at(@1), new ExprString(state->alloc, $1 ));
361370 $$->emplace_back(state->at(@2), $3);
362371 }
363372 ;
@@ -455,15 +464,16 @@ attrs
455464 : attrs attr { $$ = $1; $1->emplace_back(AttrName(state->symbols.create($2)), state->at(@2)); }
456465 | attrs string_attr
457466 { $$ = $1;
458- ExprString * str = dynamic_cast<ExprString *>($2);
459- if (str) {
460- $$->emplace_back(AttrName(state->symbols.create(str->s)), state->at(@2));
461- delete str;
462- } else
463- throw ParseError({
464- .msg = HintFmt("dynamic attributes not allowed in inherit"),
465- .pos = state->positions[state->at(@2)]
466- });
467+ std ::visit (overloaded {
468+ [&](std::string_view str) { $$ ->emplace_back (AttrName(state->symbols.create(str)), state->at(@2 )); },
469+ [&](Expr * expr) {
470+ throw ParseError ({
471+ .msg = HintFmt (" dynamic attributes not allowed in inherit" ),
472+ .pos = state->positions [state->at (@2 )]
473+ });
474+ }
475+ }, *$2);
476+ delete $2;
467477 }
468478 | { $$ = new std::vector<std::pair<AttrName, PosIdx>>; }
469479 ;
@@ -472,22 +482,20 @@ attrpath
472482 : attrpath '.' attr { $$ = $1; $1->push_back(AttrName(state->symbols.create($3))); }
473483 | attrpath '.' string_attr
474484 { $$ = $1;
475- ExprString * str = dynamic_cast<ExprString *>($3);
476- if (str) {
477- $$->push_back(AttrName(state->symbols.create(str->s)));
478- delete str;
479- } else
480- $$->push_back(AttrName($3));
485+ std ::visit (overloaded {
486+ [&](std::string_view str) { $$ ->push_back (AttrName(state->symbols.create(str))); },
487+ [&](Expr * expr) { $$ ->push_back (AttrName(expr)); }
488+ }, *$3);
489+ delete $3;
481490 }
482491 | attr { $$ = new std::vector<AttrName>; $$->push_back(AttrName(state->symbols.create($1))); }
483492 | string_attr
484493 { $$ = new std::vector<AttrName>;
485- ExprString *str = dynamic_cast<ExprString *>($1);
486- if (str) {
487- $$->push_back(AttrName(state->symbols.create(str->s)));
488- delete str;
489- } else
490- $$->push_back(AttrName($1));
494+ std ::visit (overloaded {
495+ [&](std::string_view str) { $$ ->push_back (AttrName(state->symbols.create(str))); },
496+ [&](Expr * expr) { $$ ->push_back (AttrName(expr)); }
497+ }, *$1);
498+ delete $1;
491499 }
492500 ;
493501
498506
499507string_attr
500508 : '"' string_parts '"' { $$ = $2; }
501- | DOLLAR_CURLY expr '}' { $$ = $2 ; }
509+ | DOLLAR_CURLY expr '}' { $$ = new std::variant<Expr *, std::string_view>($2) ; }
502510 ;
503511
504512expr_list
@@ -538,6 +546,7 @@ Expr * parseExprFromBuf(
538546 size_t length,
539547 Pos::Origin origin,
540548 const SourcePath & basePath,
549+ std::pmr::polymorphic_allocator<char > & alloc,
541550 SymbolTable & symbols,
542551 const EvalSettings & settings,
543552 PosTable & positions,
@@ -552,6 +561,7 @@ Expr * parseExprFromBuf(
552561 };
553562 ParserState state {
554563 .lexerState = lexerState,
564+ .alloc = alloc,
555565 .symbols = symbols,
556566 .positions = positions,
557567 .basePath = basePath,
0 commit comments