Skip to content

Commit

Permalink
libnixf: extract parseInterpolation func, rename parseInterpolableParts
Browse files Browse the repository at this point in the history
parseInterpolableParts -> parseStringParts

`StringParts` are different from path fragments because paths have no *surrounding quotes*.
So, the first path fragment should be parsed normally, and the rest in "PS_Path" context.
Previously `parseInterpolableParts` was used for only unified parsing contexts (and this only works for strings).
So it was renamed to `parseStringParts`.
  • Loading branch information
inclyc committed Jan 14, 2024
1 parent 13142d8 commit f9afce3
Showing 1 changed file with 22 additions and 12 deletions.
34 changes: 22 additions & 12 deletions libnixf/lib/Parse/Parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,26 +123,36 @@ class Parser {
pushState(PS_Expr);
}

/// \brief Parse interpolations.
///
/// interpolation : "${" expr "}"
std::shared_ptr<Expr> parseInterpolation() {
assert(peek().kind() == tok_dollar_curly);
consume();
assert(LastToken);
/* with(PS_Expr) */ {
auto ExprState = withState(PS_Expr);
return parseExpr();
} // with(PS_Expr)
return nullptr;
}

/// \brief Parse interpolable things.
///
/// They are strings, ind-strings, paths, in nix language.
/// \note This needs context-switching so look-ahead buf should be cleared.
std::shared_ptr<InterpolatedParts> parseInterpolableParts() {
std::shared_ptr<InterpolatedParts> parseStringParts() {
std::vector<InterpolablePart> Parts;
Point PartsBegin = peek().begin();
while (true) {
switch (Token Tok = peek(0); Tok.kind()) {
case tok_dollar_curly: {
consume();
assert(LastToken);
/* with(PS_Expr) */ {
auto ExprState = withState(PS_Expr);
// interpolation, we need to parse a subtree then.
if (auto Expr = parseExpr())
Parts.emplace_back(std::move(Expr));
else
diagNullExpr(Diag, LastToken->end(), "interpolation");
} // with(PS_Expr)
if (auto Expr = parseInterpolation()) {
Parts.emplace_back(std::move(Expr));
} else {
assert(LastToken); // at least "${"
diagNullExpr(Diag, LastToken->end(), "string interpolation");
}
continue;
}
case tok_string_part: {
Expand Down Expand Up @@ -178,7 +188,7 @@ class Parser {
assert(LastToken && "LastToken should be set after consume()");
/* with(PS_String / PS_IndString) */ {
auto StringState = withState(IsIndented ? PS_IndString : PS_String);
std::shared_ptr<InterpolatedParts> Parts = parseInterpolableParts();
std::shared_ptr<InterpolatedParts> Parts = parseStringParts();
if (Token EndTok = peek(); EndTok.kind() == QuoteKind) {
consume();
return std::make_shared<ExprString>(
Expand Down

0 comments on commit f9afce3

Please sign in to comment.