@@ -64,6 +64,7 @@ Expr * parseExprFromBuf(
6464 size_t length,
6565 Pos::Origin origin,
6666 const SourcePath & basePath,
67+ std::pmr::polymorphic_allocator<char > & alloc,
6768 SymbolTable & symbols,
6869 const EvalSettings & settings,
6970 PosTable & positions,
@@ -134,6 +135,7 @@ static Expr * makeCall(PosIdx pos, Expr * fn, Expr * arg) {
134135 std::vector<nix::AttrName> * attrNames;
135136 std::vector<std::pair<nix::AttrName, nix::PosIdx>> * inheritAttrs;
136137 std::vector<std::pair<nix::PosIdx, nix::Expr *>> * string_parts;
138+ std::variant<nix::Expr *, std::string_view> * to_be_string;
137139 std::vector<std::pair<nix::PosIdx, std::variant<nix::Expr *, nix::StringToken>>> * ind_string_parts;
138140}
139141
@@ -148,7 +150,8 @@ static Expr * makeCall(PosIdx pos, Expr * fn, Expr * arg) {
148150%type <inheritAttrs> attrs
149151%type <string_parts> string_parts_interpolated
150152%type <ind_string_parts> ind_string_parts
151- %type <e> path_start string_parts string_attr
153+ %type <e> path_start
154+ %type <to_be_string> string_parts string_attr
152155%type <id> attr
153156%token <id> ID
154157%token <str> STR IND_STR
@@ -303,7 +306,13 @@ expr_simple
303306 }
304307 | INT_LIT { $$ = new ExprInt($1); }
305308 | FLOAT_LIT { $$ = new ExprFloat($1); }
306- | '"' string_parts '"' { $$ = $2; }
309+ | '"' string_parts '"' {
310+ std ::visit (overloaded {
311+ [&](std::string_view str) { $$ = new ExprString(state->alloc, str); },
312+ [&](Expr * expr) { $$ = expr; }},
313+ *$2);
314+ delete $2;
315+ }
307316 | IND_STRING_OPEN ind_string_parts IND_STRING_CLOSE {
308317 $$ = state->stripIndentation(CUR_POS, std::move(*$2));
309318 delete $2;
@@ -314,11 +323,11 @@ expr_simple
314323 $$ = new ExprConcatStrings(CUR_POS, false, $2);
315324 }
316325 | SPATH {
317- std ::string path ($1.p + 1, $1.l - 2);
326+ std ::string_view path ($1.p + 1, $1.l - 2);
318327 $$ = new ExprCall(CUR_POS,
319328 new ExprVar(state->s.findFile),
320329 {new ExprVar(state->s.nixPath),
321- new ExprString(std::move( path) )});
330+ new ExprString(state->alloc, path)});
322331 }
323332 | URI {
324333 static bool noURLLiterals = experimentalFeatureSettings.isEnabled(Xp::NoUrlLiterals);
@@ -327,7 +336,7 @@ expr_simple
327336 .msg = HintFmt("URL literals are disabled"),
328337 .pos = state->positions[CUR_POS]
329338 });
330- $$ = new ExprString(std::string($1) );
339+ $$ = new ExprString(state->alloc, $1 );
331340 }
332341 | '(' expr ')' { $$ = $2; }
333342 /* Let expressions `let {..., body = ...}' are just desugared
@@ -344,19 +353,19 @@ expr_simple
344353 ;
345354
346355string_parts
347- : STR { $$ = new ExprString( std::string ($1) ); }
348- | string_parts_interpolated { $$ = new ExprConcatStrings(CUR_POS, true, $1); }
349- | { $$ = new ExprString("" ); }
356+ : STR { $$ = new std::variant<Expr *, std::string_view> ($1); }
357+ | string_parts_interpolated { $$ = new std::variant<Expr *, std::string_view>(new ExprConcatStrings(CUR_POS, true, $1) ); }
358+ | { $$ = new std::variant<Expr *, std::string_view>(std::string_view() ); }
350359 ;
351360
352361string_parts_interpolated
353362 : string_parts_interpolated STR
354- { $$ = $1; $1->emplace_back(state->at(@2), new ExprString(std::string($2) )); }
363+ { $$ = $1; $1->emplace_back(state->at(@2), new ExprString(state->alloc, $2 )); }
355364 | string_parts_interpolated DOLLAR_CURLY expr '}' { $$ = $1; $1->emplace_back(state->at(@2), $3); }
356365 | DOLLAR_CURLY expr '}' { $$ = new std::vector<std::pair<PosIdx, Expr *>>; $$->emplace_back(state->at(@1), $2); }
357366 | STR DOLLAR_CURLY expr '}' {
358367 $$ = new std::vector<std::pair<PosIdx, Expr *>>;
359- $$->emplace_back(state->at(@1), new ExprString(std::string($1) ));
368+ $$->emplace_back(state->at(@1), new ExprString(state->alloc, $1 ));
360369 $$->emplace_back(state->at(@2), $3);
361370 }
362371 ;
@@ -454,15 +463,16 @@ attrs
454463 : attrs attr { $$ = $1; $1->emplace_back(AttrName(state->symbols.create($2)), state->at(@2)); }
455464 | attrs string_attr
456465 { $$ = $1;
457- ExprString * str = dynamic_cast<ExprString *>($2);
458- if (str) {
459- $$->emplace_back(AttrName(state->symbols.create(str->s)), state->at(@2));
460- delete str;
461- } else
462- throw ParseError({
463- .msg = HintFmt("dynamic attributes not allowed in inherit"),
464- .pos = state->positions[state->at(@2)]
465- });
466+ std ::visit (overloaded {
467+ [&](std::string_view str) { $$ ->emplace_back (AttrName(state->symbols.create(str)), state->at(@2 )); },
468+ [&](Expr * expr) {
469+ throw ParseError ({
470+ .msg = HintFmt (" dynamic attributes not allowed in inherit" ),
471+ .pos = state->positions [state->at (@2 )]
472+ });
473+ }
474+ }, *$2);
475+ delete $2;
466476 }
467477 | { $$ = new std::vector<std::pair<AttrName, PosIdx>>; }
468478 ;
@@ -471,22 +481,20 @@ attrpath
471481 : attrpath '.' attr { $$ = $1; $1->push_back(AttrName(state->symbols.create($3))); }
472482 | attrpath '.' string_attr
473483 { $$ = $1;
474- ExprString * str = dynamic_cast<ExprString *>($3);
475- if (str) {
476- $$->push_back(AttrName(state->symbols.create(str->s)));
477- delete str;
478- } else
479- $$->push_back(AttrName($3));
484+ std ::visit (overloaded {
485+ [&](std::string_view str) { $$ ->push_back (AttrName(state->symbols.create(str))); },
486+ [&](Expr * expr) { $$ ->push_back (AttrName(expr)); }
487+ }, *$3);
488+ delete $3;
480489 }
481490 | attr { $$ = new std::vector<AttrName>; $$->push_back(AttrName(state->symbols.create($1))); }
482491 | string_attr
483492 { $$ = new std::vector<AttrName>;
484- ExprString *str = dynamic_cast<ExprString *>($1);
485- if (str) {
486- $$->push_back(AttrName(state->symbols.create(str->s)));
487- delete str;
488- } else
489- $$->push_back(AttrName($1));
493+ std ::visit (overloaded {
494+ [&](std::string_view str) { $$ ->push_back (AttrName(state->symbols.create(str))); },
495+ [&](Expr * expr) { $$ ->push_back (AttrName(expr)); }
496+ }, *$1);
497+ delete $1;
490498 }
491499 ;
492500
497505
498506string_attr
499507 : '"' string_parts '"' { $$ = $2; }
500- | DOLLAR_CURLY expr '}' { $$ = $2 ; }
508+ | DOLLAR_CURLY expr '}' { $$ = new std::variant<Expr *, std::string_view>($2) ; }
501509 ;
502510
503511expr_list
@@ -537,6 +545,7 @@ Expr * parseExprFromBuf(
537545 size_t length,
538546 Pos::Origin origin,
539547 const SourcePath & basePath,
548+ std::pmr::polymorphic_allocator<char > & alloc,
540549 SymbolTable & symbols,
541550 const EvalSettings & settings,
542551 PosTable & positions,
@@ -551,6 +560,7 @@ Expr * parseExprFromBuf(
551560 };
552561 ParserState state {
553562 .lexerState = lexerState,
563+ .alloc = alloc,
554564 .symbols = symbols,
555565 .positions = positions,
556566 .basePath = basePath,
0 commit comments