aboutsummaryrefslogtreecommitdiff
path: root/src/libexpr/parser/state.hh
diff options
context:
space:
mode:
Diffstat (limited to 'src/libexpr/parser/state.hh')
-rw-r--r--src/libexpr/parser/state.hh52
1 files changed, 8 insertions, 44 deletions
diff --git a/src/libexpr/parser/state.hh b/src/libexpr/parser/state.hh
index 62bf08ae7..b969f73e4 100644
--- a/src/libexpr/parser/state.hh
+++ b/src/libexpr/parser/state.hh
@@ -6,14 +6,6 @@
namespace nix::parser {
-struct StringToken
-{
- std::string_view s;
- // canMerge is only used to faithfully reproduce the quirks from the old code base.
- bool canMerge = false;
- operator std::string_view() const { return s; }
-};
-
struct IndStringLine {
// String containing only the leading whitespace of the line. May be empty.
std::string_view indentation;
@@ -26,7 +18,7 @@ struct IndStringLine {
std::vector<
std::pair<
PosIdx,
- std::variant<std::unique_ptr<Expr>, StringToken>
+ std::variant<std::unique_ptr<Expr>, std::string_view>
>
> parts = {};
};
@@ -204,8 +196,7 @@ inline std::unique_ptr<Expr> State::stripIndentation(
std::vector<IndStringLine> && lines)
{
/* If the only line is whitespace-only, directly return empty string.
- * NOTE: This is not merely an optimization, but `compatStripLeadingEmptyString`
- * later on relies on the string not being empty for working.
+ * The rest of the code relies on the final string not being empty.
*/
if (lines.size() == 1 && lines.front().parts.empty()) {
return std::make_unique<ExprString>("");
@@ -219,19 +210,6 @@ inline std::unique_ptr<Expr> State::stripIndentation(
lines.back().indentation = {};
}
- /*
- * Quirk compatibility:
- *
- * » nix-instantiate --parse -E $'\'\'${"foo"}\'\''
- * "foo"
- * » nix-instantiate --parse -E $'\'\' ${"foo"}\'\''
- * ("" + "foo")
- *
- * Our code always produces the form with the additional "" +, so we'll manually
- * strip it at the end if necessary.
- */
- const bool compatStripLeadingEmptyString = !lines.empty() && lines[0].indentation.empty();
-
/* Figure out the minimum indentation. Note that by design
whitespace-only lines are not taken into account. */
size_t minIndent = 1000000;
@@ -248,48 +226,34 @@ inline std::unique_ptr<Expr> State::stripIndentation(
/* Concat the parts together again */
- /* Note that we don't concat all adjacent string parts to fully reproduce the original code.
- * This means that any escapes will result in string concatenation even if this is unnecessary.
- */
std::vector<std::pair<PosIdx, std::unique_ptr<Expr>>> parts;
/* Accumulator for merging intermediates */
PosIdx merged_pos;
std::string merged = "";
- bool has_merged = false;
auto push_merged = [&] (PosIdx i_pos, std::string_view str) {
- merged += str;
- if (!has_merged) {
- has_merged = true;
+ if (merged.empty()) {
merged_pos = i_pos;
}
+ merged += str;
};
auto flush_merged = [&] () {
- if (has_merged) {
+ if (!merged.empty()) {
parts.emplace_back(merged_pos, std::make_unique<ExprString>(std::string(merged)));
merged.clear();
- has_merged = false;
}
};
for (auto && [li, line] : enumerate(lines)) {
- /* Always merge indentation, except for the first line when compatStripLeadingEmptyString is set (see above) */
- if (!compatStripLeadingEmptyString || li != 0) {
- push_merged(line.pos, line.indentation);
- }
+ push_merged(line.pos, line.indentation);
for (auto & val : line.parts) {
auto &[i_pos, item] = val;
std::visit(overloaded{
- [&](StringToken str) {
- if (str.canMerge) {
- push_merged(i_pos, str.s);
- } else {
- flush_merged();
- parts.emplace_back(i_pos, std::make_unique<ExprString>(std::string(str.s)));
- }
+ [&](std::string_view str) {
+ push_merged(i_pos, str);
},
[&](std::unique_ptr<Expr> expr) {
flush_merged();