nixd
Toggle main menu visibility
Loading...
Searching...
No Matches
libnixf
src
Parse
ParseLambda.cpp
Go to the documentation of this file.
1
#include "
Parser.h
"
2
3
using namespace
nixf
;
4
using namespace
detail
;
5
6
std::shared_ptr<Formal>
Parser::parseFormal
() {
7
// formal : ,? ID
8
// | ,? ID '?' expr
9
// | ,? ...
10
11
LexerCursor
LCur = lCur();
12
std::shared_ptr<Misc> Comma =
nullptr
;
13
if
(
Token
Tok = peek(); Tok.
kind
() == tok_comma) {
14
consume();
15
Comma = std::make_shared<Misc>(Tok.range());
16
}
17
if
(
Token
Tok = peek(); Tok.
kind
() == tok_id) {
18
consume();
// ID
19
assert(LastToken &&
"LastToken should be set after consume()"
);
20
auto
ID =
21
std::make_shared<Identifier>(Tok.range(), std::string(Tok.view()));
22
if
(peek().kind() != tok_question)
23
return
std::make_shared<Formal>(
LexerCursorRange
{LCur, LastToken->rCur()},
24
std::move(Comma), std::move(ID),
nullptr
);
25
consume();
// ?
26
std::shared_ptr<Expr> Default =
parseExpr
();
27
if
(!Default)
28
diagNullExpr
(Diags, LastToken->rCur(),
"default value"
);
29
return
std::make_shared<Formal>(
LexerCursorRange
{LCur, LastToken->rCur()},
30
std::move(Comma), std::move(ID),
31
std::move(Default));
32
}
33
if
(
Token
Tok = peek(); Tok.
kind
() == tok_ellipsis) {
34
consume();
// ...
35
assert(LastToken &&
"LastToken should be set after consume()"
);
36
std::shared_ptr<Misc> Ellipsis = std::make_shared<Misc>(Tok.range());
37
return
std::make_shared<Formal>(
LexerCursorRange
{LCur, LastToken->rCur()},
38
std::move(Comma), std::move(Ellipsis));
39
}
40
41
if
(Comma) {
42
assert(LastToken &&
"LastToken should be set after consume()"
);
43
return
std::make_shared<Formal>(
LexerCursorRange
{LCur, LastToken->rCur()},
44
std::move(Comma),
/*ID=*/
nullptr
,
45
/*Default=*/
nullptr
);
46
}
47
return
nullptr
;
48
}
49
50
std::shared_ptr<Formals>
Parser::parseFormals
() {
51
ExpectResult ER = expect(tok_l_curly);
52
if
(!ER.ok())
53
return
nullptr
;
54
Token
TokLCurly = ER.tok();
55
consume();
// {
56
assert(LastToken &&
"LastToken should be set after consume()"
);
57
auto
SyncRCurly = withSync(tok_r_curly);
58
auto
SyncComma = withSync(tok_comma);
59
auto
SyncQuestion = withSync(tok_question);
60
auto
SyncID = withSync(tok_id);
61
LexerCursor
LCur = ER.tok().
lCur
();
62
std::vector<std::shared_ptr<Formal>> Members;
63
while
(
true
) {
64
if
(
Token
Tok = peek(); Tok.
kind
() == tok_r_curly)
65
break
;
66
std::shared_ptr<Formal>
Formal
=
parseFormal
();
67
if
(
Formal
) {
68
Members.emplace_back(std::move(
Formal
));
69
continue
;
70
}
71
if
(removeUnexpected())
72
continue
;
73
break
;
74
}
75
if
(ExpectResult ER = expect(tok_r_curly); ER.ok())
76
consume();
77
else
78
ER.diag().
note
(Note::NK_ToMachThis, TokLCurly.
range
())
79
<< std::string(tok::spelling(tok_l_curly));
80
return
Act.onFormals(
LexerCursorRange
{LCur, LastToken->rCur()},
81
std::move(Members));
82
}
83
84
std::shared_ptr<LambdaArg>
Parser::parseLambdaArg
() {
85
LexerCursor
LCur = lCur();
86
if
(
Token
TokID = peek(); TokID.
kind
() == tok_id) {
87
consume();
// ID
88
assert(LastToken &&
"LastToken should be set after consume()"
);
89
auto
ID =
90
std::make_shared<Identifier>(TokID.range(), std::string(TokID.view()));
91
if
(peek().kind() != tok_at)
92
return
Act.onLambdaArg(
LexerCursorRange
{LCur, LastToken->rCur()},
93
std::move(ID),
nullptr
);
94
95
consume();
// @
96
std::shared_ptr<Formals>
Formals
=
parseFormals
();
97
if
(!
Formals
) {
98
// extra "@", consider remove it.
99
Diagnostic
&D =
100
Diags.emplace_back(Diagnostic::DK_LambdaArgExtraAt, TokID.range());
101
D.
fix
(
"remove extra @"
).
edit
(
TextEdit::mkRemoval
(TokID.range()));
102
D.
fix
(
"insert dummy formals"
)
103
.
edit
(
TextEdit::mkInsertion
(TokID.rCur(), R
"({})"));
104
}
105
return
Act.onLambdaArg(
LexerCursorRange
{LCur, LastToken->rCur()},
106
std::move(ID), std::move(
Formals
));
107
}
108
109
std::shared_ptr<Formals>
Formals
=
parseFormals
();
110
if
(!
Formals
)
111
return
nullptr
;
112
assert(LastToken &&
"LastToken should be set after valid formals"
);
113
Token
TokAt = peek();
114
if
(TokAt.
kind
() != tok_at)
115
return
Act.onLambdaArg(
LexerCursorRange
{LCur, LastToken->rCur()},
nullptr
,
116
std::move(
Formals
));
117
consume();
// @
118
ExpectResult ER = expect(tok_id);
119
if
(!ER.ok()) {
120
ER.diag().
note
(Note::NK_ToMachThis, TokAt.
range
())
121
<< std::string(tok::spelling(tok_at));
122
return
Act.onLambdaArg(
LexerCursorRange
{LCur, LastToken->rCur()},
nullptr
,
123
std::move(
Formals
));
124
}
125
consume();
// ID
126
auto
ID = std::make_shared<Identifier>(ER.tok().
range
(),
127
std::string(ER.tok().
view
()));
128
return
Act.onLambdaArg(
LexerCursorRange
{LCur, LastToken->rCur()},
129
std::move(ID), std::move(
Formals
));
130
}
131
132
std::shared_ptr<ExprLambda>
Parser::parseExprLambda
() {
133
// expr_lambda : lambda_arg ':' expr
134
LexerCursor
LCur = lCur();
135
std::shared_ptr<LambdaArg> Arg =
parseLambdaArg
();
136
assert(LastToken &&
"LastToken should be set after parseLambdaArg"
);
137
if
(!Arg)
138
return
nullptr
;
139
if
(ExpectResult ER = expect(tok_colon); ER.ok())
140
consume();
141
142
std::shared_ptr<Expr> Body =
parseExpr
();
143
if
(!Body)
144
diagNullExpr
(Diags, LastToken->rCur(),
"lambda body"
);
145
return
std::make_shared<ExprLambda>(
LexerCursorRange
{LCur, LastToken->rCur()},
146
std::move(Arg), std::move(Body));
147
}
nixf::Diagnostic::note
Note & note(Note::NoteKind Kind, LexerCursorRange Range)
Definition
Diagnostic.h:197
nixf::Diagnostic::fix
Fix & fix(std::string Message)
Definition
Diagnostic.h:203
nixf::Fix::edit
Fix & edit(TextEdit Edit)
Definition
Diagnostic.h:65
nixf::Formal
Definition
Lambda.h:11
nixf::Formals
Lambda formal arguments.
Definition
Lambda.h:58
nixf::LexerCursorRange
Definition
Range.h:105
nixf::LexerCursor
A point in the source file.
Definition
Range.h:57
nixf::Parser::parseFormals
std::shared_ptr< Formals > parseFormals()
Definition
ParseLambda.cpp:50
nixf::Parser::parseFormal
std::shared_ptr< Formal > parseFormal()
Definition
ParseLambda.cpp:6
nixf::Parser::parseExpr
std::shared_ptr< Expr > parseExpr()
Definition
ParseExpr.cpp:76
nixf::Parser::parseExprLambda
std::shared_ptr< ExprLambda > parseExprLambda()
Definition
ParseLambda.cpp:132
nixf::Parser::parseLambdaArg
std::shared_ptr< LambdaArg > parseLambdaArg()
Definition
ParseLambda.cpp:84
nixf::TextEdit::mkRemoval
static TextEdit mkRemoval(LexerCursorRange RemovingRange)
Definition
Diagnostic.h:39
nixf::TextEdit::mkInsertion
static TextEdit mkInsertion(LexerCursor P, std::string NewText)
Definition
Diagnostic.h:35
nixf::Token
A token. With it's kind, and the range in source code.
Definition
Token.h:14
nixf::Token::lCur
LexerCursor lCur() const
Definition
Token.h:22
nixf::Token::kind
tok::TokenKind kind() const
Definition
Token.h:24
nixf::Token::range
LexerCursorRange range() const
Definition
Token.h:25
nixf::Token::view
std::string_view view() const
Definition
Token.h:26
Diagnostic
Definition
Diagnostic.cpp.py:1
nixf::detail
Definition
src/Parse/Parser.h:22
nixf::detail::diagNullExpr
Diagnostic & diagNullExpr(std::vector< Diagnostic > &Diags, LexerCursor Loc, std::string As)
Definition
ParseSupport.cpp:11
nixf
Definition
Diagnostic.h:19
Parser.h
Parser for the Nix expression language.
Generated by
1.17.0