-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
nixexpr: introduce arena to hold ExprString strings #14090
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -64,6 +64,7 @@ Expr * parseExprFromBuf( | |
| size_t length, | ||
| Pos::Origin origin, | ||
| const SourcePath & basePath, | ||
| std::pmr::polymorphic_allocator<char> & alloc, | ||
| SymbolTable & symbols, | ||
| const EvalSettings & settings, | ||
| PosTable & positions, | ||
|
|
@@ -134,6 +135,7 @@ static Expr * makeCall(PosIdx pos, Expr * fn, Expr * arg) { | |
| std::vector<nix::AttrName> * attrNames; | ||
| std::vector<std::pair<nix::AttrName, nix::PosIdx>> * inheritAttrs; | ||
| std::vector<std::pair<nix::PosIdx, nix::Expr *>> * string_parts; | ||
| std::variant<nix::Expr *, std::string_view> * to_be_string; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. All this makes me wish we could move to a C++ skeleton in bison. Then we'd be able to use proper variant types for values.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure what that means "C++ skeleton in bison". I kind of have an itching to move us to a recursive descent parser, but I'm not sure other people would like that, and in any case that should definitely be after we have a fuzzer that can thoroughly check that they're equivalent
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. https://www.gnu.org/software/bison/manual/html_node/A-Simple-C_002b_002b-Example.html Then we wouldn't have to use the
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This was added now in #14105 |
||
| std::vector<std::pair<nix::PosIdx, std::variant<nix::Expr *, nix::StringToken>>> * ind_string_parts; | ||
| } | ||
|
|
||
|
|
@@ -148,7 +150,8 @@ static Expr * makeCall(PosIdx pos, Expr * fn, Expr * arg) { | |
| %type <inheritAttrs> attrs | ||
| %type <string_parts> string_parts_interpolated | ||
| %type <ind_string_parts> ind_string_parts | ||
| %type <e> path_start string_parts string_attr | ||
| %type <e> path_start | ||
| %type <to_be_string> string_parts string_attr | ||
| %type <id> attr | ||
| %token <id> ID | ||
| %token <str> STR IND_STR | ||
|
|
@@ -303,7 +306,13 @@ expr_simple | |
| } | ||
| | INT_LIT { $$ = new ExprInt($1); } | ||
| | FLOAT_LIT { $$ = new ExprFloat($1); } | ||
| | '"' string_parts '"' { $$ = $2; } | ||
| | '"' string_parts '"' { | ||
| std::visit(overloaded{ | ||
| [&](std::string_view str) { $$ = new ExprString(state->alloc, str); }, | ||
| [&](Expr * expr) { $$ = expr; }}, | ||
| *$2); | ||
| delete $2; | ||
| } | ||
| | IND_STRING_OPEN ind_string_parts IND_STRING_CLOSE { | ||
| $$ = state->stripIndentation(CUR_POS, std::move(*$2)); | ||
| delete $2; | ||
|
|
@@ -314,11 +323,11 @@ expr_simple | |
| $$ = new ExprConcatStrings(CUR_POS, false, $2); | ||
| } | ||
| | SPATH { | ||
| std::string path($1.p + 1, $1.l - 2); | ||
| std::string_view path($1.p + 1, $1.l - 2); | ||
| $$ = new ExprCall(CUR_POS, | ||
| new ExprVar(state->s.findFile), | ||
| {new ExprVar(state->s.nixPath), | ||
| new ExprString(std::move(path))}); | ||
| new ExprString(state->alloc, path)}); | ||
| } | ||
| | URI { | ||
| static bool noURLLiterals = experimentalFeatureSettings.isEnabled(Xp::NoUrlLiterals); | ||
|
|
@@ -327,7 +336,7 @@ expr_simple | |
| .msg = HintFmt("URL literals are disabled"), | ||
| .pos = state->positions[CUR_POS] | ||
| }); | ||
| $$ = new ExprString(std::string($1)); | ||
| $$ = new ExprString(state->alloc, $1); | ||
| } | ||
| | '(' expr ')' { $$ = $2; } | ||
| /* Let expressions `let {..., body = ...}' are just desugared | ||
|
|
@@ -344,19 +353,19 @@ expr_simple | |
| ; | ||
|
|
||
| string_parts | ||
| : STR { $$ = new ExprString(std::string($1)); } | ||
| | string_parts_interpolated { $$ = new ExprConcatStrings(CUR_POS, true, $1); } | ||
| | { $$ = new ExprString(""); } | ||
| : STR { $$ = new std::variant<Expr *, std::string_view>($1); } | ||
| | string_parts_interpolated { $$ = new std::variant<Expr *, std::string_view>(new ExprConcatStrings(CUR_POS, true, $1)); } | ||
| | { $$ = new std::variant<Expr *, std::string_view>(std::string_view()); } | ||
| ; | ||
|
|
||
| string_parts_interpolated | ||
| : string_parts_interpolated STR | ||
| { $$ = $1; $1->emplace_back(state->at(@2), new ExprString(std::string($2))); } | ||
| { $$ = $1; $1->emplace_back(state->at(@2), new ExprString(state->alloc, $2)); } | ||
| | string_parts_interpolated DOLLAR_CURLY expr '}' { $$ = $1; $1->emplace_back(state->at(@2), $3); } | ||
| | DOLLAR_CURLY expr '}' { $$ = new std::vector<std::pair<PosIdx, Expr *>>; $$->emplace_back(state->at(@1), $2); } | ||
| | STR DOLLAR_CURLY expr '}' { | ||
| $$ = new std::vector<std::pair<PosIdx, Expr *>>; | ||
| $$->emplace_back(state->at(@1), new ExprString(std::string($1))); | ||
| $$->emplace_back(state->at(@1), new ExprString(state->alloc, $1)); | ||
| $$->emplace_back(state->at(@2), $3); | ||
| } | ||
| ; | ||
|
|
@@ -454,15 +463,16 @@ attrs | |
| : attrs attr { $$ = $1; $1->emplace_back(AttrName(state->symbols.create($2)), state->at(@2)); } | ||
| | attrs string_attr | ||
| { $$ = $1; | ||
| ExprString * str = dynamic_cast<ExprString *>($2); | ||
| if (str) { | ||
| $$->emplace_back(AttrName(state->symbols.create(str->s)), state->at(@2)); | ||
| delete str; | ||
| } else | ||
| throw ParseError({ | ||
| .msg = HintFmt("dynamic attributes not allowed in inherit"), | ||
| .pos = state->positions[state->at(@2)] | ||
| }); | ||
| std::visit(overloaded { | ||
| [&](std::string_view str) { $$->emplace_back(AttrName(state->symbols.create(str)), state->at(@2)); }, | ||
| [&](Expr * expr) { | ||
| throw ParseError({ | ||
| .msg = HintFmt("dynamic attributes not allowed in inherit"), | ||
| .pos = state->positions[state->at(@2)] | ||
| }); | ||
| } | ||
| }, *$2); | ||
| delete $2; | ||
| } | ||
| | { $$ = new std::vector<std::pair<AttrName, PosIdx>>; } | ||
| ; | ||
|
|
@@ -471,22 +481,20 @@ attrpath | |
| : attrpath '.' attr { $$ = $1; $1->push_back(AttrName(state->symbols.create($3))); } | ||
| | attrpath '.' string_attr | ||
| { $$ = $1; | ||
| ExprString * str = dynamic_cast<ExprString *>($3); | ||
| if (str) { | ||
| $$->push_back(AttrName(state->symbols.create(str->s))); | ||
| delete str; | ||
| } else | ||
| $$->push_back(AttrName($3)); | ||
| std::visit(overloaded { | ||
| [&](std::string_view str) { $$->push_back(AttrName(state->symbols.create(str))); }, | ||
| [&](Expr * expr) { $$->push_back(AttrName(expr)); } | ||
| }, *$3); | ||
| delete $3; | ||
| } | ||
| | attr { $$ = new std::vector<AttrName>; $$->push_back(AttrName(state->symbols.create($1))); } | ||
| | string_attr | ||
| { $$ = new std::vector<AttrName>; | ||
| ExprString *str = dynamic_cast<ExprString *>($1); | ||
| if (str) { | ||
| $$->push_back(AttrName(state->symbols.create(str->s))); | ||
| delete str; | ||
| } else | ||
| $$->push_back(AttrName($1)); | ||
| std::visit(overloaded { | ||
| [&](std::string_view str) { $$->push_back(AttrName(state->symbols.create(str))); }, | ||
| [&](Expr * expr) { $$->push_back(AttrName(expr)); } | ||
| }, *$1); | ||
| delete $1; | ||
| } | ||
| ; | ||
|
|
||
|
|
@@ -497,7 +505,7 @@ attr | |
|
|
||
| string_attr | ||
| : '"' string_parts '"' { $$ = $2; } | ||
| | DOLLAR_CURLY expr '}' { $$ = $2; } | ||
| | DOLLAR_CURLY expr '}' { $$ = new std::variant<Expr *, std::string_view>($2); } | ||
Radvendii marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| ; | ||
|
|
||
| expr_list | ||
|
|
@@ -537,6 +545,7 @@ Expr * parseExprFromBuf( | |
| size_t length, | ||
| Pos::Origin origin, | ||
| const SourcePath & basePath, | ||
| std::pmr::polymorphic_allocator<char> & alloc, | ||
| SymbolTable & symbols, | ||
| const EvalSettings & settings, | ||
| PosTable & positions, | ||
|
|
@@ -551,6 +560,7 @@ Expr * parseExprFromBuf( | |
| }; | ||
| ParserState state { | ||
| .lexerState = lexerState, | ||
| .alloc = alloc, | ||
| .symbols = symbols, | ||
| .positions = positions, | ||
| .basePath = basePath, | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.