aboutsummaryrefslogtreecommitdiff
path: root/src/libexpr/parser/parser-impl1.inc.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/libexpr/parser/parser-impl1.inc.cc')
-rw-r--r--src/libexpr/parser/parser-impl1.inc.cc32
1 files changed, 22 insertions, 10 deletions
diff --git a/src/libexpr/parser/parser-impl1.inc.cc b/src/libexpr/parser/parser-impl1.inc.cc
index 0d41324b3..c65fb3ddc 100644
--- a/src/libexpr/parser/parser-impl1.inc.cc
+++ b/src/libexpr/parser/parser-impl1.inc.cc
@@ -533,36 +533,48 @@ template<> struct BuildAST<grammar::v1::string> : change_head<StringState> {
struct IndStringState : SubexprState {
using SubexprState::SubexprState;
- std::vector<std::pair<PosIdx, std::variant<std::unique_ptr<Expr>, StringToken>>> parts;
+ std::vector<IndStringLine> lines;
};
-template<bool Indented, typename... Content>
-struct BuildAST<grammar::v1::ind_string::literal<Indented, Content...>> {
+template<> struct BuildAST<grammar::v1::ind_string::line_start> {
static void apply(const auto & in, IndStringState & s, State & ps) {
- s.parts.emplace_back(ps.at(in), StringToken{in.string_view(), Indented});
+ s.lines.push_back(IndStringLine { in.string_view(), ps.at(in) });
+ }
+};
+
+template<bool CanMerge, typename... Content>
+struct BuildAST<grammar::v1::ind_string::literal<CanMerge, Content...>> {
+ static void apply(const auto & in, IndStringState & s, State & ps) {
+ s.lines.back().parts.emplace_back(ps.at(in), StringToken{ in.string_view(), CanMerge });
}
};
template<> struct BuildAST<grammar::v1::ind_string::interpolation> {
static void apply(const auto & in, IndStringState & s, State & ps) {
- s.parts.emplace_back(ps.at(in), s->popExprOnly());
+ s.lines.back().parts.emplace_back(ps.at(in), s->popExprOnly());
}
};
template<> struct BuildAST<grammar::v1::ind_string::escape> {
static void apply(const auto & in, IndStringState & s, State & ps) {
switch (*in.begin()) {
- case 'n': s.parts.emplace_back(ps.at(in), StringToken{"\n"}); break;
- case 'r': s.parts.emplace_back(ps.at(in), StringToken{"\r"}); break;
- case 't': s.parts.emplace_back(ps.at(in), StringToken{"\t"}); break;
- default: s.parts.emplace_back(ps.at(in), StringToken{in.string_view()}); break;
+ case 'n': s.lines.back().parts.emplace_back(ps.at(in), StringToken{"\n"}); break;
+ case 'r': s.lines.back().parts.emplace_back(ps.at(in), StringToken{"\r"}); break;
+ case 't': s.lines.back().parts.emplace_back(ps.at(in), StringToken{"\t"}); break;
+ default: s.lines.back().parts.emplace_back(ps.at(in), StringToken{in.string_view()}); break;
}
}
};
+template<> struct BuildAST<grammar::v1::ind_string::has_content> {
+ static void apply(const auto & in, IndStringState & s, State & ps) {
+ s.lines.back().hasContent = true;
+ }
+};
+
template<> struct BuildAST<grammar::v1::ind_string> : change_head<IndStringState> {
static void success(const auto & in, IndStringState & s, ExprState & e, State & ps) {
- e.exprs.emplace_back(noPos, ps.stripIndentation(ps.at(in), std::move(s.parts)));
+ e.exprs.emplace_back(noPos, ps.stripIndentation(ps.at(in), std::move(s.lines)));
}
};