nixd
Loading...
Searching...
No Matches
ParseStrings.cpp
Go to the documentation of this file.
1#include "Parser.h"
2
3using namespace nixf;
4using namespace nixf::detail;
5
6std::shared_ptr<Interpolation> Parser::parseInterpolation() {
7 Token TokDollarCurly = peek();
8 assert(TokDollarCurly.kind() == tok_dollar_curly);
9 consume(); // ${
10 auto Sync = withSync(tok_r_curly);
11 assert(LastToken);
12 /* with(PS_Expr) */ {
13 auto ExprState = withState(PS_Expr);
14 auto Expr = parseExpr();
15 if (!Expr)
16 diagNullExpr(Diags, LastToken->rCur(), "interpolation");
17 if (ExpectResult ER = expect(tok_r_curly); ER.ok()) {
18 consume(); // }
19 } else {
20 ER.diag().note(Note::NK_ToMachThis, TokDollarCurly.range())
21 << std::string(tok::spelling(tok_dollar_curly));
22 }
23 return std::make_shared<Interpolation>(
24 LexerCursorRange{TokDollarCurly.lCur(), LastToken->rCur()},
25 std::move(Expr));
26 } // with(PS_Expr)
27}
28
29std::shared_ptr<Expr> Parser::parseExprPath() {
30 Token Begin = peek();
31 std::vector<InterpolablePart> Fragments;
32 assert(Begin.kind() == tok_path_fragment);
33 LexerCursor End;
34 /* with(PS_Path) */ {
35 auto PathState = withState(PS_Path);
36 do {
37 Token Current = peek();
38 Fragments.emplace_back(std::string(Current.view()));
39 consume();
40 End = Current.rCur();
41 Token Next = peek();
42 if (Next.kind() == tok_path_end)
43 break;
44 if (Next.kind() == tok_dollar_curly) {
45 if (auto Expr = parseInterpolation())
46 Fragments.emplace_back(std::move(Expr));
47 continue;
48 }
49 assert(false && "should be path_end or ${");
50 } while (true);
51 }
52 auto Parts = std::make_shared<InterpolatedParts>(
53 LexerCursorRange{Begin.lCur(), End}, std::move(Fragments));
54 return std::make_shared<ExprPath>(LexerCursorRange{Begin.lCur(), End},
55 std::move(Parts));
56}
57
58std::shared_ptr<InterpolatedParts> Parser::parseStringParts() {
59 std::vector<InterpolablePart> Parts;
60 LexerCursor PartsBegin = peek().lCur();
61 while (true) {
62 switch (Token Tok = peek(0); Tok.kind()) {
63 case tok_dollar_curly: {
64 if (auto Expr = parseInterpolation())
65 Parts.emplace_back(std::move(Expr));
66 continue;
67 }
68 case tok_string_part: {
69 // If this is a part of string, just push it.
70 Parts.emplace_back(std::string(Tok.view()));
71 consume();
72 continue;
73 }
74 case tok_string_escape:
75 // If this is a part of string, just push it.
76 consume();
77 // TODO: escape and emplace_back
78 continue;
79 default:
80 assert(LastToken && "LastToken should be set in `parseString`");
81 return std::make_shared<InterpolatedParts>(
82 LexerCursorRange{PartsBegin, LastToken->rCur()},
83 std::move(Parts)); // TODO!
84 }
85 }
86}
87
88std::shared_ptr<ExprString> Parser::parseString(bool IsIndented) {
89 Token Quote = peek();
90 TokenKind QuoteKind = IsIndented ? tok_quote2 : tok_dquote;
91 std::string QuoteSpel(tok::spelling(QuoteKind));
92 assert(Quote.kind() == QuoteKind && "should be a quote");
93 // Consume the quote and so make the look-ahead buf empty.
94 consume();
95 auto Sync = withSync(QuoteKind);
96 assert(LastToken && "LastToken should be set after consume()");
97 /* with(PS_String / PS_IndString) */ {
98 auto StringState = withState(IsIndented ? PS_IndString : PS_String);
99 std::shared_ptr<InterpolatedParts> Parts = parseStringParts();
100 if (ExpectResult ER = expect(QuoteKind); ER.ok()) {
101 consume();
102 return std::make_shared<ExprString>(
103 LexerCursorRange{Quote.lCur(), ER.tok().rCur()}, std::move(Parts));
104 } else { // NOLINT(readability-else-after-return)
105 ER.diag().note(Note::NK_ToMachThis, Quote.range()) << QuoteSpel;
106 return std::make_shared<ExprString>(
107 LexerCursorRange{Quote.lCur(), Parts->rCur()}, std::move(Parts));
108 }
109
110 } // with(PS_String / PS_IndString)
111}
A point in the source file.
Definition Range.h:57
std::shared_ptr< Interpolation > parseInterpolation()
Parse interpolations.
std::shared_ptr< Expr > parseExpr()
Definition ParseExpr.cpp:73
std::shared_ptr< InterpolatedParts > parseStringParts()
std::shared_ptr< ExprString > parseString(bool IsIndented)
std::shared_ptr< Expr > parseExprPath()
Parse paths.
A token. With it's kind, and the range in source code.
Definition Token.h:55
LexerCursor lCur() const
Definition Token.h:63
tok::TokenKind kind() const
Definition Token.h:65
LexerCursorRange range() const
Definition Token.h:66
LexerCursor rCur() const
Definition Token.h:64
std::string_view view() const
Definition Token.h:67
Diagnostic & diagNullExpr(std::vector< Diagnostic > &Diags, LexerCursor Loc, std::string As)
constexpr std::string_view spelling(TokenKind Kind)
Definition Token.h:13
Parser for the Nix expression language.