Line | Branch | Exec | Source |
---|---|---|---|
1 | #include "parser.h" | ||
2 | #include "ast/magic.h" | ||
3 | #include "ast/ops.h" | ||
4 | #include "utilities/guard.h" | ||
5 | #include "utilities/strings.h" | ||
6 | |||
7 | #define TRACE_START2(tok) \ | ||
8 | kwtrace_start( \ | ||
9 | depth, "{}: {} - `{}`", to_string(tok.type()).c_str(), tok.type(), tok.identifier()) | ||
10 | |||
11 | #define TRACE_END2(tok) kwtrace_end(depth, "{}: {}", to_string(tok.type()).c_str(), tok.type()) | ||
12 | |||
13 | #define TRACE_START() TRACE_START2(token()) | ||
14 | |||
15 | #define TRACE_END() TRACE_END2(token()) | ||
16 | |||
17 | #define MAYBE_COMMENT(obj, attr) \ | ||
18 | if (token().type() == tok_comment) { \ | ||
19 | (obj)->attr = parse_comment(parent, depth + 1); \ | ||
20 | } | ||
21 | |||
22 | namespace lython { | ||
23 | |||
24 | #define SHOW_TOK(tok) kwerror("{}", str(tok)); | ||
25 | |||
26 | // Reduce the number of dynamic alloc | ||
27 | // but debug info is not kept for the nodes | ||
28 | #define AVOID_DUPLICATE_CONST 0 | ||
29 | |||
30 | template <typename Literal> | ||
31 | ExprNode* parse_literal(Parser* parser, Node* parent, ExprNode* child, char kind, int depth); | ||
32 | |||
33 | StmtNode* not_implemented_stmt(Node* parent) { return parent->new_object<NotImplementedStmt>(); } | ||
34 | |||
35 | ExprNode* not_implemented_expr(Node* parent) { return parent->new_object<NotImplementedExpr>(); } | ||
36 | |||
37 | ExprNode* not_allowed_expr(Node* parent) { return parent->new_object<NotAllowedEpxr>(); } | ||
38 | |||
39 | void Parser::start_code_loc(CommonAttributes* target, Token tok) { | ||
40 | 7467 | target->col_offset = tok.begin_col(); | |
41 | 7467 | target->lineno = tok.line(); | |
42 | 7467 | } | |
43 | void Parser::end_code_loc(CommonAttributes* target, Token tok) { | ||
44 | 6865 | target->col_offset = tok.end_col(); | |
45 |
1/1✓ Branch 2 taken 6865 times.
|
6865 | target->end_lineno = tok.line(); |
46 | 6865 | } | |
47 | |||
48 | #define PARSER_THROW(T, err) throw T(err.message) | ||
49 | |||
50 | // Helpers | ||
51 | // --------------------------------------------- | ||
52 | |||
53 | void Parser::ensure_valid() { | ||
54 | ✗ | if (has_errors()) { | |
55 | ✗ | throw ParsingException(); | |
56 | } | ||
57 | ✗ | } | |
58 | |||
59 | void Parser::show_diagnostics(std::ostream& out) { | ||
60 | // | ||
61 |
2/2✓ Branch 1 taken 561 times.
✓ Branch 2 taken 393 times.
|
954 | if (has_errors()) { |
62 |
3/3✓ Branch 1 taken 561 times.
✓ Branch 5 taken 561 times.
✓ Branch 8 taken 561 times.
|
561 | out << "Parsing error messages (" << errors.size() << ")\n"; |
63 | |||
64 | 561 | ParsingErrorPrinter printer(out, &_lex); | |
65 | 561 | printer.with_compiler_code_loc = true; | |
66 | 561 | printer.indent = 1; | |
67 | |||
68 |
2/2✓ Branch 5 taken 565 times.
✓ Branch 6 taken 561 times.
|
1126 | for (ParsingError const& error: errors) { |
69 |
1/1✓ Branch 1 taken 565 times.
|
565 | out << " "; |
70 |
1/1✓ Branch 1 taken 565 times.
|
565 | printer.print(error); |
71 |
1/1✓ Branch 1 taken 565 times.
|
565 | out << "\n"; |
72 | } | ||
73 | 561 | } | |
74 | 954 | } | |
75 | |||
76 | void Parser::expect_token(int expected, bool eat, Node* wip_expression, CodeLocation const& loc) { | ||
77 |
2/2✓ Branch 2 taken 9679 times.
✓ Branch 5 taken 9433 times.
|
9925 | return expect_tokens(Array<int>{expected}, eat, wip_expression, loc); |
78 | } | ||
79 | |||
80 | OpConfig const& Parser::get_operator_config(Token const& tok) const { | ||
81 | static OpConfig nothing; | ||
82 | |||
83 |
1/1✓ Branch 1 taken 896 times.
|
896 | Dict<String, OpConfig> const& confs = default_precedence(); |
84 | |||
85 |
1/1✓ Branch 2 taken 896 times.
|
896 | auto result = confs.find(tok.operator_name()); |
86 |
2/2✓ Branch 2 taken 512 times.
✓ Branch 3 taken 384 times.
|
896 | if (result == confs.end()) { |
87 | 512 | return nothing; | |
88 | } | ||
89 | 384 | return result->second; | |
90 | } | ||
91 | |||
92 | bool Parser::is_binary_operator_family(OpConfig const& conf) { | ||
93 |
4/4✓ Branch 0 taken 155 times.
✓ Branch 1 taken 154 times.
✓ Branch 2 taken 44 times.
✓ Branch 3 taken 111 times.
|
353 | return conf.binarykind != BinaryOperator::None || conf.cmpkind != CmpOperator::None || |
94 |
2/2✓ Branch 0 taken 34 times.
✓ Branch 1 taken 10 times.
|
353 | conf.boolkind != BoolOperator::None; |
95 | } | ||
96 | |||
97 | void Parser::expect_operator(String const& op, | ||
98 | bool eat, | ||
99 | Node* wip_expression, | ||
100 | CodeLocation const& loc) { | ||
101 | ✗ | Token tok = token(); | |
102 | |||
103 | expect_token(tok_operator, eat, wip_expression, LOC); | ||
104 | |||
105 | ✗ | if (tok.operator_name() == op) { | |
106 | ✗ | return; | |
107 | } | ||
108 | |||
109 | ✗ | ParsingError& error = parser_kwerror( // | |
110 | loc, // | ||
111 | "SyntaxError", // | ||
112 | ✗ | fmtstr("Wrong operator expected {} but got {}", op, tok.operator_name()) // | |
113 | // | ||
114 | ); | ||
115 | |||
116 | ✗ | add_wip_expr(error, wip_expression); | |
117 | ✗ | PARSER_THROW(SyntaxError, error); | |
118 | ✗ | } | |
119 | |||
120 | void Parser::expect_tokens(Array<int> const& expected, | ||
121 | bool eat, | ||
122 | Node* wip_expression, | ||
123 | CodeLocation const& loc) { | ||
124 |
1/1✓ Branch 1 taken 13917 times.
|
13917 | auto toktype = token().type(); |
125 | |||
126 |
2/2✓ Branch 5 taken 16820 times.
✓ Branch 6 taken 251 times.
|
17071 | for (auto& tok: expected) { |
127 |
2/2✓ Branch 0 taken 13666 times.
✓ Branch 1 taken 3154 times.
|
16820 | if (toktype == tok) { |
128 |
2/2✓ Branch 0 taken 13535 times.
✓ Branch 1 taken 131 times.
|
13666 | if (eat) { |
129 |
1/1✓ Branch 1 taken 13535 times.
|
13535 | next_token(); |
130 | } | ||
131 | 13666 | return; | |
132 | } | ||
133 | } | ||
134 | // ---- | ||
135 | 251 | Array<String> expected_str; | |
136 |
1/1✓ Branch 2 taken 251 times.
|
251 | expected_str.reserve(expected.size()); |
137 |
2/2✓ Branch 4 taken 256 times.
✓ Branch 5 taken 251 times.
|
507 | for (auto& ex: expected) { |
138 |
2/2✓ Branch 1 taken 256 times.
✓ Branch 4 taken 256 times.
|
256 | expected_str.push_back(str(TokenType(ex))); |
139 | } | ||
140 | |||
141 |
2/2✓ Branch 2 taken 251 times.
✓ Branch 5 taken 251 times.
|
251 | ParsingError& error = parser_kwerror( // |
142 | loc, // | ||
143 | "SyntaxError", // | ||
144 |
3/3✓ Branch 2 taken 251 times.
✓ Branch 5 taken 251 times.
✓ Branch 8 taken 251 times.
|
753 | fmtstr("Expected {} got {}", join(", ", expected), toktype) // |
145 | ); | ||
146 |
1/1✓ Branch 1 taken 251 times.
|
251 | error.expected_tokens = expected; |
147 |
2/2✓ Branch 1 taken 251 times.
✓ Branch 4 taken 251 times.
|
251 | error.received_token = token(); |
148 | |||
149 |
1/1✓ Branch 1 taken 251 times.
|
251 | add_wip_expr(error, wip_expression); |
150 |
1/1✓ Branch 2 taken 251 times.
|
251 | PARSER_THROW(SyntaxError, error); |
151 | 251 | } | |
152 | |||
153 | Token Parser::parse_body(Node* parent, Array<StmtNode*>& out, int depth) { | ||
154 | TRACE_START(); | ||
155 | |||
156 |
4/4✓ Branch 1 taken 4705 times.
✓ Branch 5 taken 4705 times.
✓ Branch 7 taken 2511 times.
✓ Branch 8 taken 2194 times.
|
4705 | while (!in(token().type(), tok_desindent, tok_eof)) { |
157 | |||
158 | // Found an unexpected token | ||
159 | // eat the full line to try to recover and emit an error | ||
160 |
2/3✓ Branch 1 taken 2511 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 2511 times.
|
2511 | if (token().type() == tok_incorrect) { |
161 | ✗ | ParsingError& error = parser_kwerror( // | |
162 | LOC, // | ||
163 | "SyntaxError", // | ||
164 | "Unexpected token" // | ||
165 | ); | ||
166 | ✗ | add_wip_expr(error, parent); | |
167 | ✗ | error_recovery(&error); | |
168 | |||
169 | ✗ | InvalidStatement* stmt = parent->new_object<InvalidStatement>(); | |
170 | ✗ | stmt->tokens = error.line; | |
171 | ✗ | out.push_back(stmt); | |
172 | ✗ | continue; | |
173 | ✗ | } | |
174 | |||
175 | // Comment attach themselves to the next statement | ||
176 | // when comments are inserted at the beginning of a block | ||
177 | // they can be inserted to the previous block instead | ||
178 |
3/3✓ Branch 1 taken 2511 times.
✓ Branch 4 taken 116 times.
✓ Branch 5 taken 2395 times.
|
2511 | if (token().type() == tok_comment) { |
179 |
1/1✓ Branch 1 taken 116 times.
|
116 | StmtNode* cmt = parse_comment_stmt(parent, depth); |
180 |
1/1✓ Branch 1 taken 116 times.
|
116 | _pending_comments.push_back(cmt); |
181 | 116 | continue; | |
182 | 116 | } | |
183 | |||
184 | // we have read a bunch of comments and we are still in this block | ||
185 | { | ||
186 |
2/2✓ Branch 5 taken 105 times.
✓ Branch 6 taken 2395 times.
|
2500 | for (auto* comment: _pending_comments) { |
187 |
1/1✓ Branch 1 taken 105 times.
|
105 | out.push_back(comment); |
188 | } | ||
189 | 2395 | _pending_comments.clear(); | |
190 | } | ||
191 | |||
192 | try { | ||
193 |
1/1✓ Branch 1 taken 1834 times.
|
2395 | auto stmt = parse_statement(parent, depth + 1); |
194 | |||
195 | // only one liner should have the comment attached | ||
196 |
8/8✓ Branch 1 taken 1834 times.
✓ Branch 3 taken 982 times.
✓ Branch 4 taken 852 times.
✓ Branch 6 taken 982 times.
✓ Branch 9 taken 120 times.
✓ Branch 10 taken 862 times.
✓ Branch 11 taken 120 times.
✓ Branch 12 taken 1714 times.
|
1834 | if (stmt->is_one_line() && token().type() == tok_comment) { |
197 |
1/1✓ Branch 1 taken 120 times.
|
120 | stmt->comment = parse_comment(stmt, depth); |
198 | } | ||
199 | |||
200 |
2/2✓ Branch 0 taken 1776 times.
✓ Branch 1 taken 58 times.
|
1834 | if (!is_empty_line) { |
201 | // expects at least one newline to end the statement | ||
202 | // if not we do not know what this line is supposed to be | ||
203 | expect_tokens({tok_newline, tok_eof}, true, parent, LOC); | ||
204 | } | ||
205 | |||
206 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1830 times.
|
1830 | if (stmt == nullptr) { |
207 | ✗ | return token(); | |
208 | } | ||
209 | |||
210 |
1/1✓ Branch 1 taken 1830 times.
|
1830 | out.push_back(stmt); |
211 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 565 times.
|
565 | } catch (ParsingException const&) { |
212 | // | ||
213 | 565 | ParsingError* error = &errors[current_error]; | |
214 |
1/1✓ Branch 1 taken 565 times.
|
565 | error_recovery(error); |
215 | |||
216 |
1/1✓ Branch 1 taken 565 times.
|
565 | InvalidStatement* stmt = parent->new_object<InvalidStatement>(); |
217 |
1/1✓ Branch 1 taken 565 times.
|
565 | stmt->tokens = error->line; |
218 |
1/1✓ Branch 1 taken 565 times.
|
565 | out.push_back(stmt); |
219 | 565 | } | |
220 | |||
221 | // look for the desindent token or next statement | ||
222 |
3/3✓ Branch 1 taken 2479 times.
✓ Branch 4 taken 84 times.
✓ Branch 5 taken 2395 times.
|
2479 | while (token().type() == tok_newline) { |
223 |
1/1✓ Branch 1 taken 84 times.
|
84 | next_token(); |
224 | } | ||
225 | } | ||
226 | |||
227 |
2/2✓ Branch 1 taken 30 times.
✓ Branch 2 taken 2164 times.
|
2194 | if (out.size() <= 0) { |
228 |
2/2✓ Branch 2 taken 30 times.
✓ Branch 6 taken 30 times.
|
60 | ParsingError& error = parser_kwerror( // |
229 | LOC, // | ||
230 | "SyntaxError", // | ||
231 | "Expected a body" // | ||
232 | ); | ||
233 |
1/1✓ Branch 1 taken 30 times.
|
30 | add_wip_expr(error, parent); |
234 |
1/1✓ Branch 2 taken 30 times.
|
30 | PARSER_THROW(SyntaxError, error); |
235 | } | ||
236 | |||
237 |
2/2✓ Branch 1 taken 2164 times.
✓ Branch 4 taken 2164 times.
|
2164 | auto last = token(); |
238 | |||
239 |
6/6✓ Branch 1 taken 1797 times.
✓ Branch 2 taken 367 times.
✓ Branch 3 taken 1484 times.
✓ Branch 4 taken 313 times.
✓ Branch 5 taken 1484 times.
✓ Branch 6 taken 680 times.
|
2164 | if (last.type() == tok_eof && depth == 0) { |
240 | // reached eof, insert all the comments here | ||
241 |
2/2✓ Branch 5 taken 11 times.
✓ Branch 6 taken 1484 times.
|
1495 | for (auto* comment: _pending_comments) { |
242 |
1/1✓ Branch 1 taken 11 times.
|
11 | out.push_back(comment); |
243 | } | ||
244 | 1484 | _pending_comments.clear(); | |
245 | } | ||
246 | // | ||
247 | expect_tokens({tok_desindent, tok_eof}, true, parent, LOC); | ||
248 | 2164 | return last; | |
249 | 2164 | } | |
250 | |||
251 | bool Parser::is_tok_statement_ender() const { | ||
252 | // returns true if the token terminates a statement | ||
253 |
2/2✓ Branch 1 taken 508 times.
✓ Branch 5 taken 508 times.
|
508 | return in(token().type(), tok_newline, tok_eof, tok_comment); |
254 | } | ||
255 | |||
256 | void Parser::expect_newline(Node* stmt, CodeLocation const& loc) { | ||
257 | 921 | expect_token(tok_newline, true, stmt, loc); | |
258 | |||
259 |
2/2✓ Branch 2 taken 1 times.
✓ Branch 3 taken 887 times.
|
888 | while (token().type() == tok_newline) { |
260 | 1 | next_token(); | |
261 | } | ||
262 | 887 | } | |
263 | |||
264 | // Statement_1 | ||
265 | StmtNode* Parser::parse_function_def(Node* parent, bool async, int depth) { | ||
266 | TRACE_START(); | ||
267 | |||
268 | 216 | FunctionDef* stmt = nullptr; | |
269 |
2/2✓ Branch 1 taken 216 times.
✓ Branch 4 taken 216 times.
|
216 | auto start = token(); |
270 |
1/1✓ Branch 1 taken 216 times.
|
216 | async_mode.push_back(async); |
271 | |||
272 |
1/2✓ Branch 0 taken 216 times.
✗ Branch 1 not taken.
|
216 | if (!async) { |
273 |
1/1✓ Branch 1 taken 216 times.
|
216 | stmt = parent->new_object<FunctionDef>(); |
274 | } else { | ||
275 | ✗ | next_token(); // eat async | |
276 | ✗ | stmt = parent->new_object<AsyncFunctionDef>(); | |
277 | } | ||
278 | |||
279 |
3/4✓ Branch 1 taken 216 times.
✓ Branch 3 taken 216 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 216 times.
|
216 | start_code_loc(stmt, start); |
280 |
1/1✓ Branch 1 taken 216 times.
|
216 | next_token(); |
281 | |||
282 |
2/2✓ Branch 1 taken 216 times.
✓ Branch 4 taken 216 times.
|
216 | stmt->name = get_identifier(); |
283 | |||
284 | expect_token(tok_identifier, true, stmt, LOC); | ||
285 | expect_token(tok_parens, true, stmt, LOC); | ||
286 |
2/2✓ Branch 1 taken 182 times.
✓ Branch 4 taken 182 times.
|
210 | stmt->args = parse_arguments(stmt, ')', depth + 1); |
287 | |||
288 |
3/3✓ Branch 1 taken 182 times.
✓ Branch 4 taken 78 times.
✓ Branch 5 taken 104 times.
|
182 | if (token().type() == tok_arrow) { |
289 |
1/1✓ Branch 1 taken 78 times.
|
78 | next_token(); |
290 |
2/2✓ Branch 1 taken 77 times.
✓ Branch 4 taken 77 times.
|
78 | stmt->returns = parse_expression(stmt, depth + 1); |
291 | } | ||
292 | |||
293 | expect_token(':', true, stmt, LOC); | ||
294 | expect_comment_or_newline(stmt, depth, LOC); | ||
295 | expect_token(tok_indent, true, stmt, LOC); | ||
296 | |||
297 |
3/3✓ Branch 1 taken 170 times.
✓ Branch 4 taken 10 times.
✓ Branch 5 taken 160 times.
|
170 | if (token().type() == tok_docstring) { |
298 | 10 | Comment* comment = nullptr; | |
299 |
2/2✓ Branch 1 taken 10 times.
✓ Branch 5 taken 10 times.
|
10 | String docstring = token().identifier(); |
300 | |||
301 |
1/1✓ Branch 1 taken 10 times.
|
10 | next_token(); |
302 |
3/3✓ Branch 1 taken 10 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 9 times.
|
10 | if (token().type() == tok_comment) { |
303 |
1/1✓ Branch 1 taken 1 times.
|
1 | comment = parse_comment(parent, depth + 1); |
304 | } | ||
305 | |||
306 |
2/2✓ Branch 1 taken 10 times.
✓ Branch 4 taken 10 times.
|
10 | stmt->docstring = Docstring(docstring, comment); |
307 | expect_newline(stmt, LOC); | ||
308 | 10 | } | |
309 | |||
310 |
1/1✓ Branch 1 taken 165 times.
|
169 | auto last = parse_body(stmt, stmt->body, depth + 1); |
311 |
3/4✓ Branch 1 taken 165 times.
✓ Branch 3 taken 165 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 165 times.
|
165 | end_code_loc(stmt, last); |
312 | 165 | async_mode.pop_back(); | |
313 | |||
314 | TRACE_END(); | ||
315 | 165 | return stmt; | |
316 | 216 | } | |
317 | |||
318 | StmtNode* Parser::parse_class_def(Node* parent, int depth) { | ||
319 | TRACE_START(); | ||
320 | |||
321 |
1/1✓ Branch 1 taken 76 times.
|
76 | auto stmt = parent->new_object<ClassDef>(); |
322 |
4/5✓ Branch 1 taken 76 times.
✓ Branch 4 taken 76 times.
✓ Branch 6 taken 76 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 76 times.
|
76 | start_code_loc(stmt, token()); |
323 |
1/1✓ Branch 1 taken 76 times.
|
76 | next_token(); |
324 | |||
325 |
2/2✓ Branch 1 taken 76 times.
✓ Branch 4 taken 76 times.
|
76 | stmt->name = get_identifier(); |
326 | expect_token(tok_identifier, true, stmt, LOC); | ||
327 | |||
328 | // Parse bases | ||
329 |
3/3✓ Branch 1 taken 74 times.
✓ Branch 4 taken 18 times.
✓ Branch 5 taken 56 times.
|
74 | if (token().type() == tok_parens) { |
330 |
1/1✓ Branch 1 taken 18 times.
|
18 | next_token(); |
331 |
1/1✓ Branch 1 taken 12 times.
|
18 | parse_call_args(stmt, stmt->bases, stmt->keywords, depth + 1); |
332 | } | ||
333 | |||
334 | expect_token(':', true, stmt, LOC); | ||
335 | expect_comment_or_newline(stmt, depth, LOC); | ||
336 | expect_token(tok_indent, true, stmt, LOC); | ||
337 | |||
338 |
3/3✓ Branch 1 taken 61 times.
✓ Branch 4 taken 8 times.
✓ Branch 5 taken 53 times.
|
61 | if (token().type() == tok_docstring) { |
339 | 8 | Comment* comment = nullptr; | |
340 |
2/2✓ Branch 1 taken 8 times.
✓ Branch 5 taken 8 times.
|
8 | String docstring = token().identifier(); |
341 |
1/1✓ Branch 1 taken 8 times.
|
8 | next_token(); |
342 | |||
343 |
3/3✓ Branch 1 taken 8 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 7 times.
|
8 | if (token().type() == tok_comment) { |
344 |
1/1✓ Branch 1 taken 1 times.
|
1 | comment = parse_comment(parent, depth + 1); |
345 | } | ||
346 | |||
347 |
2/2✓ Branch 1 taken 8 times.
✓ Branch 4 taken 8 times.
|
8 | stmt->docstring = Docstring(docstring, comment); |
348 | expect_newline(stmt, LOC); | ||
349 | 8 | } | |
350 | |||
351 |
1/1✓ Branch 1 taken 57 times.
|
60 | auto last = parse_body(stmt, stmt->body, depth + 1); |
352 | |||
353 |
2/2✓ Branch 5 taken 135 times.
✓ Branch 6 taken 54 times.
|
189 | for (auto child: stmt->body) { |
354 | // this checks we do not have expression inside the body of a class | ||
355 |
1/1✓ Branch 1 taken 135 times.
|
135 | Expr* exprstmt = cast<Expr>(child); |
356 | |||
357 | // Comments are fine though | ||
358 |
4/4✓ Branch 0 taken 4 times.
✓ Branch 1 taken 131 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 1 times.
|
135 | if (exprstmt && exprstmt->value->kind != NodeKind::Comment) { |
359 |
2/2✓ Branch 2 taken 3 times.
✓ Branch 6 taken 3 times.
|
6 | ParsingError& error = parser_kwerror( // |
360 | LOC, // | ||
361 | "SyntaxError", // | ||
362 | "Unsupported statement inside a classdef" // | ||
363 | ); | ||
364 |
1/1✓ Branch 1 taken 3 times.
|
3 | add_wip_expr(error, parent); |
365 |
1/1✓ Branch 2 taken 3 times.
|
3 | PARSER_THROW(SyntaxError, error); |
366 | } | ||
367 | } | ||
368 | |||
369 |
3/4✓ Branch 1 taken 54 times.
✓ Branch 3 taken 54 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 54 times.
|
54 | end_code_loc(stmt, last); |
370 | 54 | return stmt; | |
371 | 57 | } | |
372 | ExprNode* Parser::parse_star_expression(Node* parent, int depth) { | ||
373 | // star_expressions: | ||
374 | // | star_expression (',' star_expression )+ [','] | ||
375 | // | star_expression ',' | ||
376 | // | star_expression | ||
377 | // star_expression: | ||
378 | // | '*' bitwise_or | ||
379 | // | expression | ||
380 | ✗ | return parse_expression(parent, depth); | |
381 | } | ||
382 | |||
383 | ExprNode* Parser::parse_star_targets(Node* parent, int depth) { | ||
384 |
2/2✓ Branch 1 taken 104 times.
✓ Branch 4 taken 104 times.
|
104 | auto start_tok = token(); |
385 | |||
386 | // auto kind = 0; | ||
387 | // bool has_parens = false; | ||
388 |
2/3✓ Branch 1 taken 104 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 104 times.
|
104 | if (token().type() == tok_parens) { |
389 | ✗ | next_token(); | |
390 | // kind = tok_parens; | ||
391 | // has_parens = true; | ||
392 | } | ||
393 | |||
394 | 104 | Array<ExprNode*> elts; | |
395 |
1/1✓ Branch 1 taken 98 times.
|
104 | auto r = parse_expression_primary(parent, depth + 1); |
396 |
1/1✓ Branch 1 taken 98 times.
|
98 | elts.push_back(r); |
397 | |||
398 |
3/3✓ Branch 1 taken 126 times.
✓ Branch 4 taken 34 times.
✓ Branch 5 taken 92 times.
|
126 | while (token().type() == tok_comma) { |
399 |
1/1✓ Branch 1 taken 34 times.
|
34 | next_token(); |
400 |
2/2✓ Branch 1 taken 28 times.
✓ Branch 4 taken 28 times.
|
34 | elts.push_back(parse_expression_primary(parent, depth + 1)); |
401 | }; | ||
402 | |||
403 |
2/2✓ Branch 1 taken 78 times.
✓ Branch 2 taken 14 times.
|
92 | if (elts.size() == 1) { |
404 |
3/4✓ Branch 1 taken 78 times.
✓ Branch 4 taken 78 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 78 times.
|
78 | start_code_loc(elts[0], start_tok); |
405 |
4/5✓ Branch 1 taken 78 times.
✓ Branch 4 taken 78 times.
✓ Branch 7 taken 78 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 78 times.
|
78 | end_code_loc(elts[0], token()); |
406 | 78 | return elts[0]; | |
407 | } | ||
408 | |||
409 |
1/1✓ Branch 1 taken 14 times.
|
14 | auto expr = parent->new_object<TupleExpr>(); |
410 |
3/4✓ Branch 1 taken 14 times.
✓ Branch 3 taken 14 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 14 times.
|
14 | start_code_loc(expr, start_tok); |
411 |
1/1✓ Branch 1 taken 14 times.
|
14 | expr->elts = elts; |
412 | 14 | expr->ctx = ExprContext::Store; | |
413 |
4/5✓ Branch 1 taken 14 times.
✓ Branch 4 taken 14 times.
✓ Branch 6 taken 14 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 14 times.
|
14 | end_code_loc(expr, token()); |
414 | 14 | return expr; | |
415 | |||
416 | // star_targets: | ||
417 | // | star_target !',' | ||
418 | // | star_target (',' star_target )* [','] | ||
419 | // star_target: | ||
420 | // | '*' (!'*' star_target) | ||
421 | // | target_with_star_atom | ||
422 | // target_with_star_atom: | ||
423 | // | t_primary '.' NAME !t_lookahead | ||
424 | // | t_primary '[' slices ']' !t_lookahead | ||
425 | // | star_atom | ||
426 | // star_atom: | ||
427 | // | NAME | ||
428 | // | '(' target_with_star_atom ')' | ||
429 | // | '(' [star_targets_tuple_seq] ')' | ||
430 | // | '[' [star_targets_list_seq] ']' | ||
431 | // t_primary: | ||
432 | // | t_primary '.' NAME &t_lookahead | ||
433 | // | t_primary '[' slices ']' &t_lookahead | ||
434 | // | t_primary genexp &t_lookahead | ||
435 | // | t_primary '(' [arguments] ')' &t_lookahead | ||
436 | // | atom &t_lookahead | ||
437 | // t_lookahead: '(' | '[' | '.' | ||
438 | 116 | } | |
439 | |||
440 | void Parser::expect_comment_or_newline(StmtNode* stmt, int depth, CodeLocation const& loc) { | ||
441 | 533 | add_inline_comment(stmt, depth); | |
442 | 533 | expect_newline(stmt, loc); | |
443 | 517 | } | |
444 | |||
445 | StmtNode* Parser::parse_for(Node* parent, int depth) { | ||
446 | TRACE_START(); | ||
447 | |||
448 | 48 | For* stmt = nullptr; | |
449 |
2/3✓ Branch 1 taken 48 times.
✓ Branch 3 taken 48 times.
✗ Branch 4 not taken.
|
48 | if (!async()) { |
450 |
1/1✓ Branch 1 taken 48 times.
|
48 | stmt = parent->new_object<For>(); |
451 | } else { | ||
452 | ✗ | stmt = parent->new_object<AsyncFor>(); | |
453 | ✗ | stmt->async = true; | |
454 | } | ||
455 | |||
456 |
4/5✓ Branch 1 taken 48 times.
✓ Branch 4 taken 48 times.
✓ Branch 6 taken 48 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 48 times.
|
48 | start_code_loc(stmt, token()); |
457 |
1/1✓ Branch 1 taken 48 times.
|
48 | next_token(); |
458 | |||
459 | // Store context i.e the variables are created there | ||
460 |
1/1✓ Branch 1 taken 48 times.
|
48 | _context.push_back(ExprContext::Store); |
461 |
1/1✓ Branch 1 taken 40 times.
|
48 | stmt->target = parse_star_targets(stmt, depth + 1); |
462 | 40 | _context.pop_back(); | |
463 | |||
464 | // the right context was already picked up | ||
465 | // set_context(stmt->target, ExprContext::Store); | ||
466 | |||
467 | expect_token(tok_in, true, stmt, LOC); | ||
468 |
1/1✓ Branch 1 taken 34 times.
|
36 | stmt->iter = parse_expression(stmt, depth + 1); |
469 | |||
470 | expect_token(':', true, parent, LOC); | ||
471 | |||
472 | expect_comment_or_newline(stmt, depth, LOC); | ||
473 | expect_token(tok_indent, true, parent, LOC); | ||
474 | |||
475 |
1/1✓ Branch 1 taken 26 times.
|
28 | auto last = parse_body(stmt, stmt->body, depth + 1); |
476 | |||
477 |
3/3✓ Branch 1 taken 26 times.
✓ Branch 4 taken 10 times.
✓ Branch 5 taken 16 times.
|
26 | if (token().type() == tok_else) { |
478 |
1/1✓ Branch 1 taken 10 times.
|
10 | next_token(); |
479 | expect_token(':', true, stmt, LOC); | ||
480 | |||
481 |
4/4✓ Branch 1 taken 9 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 8 times.
✓ Branch 7 taken 1 times.
|
9 | MAYBE_COMMENT(stmt, else_comment); |
482 | expect_newline(stmt, LOC); | ||
483 | |||
484 | expect_token(tok_indent, true, stmt, LOC); | ||
485 | |||
486 |
1/1✓ Branch 1 taken 6 times.
|
7 | last = parse_body(stmt, stmt->orelse, depth + 1); |
487 | } | ||
488 | |||
489 |
3/4✓ Branch 1 taken 22 times.
✓ Branch 3 taken 22 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 22 times.
|
22 | end_code_loc(stmt, last); |
490 | 22 | return stmt; | |
491 | 26 | } | |
492 | |||
493 | StmtNode* Parser::parse_while(Node* parent, int depth) { | ||
494 | TRACE_START(); | ||
495 | |||
496 |
1/1✓ Branch 1 taken 25 times.
|
25 | auto stmt = parent->new_object<While>(); |
497 |
4/5✓ Branch 1 taken 25 times.
✓ Branch 4 taken 25 times.
✓ Branch 6 taken 25 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 25 times.
|
25 | start_code_loc(stmt, token()); |
498 |
1/1✓ Branch 1 taken 25 times.
|
25 | next_token(); |
499 | |||
500 |
1/1✓ Branch 1 taken 24 times.
|
25 | stmt->test = parse_expression(stmt, depth + 1); |
501 | expect_token(':', true, stmt, LOC); | ||
502 | expect_comment_or_newline(stmt, depth, LOC); | ||
503 | expect_token(tok_indent, true, stmt, LOC); | ||
504 | |||
505 |
1/1✓ Branch 1 taken 20 times.
|
21 | auto last = parse_body(stmt, stmt->body, depth + 1); |
506 | |||
507 |
3/3✓ Branch 1 taken 20 times.
✓ Branch 4 taken 11 times.
✓ Branch 5 taken 9 times.
|
20 | if (token().type() == tok_else) { |
508 |
1/1✓ Branch 1 taken 11 times.
|
11 | next_token(); |
509 | expect_token(':', true, stmt, LOC); | ||
510 | |||
511 |
4/4✓ Branch 1 taken 10 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 9 times.
✓ Branch 7 taken 1 times.
|
10 | MAYBE_COMMENT(stmt, else_comment); |
512 | expect_newline(stmt, LOC); | ||
513 | |||
514 | expect_token(tok_indent, true, stmt, LOC); | ||
515 |
1/1✓ Branch 1 taken 7 times.
|
8 | last = parse_body(stmt, stmt->orelse, depth + 1); |
516 | } | ||
517 | |||
518 |
3/4✓ Branch 1 taken 16 times.
✓ Branch 3 taken 16 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 16 times.
|
16 | end_code_loc(stmt, last); |
519 | 16 | return stmt; | |
520 | 20 | } | |
521 | |||
522 | StmtNode* Parser::parse_if_alt(Node* parent, int depth) { | ||
523 | TRACE_START(); | ||
524 | |||
525 |
1/1✓ Branch 1 taken 33 times.
|
33 | auto stmt = parent->new_object<If>(); |
526 |
4/5✓ Branch 1 taken 33 times.
✓ Branch 4 taken 33 times.
✓ Branch 6 taken 33 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 33 times.
|
33 | start_code_loc(stmt, token()); |
527 |
1/1✓ Branch 1 taken 33 times.
|
33 | next_token(); |
528 |
1/1✓ Branch 2 taken 33 times.
|
33 | Token last = dummy(); |
529 | |||
530 | // Parse first If | ||
531 | { | ||
532 |
1/1✓ Branch 1 taken 32 times.
|
33 | stmt->test = parse_expression(stmt, depth + 1); |
533 | |||
534 | expect_token(':', true, stmt, LOC); | ||
535 | expect_comment_or_newline(stmt, depth, LOC); | ||
536 | expect_token(tok_indent, true, stmt, LOC); | ||
537 | |||
538 |
1/1✓ Branch 1 taken 28 times.
|
29 | auto last = parse_body(stmt, stmt->body, depth + 1); |
539 | 28 | } | |
540 | |||
541 |
3/3✓ Branch 1 taken 42 times.
✓ Branch 4 taken 19 times.
✓ Branch 5 taken 23 times.
|
42 | while (token().type() == tok_elif) { |
542 |
1/1✓ Branch 1 taken 19 times.
|
19 | next_token(); |
543 | |||
544 |
1/1✓ Branch 1 taken 18 times.
|
19 | auto test = parse_expression(stmt, depth + 1); |
545 | expect_token(':', true, stmt, LOC); | ||
546 | |||
547 | // We need to push a comment even if there is nothing | ||
548 | // because we will zip between tests and tests_comments | ||
549 | 17 | int n = int(stmt->tests_comment.size()); | |
550 |
1/1✓ Branch 1 taken 17 times.
|
17 | stmt->tests_comment.push_back(nullptr); |
551 | |||
552 |
4/4✓ Branch 1 taken 17 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 16 times.
✓ Branch 7 taken 1 times.
|
17 | MAYBE_COMMENT(stmt, tests_comment[n]); |
553 | expect_newline(stmt, LOC); | ||
554 | expect_token(tok_indent, true, stmt, LOC); | ||
555 | |||
556 | 15 | Array<StmtNode*> body; | |
557 |
1/1✓ Branch 1 taken 14 times.
|
15 | last = parse_body(stmt, body, depth + 1); |
558 | |||
559 |
1/1✓ Branch 1 taken 14 times.
|
14 | stmt->tests.push_back(test); |
560 |
1/1✓ Branch 1 taken 14 times.
|
14 | stmt->bodies.push_back(body); |
561 | 15 | } | |
562 | |||
563 | // The else belongs to the last ifexpr if any | ||
564 |
3/3✓ Branch 1 taken 23 times.
✓ Branch 4 taken 13 times.
✓ Branch 5 taken 10 times.
|
23 | if (token().type() == tok_else) { |
565 |
1/1✓ Branch 1 taken 13 times.
|
13 | next_token(); |
566 | |||
567 | expect_token(':', true, stmt, LOC); | ||
568 | |||
569 |
4/4✓ Branch 1 taken 12 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 11 times.
✓ Branch 7 taken 1 times.
|
12 | MAYBE_COMMENT(stmt, else_comment); |
570 | expect_newline(stmt, LOC); | ||
571 | |||
572 | expect_token(tok_indent, true, stmt, LOC); | ||
573 | |||
574 |
1/1✓ Branch 1 taken 9 times.
|
10 | last = parse_body(stmt, stmt->orelse, depth + 1); |
575 | } | ||
576 | |||
577 |
3/4✓ Branch 1 taken 19 times.
✓ Branch 3 taken 19 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 19 times.
|
19 | end_code_loc(stmt, last); |
578 | 19 | return stmt; | |
579 | 33 | } | |
580 | |||
581 | StmtNode* Parser::parse_if(Node* parent, int depth) { | ||
582 | TRACE_START(); | ||
583 | |||
584 | ✗ | auto stmt = parent->new_object<If>(); | |
585 | ✗ | start_code_loc(stmt, token()); | |
586 | ✗ | next_token(); | |
587 | |||
588 | ✗ | stmt->test = parse_expression(stmt, depth + 1); | |
589 | |||
590 | expect_token(':', true, stmt, LOC); | ||
591 | expect_comment_or_newline(stmt, depth, LOC); | ||
592 | expect_token(tok_indent, true, stmt, LOC); | ||
593 | |||
594 | ✗ | auto last = parse_body(stmt, stmt->body, depth + 1); | |
595 | |||
596 | // The else belongs to the last if if any | ||
597 | ✗ | if (token().type() == tok_else) { | |
598 | ✗ | next_token(); | |
599 | |||
600 | expect_token(':', true, stmt, LOC); | ||
601 | |||
602 | ✗ | MAYBE_COMMENT(stmt, else_comment); | |
603 | expect_newline(stmt, LOC); | ||
604 | |||
605 | expect_token(tok_indent, true, stmt, LOC); | ||
606 | |||
607 | ✗ | last = parse_body(stmt, stmt->orelse, depth + 1); | |
608 | } | ||
609 | |||
610 | // This is interesting looks like python does not chain ifs in the AST | ||
611 | ✗ | if (token().type() == tok_elif) { | |
612 | ✗ | auto elseif = parse_if(stmt, depth + 1); | |
613 | ✗ | stmt->orelse.push_back(elseif); | |
614 | } | ||
615 | |||
616 | ✗ | end_code_loc(stmt, last); | |
617 | ✗ | return stmt; | |
618 | ✗ | } | |
619 | |||
620 | // [<pattern>, <pattern>, ...] | ||
621 | Pattern* Parser::parse_match_sequence(Node* parent, int depth) { | ||
622 | TRACE_START(); | ||
623 | |||
624 | 111 | auto pat = parent->new_object<MatchSequence>(); | |
625 |
4/5✓ Branch 1 taken 111 times.
✓ Branch 4 taken 111 times.
✓ Branch 6 taken 111 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 111 times.
|
111 | start_code_loc(pat, token()); |
626 | 111 | next_token(); | |
627 | |||
628 |
2/2✓ Branch 2 taken 169 times.
✓ Branch 3 taken 24 times.
|
193 | while (token().type() != ']') { |
629 |
1/1✓ Branch 1 taken 163 times.
|
169 | auto child = parse_pattern(pat, depth + 1); |
630 |
1/1✓ Branch 1 taken 163 times.
|
163 | pat->patterns.push_back(child); |
631 | |||
632 |
3/3✓ Branch 1 taken 163 times.
✓ Branch 4 taken 82 times.
✓ Branch 5 taken 81 times.
|
163 | if (token().type() == tok_comma) { |
633 |
1/1✓ Branch 1 taken 82 times.
|
82 | next_token(); |
634 | } else { | ||
635 | 81 | break; | |
636 | } | ||
637 | } | ||
638 | |||
639 |
4/5✓ Branch 1 taken 105 times.
✓ Branch 4 taken 105 times.
✓ Branch 6 taken 105 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 105 times.
|
105 | end_code_loc(pat, token()); |
640 | expect_token(']', true, pat, LOC); | ||
641 | TRACE_END(); | ||
642 | 101 | return pat; | |
643 | } | ||
644 | |||
645 | // *<identifier> | ||
646 | Pattern* Parser::parse_match_star(Node* parent, int depth) { | ||
647 | TRACE_START(); | ||
648 | |||
649 | 13 | auto pat = parent->new_object<MatchStar>(); | |
650 |
4/5✓ Branch 1 taken 13 times.
✓ Branch 4 taken 13 times.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 13 times.
|
13 | start_code_loc(pat, token()); |
651 | 13 | next_token(); | |
652 | |||
653 |
3/3✓ Branch 1 taken 13 times.
✓ Branch 4 taken 13 times.
✓ Branch 7 taken 13 times.
|
13 | pat->name = get_identifier(); |
654 | expect_token(tok_identifier, true, pat, LOC); | ||
655 | |||
656 |
4/5✓ Branch 1 taken 12 times.
✓ Branch 4 taken 12 times.
✓ Branch 6 taken 12 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 12 times.
|
12 | end_code_loc(pat, token()); |
657 | 12 | return pat; | |
658 | } | ||
659 | |||
660 | // <expr>(<pattern>..., <identifier>=<pattern>) | ||
661 | Pattern* Parser::parse_match_class(Node* parent, ExprNode* cls, int depth) { | ||
662 | TRACE_START(); | ||
663 | |||
664 | 35 | auto pat = parent->new_object<MatchClass>(); | |
665 | 35 | pat->cls = cls; | |
666 | |||
667 | // TODO: This is the location of '(' not the full pattern | ||
668 |
4/5✓ Branch 1 taken 35 times.
✓ Branch 4 taken 35 times.
✓ Branch 6 taken 35 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 35 times.
|
35 | start_code_loc(pat, token()); |
669 | expect_token(tok_parens, true, pat, LOC); | ||
670 | |||
671 | 35 | bool keyword = false; | |
672 |
1/2✓ Branch 2 taken 99 times.
✗ Branch 3 not taken.
|
99 | while (token().type() != ')') { |
673 | |||
674 | // keyword arguments are starting | ||
675 |
6/6✓ Branch 2 taken 96 times.
✓ Branch 3 taken 3 times.
✓ Branch 6 taken 29 times.
✓ Branch 7 taken 67 times.
✓ Branch 8 taken 29 times.
✓ Branch 9 taken 70 times.
|
99 | if (token().type() == tok_identifier && peek_token().type() == tok_assign) { |
676 | 29 | keyword = true; | |
677 | } | ||
678 | |||
679 | // positional arguments | ||
680 |
2/2✓ Branch 0 taken 70 times.
✓ Branch 1 taken 29 times.
|
99 | if (!keyword) { |
681 |
2/2✓ Branch 1 taken 67 times.
✓ Branch 4 taken 67 times.
|
70 | pat->patterns.push_back(parse_pattern(pat, depth + 1)); |
682 | } | ||
683 | |||
684 | // keywords | ||
685 |
1/2✓ Branch 0 taken 29 times.
✗ Branch 1 not taken.
|
29 | else if (keyword) { |
686 |
3/3✓ Branch 1 taken 29 times.
✓ Branch 4 taken 29 times.
✓ Branch 7 taken 29 times.
|
29 | pat->kwd_attrs.push_back(get_identifier()); |
687 | expect_token(tok_identifier, true, pat, LOC); | ||
688 | expect_token(tok_assign, true, pat, LOC); | ||
689 |
2/2✓ Branch 1 taken 28 times.
✓ Branch 4 taken 28 times.
|
29 | pat->kwd_patterns.push_back(parse_pattern(pat, depth + 1)); |
690 | } | ||
691 | |||
692 |
2/2✓ Branch 2 taken 64 times.
✓ Branch 3 taken 31 times.
|
95 | if (token().type() == tok_comma) { |
693 | 64 | next_token(); | |
694 | } else { | ||
695 |
4/5✓ Branch 1 taken 31 times.
✓ Branch 4 taken 31 times.
✓ Branch 6 taken 31 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 31 times.
|
31 | end_code_loc(pat, token()); |
696 | expect_token(')', true, pat, LOC); | ||
697 | 27 | break; | |
698 | } | ||
699 | } | ||
700 | |||
701 | 27 | return pat; | |
702 | } | ||
703 | |||
704 | // This one does not make much sense | ||
705 | // {'a': Point(x, y)} | ||
706 | // { 1 + 1: 2} | ||
707 | // { <expr>: <pattern> } | ||
708 | Pattern* Parser::parse_match_mapping(Node* parent, int depth) { | ||
709 | TRACE_START(); | ||
710 | |||
711 | 45 | auto pat = parent->new_object<MatchMapping>(); | |
712 |
4/5✓ Branch 1 taken 45 times.
✓ Branch 4 taken 45 times.
✓ Branch 6 taken 45 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 45 times.
|
45 | start_code_loc(pat, token()); |
713 | 45 | next_token(); | |
714 | |||
715 |
2/2✓ Branch 2 taken 33 times.
✓ Branch 3 taken 26 times.
|
59 | while (token().type() != '}') { |
716 | |||
717 |
3/3✓ Branch 1 taken 33 times.
✓ Branch 5 taken 13 times.
✓ Branch 6 taken 20 times.
|
33 | if (token().operator_name() == "**") { |
718 |
1/1✓ Branch 1 taken 13 times.
|
13 | next_token(); |
719 |
3/3✓ Branch 1 taken 13 times.
✓ Branch 5 taken 13 times.
✓ Branch 8 taken 13 times.
|
13 | pat->rest = token().identifier(); |
720 | expect_token(tok_identifier, true, pat, LOC); | ||
721 | 13 | break; | |
722 | } | ||
723 | |||
724 |
1/1✓ Branch 1 taken 17 times.
|
20 | auto key = parse_expression(pat, depth + 1); |
725 | |||
726 | expect_token(':', true, pat, LOC); | ||
727 |
1/1✓ Branch 1 taken 15 times.
|
16 | auto child = parse_pattern(pat, depth + 1); |
728 | |||
729 |
1/1✓ Branch 1 taken 15 times.
|
15 | pat->keys.push_back(key); |
730 |
1/1✓ Branch 1 taken 15 times.
|
15 | pat->patterns.push_back(child); |
731 | |||
732 |
3/3✓ Branch 1 taken 15 times.
✓ Branch 4 taken 14 times.
✓ Branch 5 taken 1 times.
|
15 | if (token().type() == tok_comma) { |
733 |
1/1✓ Branch 1 taken 14 times.
|
14 | next_token(); |
734 | } else { | ||
735 | 1 | break; | |
736 | } | ||
737 | } | ||
738 | |||
739 |
4/5✓ Branch 1 taken 39 times.
✓ Branch 4 taken 39 times.
✓ Branch 6 taken 39 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 39 times.
|
39 | end_code_loc(pat, token()); |
740 | expect_token('}', true, pat, LOC); | ||
741 | 37 | return pat; | |
742 | } | ||
743 | |||
744 | // <pattern> | <pattern> | ... | ||
745 | Pattern* Parser::parse_match_or(Node* parent, Pattern* child, int depth) { | ||
746 | TRACE_START(); | ||
747 | |||
748 | 46 | auto pat = parent->new_object<MatchOr>(); | |
749 | 46 | pat->patterns.push_back(child); | |
750 | |||
751 | // TODO: this is the loc of '|' not the start of the expression | ||
752 |
4/5✓ Branch 1 taken 46 times.
✓ Branch 4 taken 46 times.
✓ Branch 6 taken 46 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 46 times.
|
46 | start_code_loc(pat, token()); |
753 | |||
754 |
1/2✗ Branch 3 not taken.
✓ Branch 4 taken 46 times.
|
46 | if (token().operator_name() != "|") { |
755 | kwerror("Unexpected operator {}", token().operator_name()); | ||
756 | } | ||
757 | |||
758 | 46 | next_token(); | |
759 | |||
760 |
1/2✓ Branch 2 taken 46 times.
✗ Branch 3 not taken.
|
46 | while (token().type() != ':') { |
761 | 46 | child = parse_pattern(pat, depth + 1); | |
762 | 45 | pat->patterns.push_back(child); | |
763 | |||
764 |
2/6✗ Branch 2 not taken.
✓ Branch 3 taken 45 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 45 times.
|
45 | if (token().type() == tok_operator && token().operator_name() == "|") { |
765 | ✗ | next_token(); | |
766 | } else { | ||
767 | // could be ":" or "if" | ||
768 | // expect_token(':', false, pat, LOC); | ||
769 | 45 | break; | |
770 | } | ||
771 | } | ||
772 | |||
773 |
4/5✓ Branch 1 taken 45 times.
✓ Branch 4 taken 45 times.
✓ Branch 6 taken 45 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 45 times.
|
45 | end_code_loc(pat, token()); |
774 | 45 | return pat; | |
775 | } | ||
776 | |||
777 | // <pattern> as <identifier> | ||
778 | Pattern* Parser::parse_match_as(Node* parent, Pattern* primary, int depth) { | ||
779 | TRACE_START(); | ||
780 | |||
781 | 57 | auto pat = parent->new_object<MatchAs>(); | |
782 | 57 | pat->pattern = primary; | |
783 | |||
784 | // TODO: this is the loc of 'as' not the start of the expression | ||
785 |
4/5✓ Branch 1 taken 57 times.
✓ Branch 4 taken 57 times.
✓ Branch 6 taken 57 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 57 times.
|
57 | start_code_loc(pat, token()); |
786 | |||
787 | expect_token(tok_as, true, pat, LOC); | ||
788 |
3/3✓ Branch 1 taken 57 times.
✓ Branch 4 taken 57 times.
✓ Branch 7 taken 57 times.
|
57 | pat->name = get_identifier(); |
789 | |||
790 |
4/5✓ Branch 1 taken 57 times.
✓ Branch 4 taken 57 times.
✓ Branch 6 taken 57 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 57 times.
|
57 | end_code_loc(pat, token()); |
791 | expect_token(tok_identifier, true, pat, LOC); | ||
792 | |||
793 | 56 | return pat; | |
794 | } | ||
795 | |||
796 | Pattern* Parser::parse_pattern_1(Node* parent, int depth) { | ||
797 | |||
798 |
5/5✓ Branch 2 taken 111 times.
✓ Branch 3 taken 45 times.
✓ Branch 4 taken 13 times.
✓ Branch 5 taken 136 times.
✓ Branch 6 taken 347 times.
|
652 | switch (token().type()) { |
799 | 111 | case tok_square: return parse_match_sequence(parent, depth); | |
800 | |||
801 | // TODO: make sure those are correct | ||
802 | 45 | case tok_curly: return parse_match_mapping(parent, depth); | |
803 | |||
804 | 13 | case tok_operator: | |
805 | case tok_star: | ||
806 |
3/6✓ Branch 3 taken 13 times.
✗ Branch 4 not taken.
✓ Branch 8 taken 13 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 13 times.
✗ Branch 11 not taken.
|
13 | if (token().operator_name() == "**" || token().operator_name() == "*") { |
807 | 13 | return parse_match_star(parent, depth); | |
808 | } | ||
809 | |||
810 | // Constants | ||
811 | // The values represented can be simple types such as a number, string or None, | ||
812 | // but also immutable container types (tuples and frozensets) | ||
813 | // if all of their elements are constant. | ||
814 | case tok_int: | ||
815 | case tok_string: | ||
816 | case tok_float: { | ||
817 | 136 | auto pat = parent->new_object<MatchSingleton>(); | |
818 |
2/2✓ Branch 1 taken 136 times.
✓ Branch 4 taken 136 times.
|
136 | pat->value = get_value(pat); |
819 | 136 | next_token(); | |
820 | 136 | return pat; | |
821 | } | ||
822 | |||
823 | // case tok_identifier: return parse_match_class(parent, depth); | ||
824 | // MatchClass is expecting a expression not an identifier | ||
825 | // this is interesting does that mean if I call a function returning a type | ||
826 | // it will match on that type ? | ||
827 | |||
828 | // Value | ||
829 | 347 | default: { | |
830 | // in this context we are storing components inside the pattern | ||
831 | //_context.push_back(ExprContext::Store); | ||
832 | 347 | auto value = parse_expression_primary(parent, depth + 1); | |
833 | //_context.pop_back(); | ||
834 | 327 | Pattern* pat = nullptr; | |
835 | |||
836 | // <expr> if|: | ||
837 |
2/2✓ Branch 2 taken 292 times.
✓ Branch 3 taken 35 times.
|
327 | if (token().type() != '(') { |
838 | 292 | pat = parent->new_object<MatchValue>(); | |
839 | 292 | ((MatchValue*)pat)->value = value; | |
840 | 292 | set_context(value, ExprContext::Store); | |
841 | } else { | ||
842 | 35 | pat = parse_match_class(parent, value, depth + 1); | |
843 | } | ||
844 | 319 | value->move(pat); | |
845 | 319 | return pat; | |
846 | } | ||
847 | } | ||
848 | } | ||
849 | |||
850 | Pattern* Parser::parse_pattern(Node* parent, int depth) { | ||
851 | TRACE_START(); | ||
852 | |||
853 | 652 | auto primary = parse_pattern_1(parent, depth); | |
854 | |||
855 |
3/3✓ Branch 2 taken 46 times.
✓ Branch 3 taken 57 times.
✓ Branch 4 taken 502 times.
|
605 | switch (token().type()) { |
856 | 46 | case tok_operator: | |
857 | case '|': | ||
858 |
1/2✓ Branch 3 taken 46 times.
✗ Branch 4 not taken.
|
46 | if (token().operator_name() == "|") { |
859 | 46 | return parse_match_or(parent, primary, depth); | |
860 | } | ||
861 | |||
862 | 57 | case tok_as: return parse_match_as(parent, primary, depth); | |
863 | } | ||
864 | // could be ":" or "if" | ||
865 | // expect_token(':', false, primary, LOC); | ||
866 | 502 | return primary; | |
867 | } | ||
868 | |||
869 | Token Parser::parse_match_case(Node* parent, Array<MatchCase>& out, int depth) { | ||
870 | TRACE_START(); | ||
871 | |||
872 | 129 | Token last = token(); | |
873 | |||
874 |
2/3✓ Branch 1 taken 325 times.
✓ Branch 4 taken 325 times.
✗ Branch 5 not taken.
|
325 | while (token().type() != tok_desindent) { |
875 |
1/1✓ Branch 1 taken 325 times.
|
325 | MatchCase case_; |
876 | expect_token(tok_case, true, parent, LOC); | ||
877 | // Patern | ||
878 |
1/1✓ Branch 1 taken 285 times.
|
322 | case_.pattern = parse_pattern(parent, depth); |
879 | |||
880 | // Guard | ||
881 |
3/3✓ Branch 1 taken 285 times.
✓ Branch 4 taken 13 times.
✓ Branch 5 taken 272 times.
|
285 | if (token().type() == tok_if) { |
882 |
1/1✓ Branch 1 taken 13 times.
|
13 | next_token(); |
883 |
2/2✓ Branch 1 taken 12 times.
✓ Branch 4 taken 12 times.
|
13 | case_.guard = parse_expression(parent, depth + 1); |
884 | } | ||
885 | |||
886 | expect_token(':', true, parent, LOC); | ||
887 |
4/4✓ Branch 1 taken 271 times.
✓ Branch 4 taken 9 times.
✓ Branch 5 taken 262 times.
✓ Branch 7 taken 9 times.
|
271 | MAYBE_COMMENT(&case_, comment); |
888 | expect_newline(parent, LOC); | ||
889 | expect_token(tok_indent, true, parent, LOC); | ||
890 | |||
891 | // Branch | ||
892 |
1/1✓ Branch 1 taken 244 times.
|
253 | last = parse_body(parent, case_.body, depth + 1); |
893 |
1/1✓ Branch 1 taken 244 times.
|
244 | out.push_back(case_); |
894 | |||
895 | // Stop if next token is not for another branch | ||
896 |
3/3✓ Branch 1 taken 244 times.
✓ Branch 4 taken 48 times.
✓ Branch 5 taken 196 times.
|
244 | if (token().type() != tok_case) { |
897 | expect_tokens({tok_desindent, tok_eof}, false, parent, LOC); | ||
898 | 48 | break; | |
899 | } | ||
900 | 325 | } | |
901 | |||
902 | 48 | return last; | |
903 | 81 | } | |
904 | |||
905 | StmtNode* Parser::parse_match(Node* parent, int depth) { | ||
906 | TRACE_START(); | ||
907 | |||
908 |
1/1✓ Branch 1 taken 141 times.
|
141 | auto stmt = parent->new_object<Match>(); |
909 |
4/5✓ Branch 1 taken 141 times.
✓ Branch 4 taken 141 times.
✓ Branch 6 taken 141 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 141 times.
|
141 | start_code_loc(stmt, token()); |
910 |
1/1✓ Branch 1 taken 141 times.
|
141 | next_token(); |
911 | |||
912 |
1/1✓ Branch 1 taken 138 times.
|
141 | stmt->subject = parse_expression(stmt, depth + 1); |
913 | expect_token(':', true, stmt, LOC); | ||
914 | expect_comment_or_newline(stmt, depth, LOC); | ||
915 | expect_token(tok_indent, true, parent, LOC); | ||
916 | |||
917 |
1/1✓ Branch 1 taken 48 times.
|
129 | auto last = parse_match_case(stmt, stmt->cases, depth); |
918 | |||
919 | expect_tokens({tok_desindent, tok_eof}, true, stmt, LOC); | ||
920 |
3/4✓ Branch 1 taken 48 times.
✓ Branch 3 taken 48 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 48 times.
|
48 | end_code_loc(stmt, last); |
921 | TRACE_END(); | ||
922 | 48 | return stmt; | |
923 | 48 | } | |
924 | |||
925 | void Parser::parse_withitem(Node* parent, Array<WithItem>& out, int depth) { | ||
926 | TRACE_START(); | ||
927 | |||
928 |
1/2✓ Branch 2 taken 96 times.
✗ Branch 3 not taken.
|
96 | while (token().type() != ':') { |
929 |
1/1✓ Branch 1 taken 92 times.
|
96 | ExprNode* expr = parse_expression(parent, depth + 1); |
930 | 92 | ExprNode* var = nullptr; | |
931 | |||
932 |
3/3✓ Branch 1 taken 92 times.
✓ Branch 4 taken 88 times.
✓ Branch 5 taken 4 times.
|
92 | if (token().type() == tok_as) { |
933 |
1/1✓ Branch 1 taken 88 times.
|
88 | next_token(); |
934 |
1/1✓ Branch 1 taken 84 times.
|
88 | var = parse_expression_primary(parent, depth + 1); |
935 | } | ||
936 | |||
937 |
1/1✓ Branch 1 taken 88 times.
|
88 | out.push_back(WithItem{expr, var}); |
938 | |||
939 |
3/3✓ Branch 1 taken 88 times.
✓ Branch 4 taken 44 times.
✓ Branch 5 taken 44 times.
|
88 | if (token().type() == tok_comma) { |
940 |
1/1✓ Branch 1 taken 44 times.
|
44 | next_token(); |
941 | } else { | ||
942 | 44 | break; | |
943 | } | ||
944 | } | ||
945 | 132 | } | |
946 | |||
947 | StmtNode* Parser::parse_with(Node* parent, int depth) { | ||
948 | TRACE_START(); | ||
949 | |||
950 | 52 | With* stmt = nullptr; | |
951 |
2/3✓ Branch 1 taken 52 times.
✓ Branch 3 taken 52 times.
✗ Branch 4 not taken.
|
52 | if (!async()) { |
952 |
1/1✓ Branch 1 taken 52 times.
|
52 | stmt = parent->new_object<With>(); |
953 | } else { | ||
954 | ✗ | stmt = parent->new_object<AsyncWith>(); | |
955 | ✗ | stmt->async = true; | |
956 | } | ||
957 | |||
958 |
4/5✓ Branch 1 taken 52 times.
✓ Branch 4 taken 52 times.
✓ Branch 6 taken 52 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 52 times.
|
52 | start_code_loc(stmt, token()); |
959 |
1/1✓ Branch 1 taken 52 times.
|
52 | next_token(); |
960 | |||
961 |
1/1✓ Branch 1 taken 44 times.
|
52 | parse_withitem(stmt, stmt->items, depth + 1); |
962 | |||
963 | expect_token(':', true, stmt, LOC); | ||
964 | expect_comment_or_newline(stmt, depth, LOC); | ||
965 | expect_token(tok_indent, true, stmt, LOC); | ||
966 | |||
967 |
1/1✓ Branch 1 taken 30 times.
|
32 | auto last = parse_body(stmt, stmt->body, depth + 1); |
968 |
4/5✓ Branch 1 taken 30 times.
✓ Branch 4 taken 30 times.
✓ Branch 6 taken 30 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 30 times.
|
30 | end_code_loc(stmt, token()); |
969 | |||
970 | 30 | return stmt; | |
971 | 30 | } | |
972 | |||
973 | StmtNode* Parser::parse_raise(Node* parent, int depth) { | ||
974 | TRACE_START(); | ||
975 | |||
976 | 16 | auto stmt = parent->new_object<Raise>(); | |
977 |
4/5✓ Branch 1 taken 16 times.
✓ Branch 4 taken 16 times.
✓ Branch 6 taken 16 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 16 times.
|
16 | start_code_loc(stmt, token()); |
978 | 16 | next_token(); | |
979 | |||
980 |
2/2✓ Branch 1 taken 14 times.
✓ Branch 2 taken 2 times.
|
16 | if (!is_tok_statement_ender()) { |
981 |
2/2✓ Branch 1 taken 14 times.
✓ Branch 4 taken 14 times.
|
14 | stmt->exc = parse_expression(stmt, depth + 1); |
982 | |||
983 |
2/2✓ Branch 2 taken 7 times.
✓ Branch 3 taken 7 times.
|
14 | if (token().type() == tok_from) { |
984 | 7 | next_token(); | |
985 |
2/2✓ Branch 1 taken 6 times.
✓ Branch 4 taken 6 times.
|
7 | stmt->cause = parse_expression(stmt, depth + 1); |
986 | } | ||
987 | |||
988 |
4/5✓ Branch 1 taken 13 times.
✓ Branch 4 taken 13 times.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 13 times.
|
13 | end_code_loc(stmt, token()); |
989 | } else { | ||
990 |
4/5✓ Branch 1 taken 2 times.
✓ Branch 4 taken 2 times.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 2 times.
|
2 | end_code_loc(stmt, token()); |
991 | |||
992 |
1/2✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
|
2 | if (token().type() != tok_comment) { |
993 | 2 | next_token(); | |
994 | } | ||
995 | } | ||
996 | |||
997 | 15 | return stmt; | |
998 | } | ||
999 | |||
1000 | Token Parser::parse_except_handler(Try* parent, Array<ExceptHandler>& out, int depth) { | ||
1001 | TRACE_START(); | ||
1002 | |||
1003 |
2/2✓ Branch 2 taken 28 times.
✓ Branch 3 taken 21 times.
|
49 | while (token().type() == tok_except) { |
1004 |
1/1✓ Branch 1 taken 28 times.
|
28 | next_token(); |
1005 |
1/1✓ Branch 1 taken 28 times.
|
28 | ExceptHandler handler; |
1006 | |||
1007 |
2/3✓ Branch 1 taken 28 times.
✓ Branch 4 taken 28 times.
✗ Branch 5 not taken.
|
28 | if (token().type() != ':') { |
1008 |
2/2✓ Branch 1 taken 27 times.
✓ Branch 4 taken 27 times.
|
28 | handler.type = parse_expression(parent, depth + 1); |
1009 | |||
1010 |
3/3✓ Branch 1 taken 27 times.
✓ Branch 4 taken 26 times.
✓ Branch 5 taken 1 times.
|
27 | if (token().type() == tok_as) { |
1011 |
1/1✓ Branch 1 taken 26 times.
|
26 | next_token(); |
1012 |
3/3✓ Branch 1 taken 26 times.
✓ Branch 4 taken 26 times.
✓ Branch 7 taken 26 times.
|
26 | handler.name = get_identifier(); |
1013 | expect_token(tok_identifier, true, parent, LOC); | ||
1014 | } | ||
1015 | } | ||
1016 | |||
1017 | expect_token(':', true, parent, LOC); | ||
1018 |
1/1✓ Branch 1 taken 24 times.
|
24 | add_inline_comment(parent, &handler, depth); |
1019 | expect_newline(parent, LOC); | ||
1020 | expect_token(tok_indent, true, parent, LOC); | ||
1021 | |||
1022 |
1/1✓ Branch 1 taken 21 times.
|
22 | parse_body(parent, handler.body, depth + 1); |
1023 | |||
1024 |
1/1✓ Branch 1 taken 21 times.
|
21 | out.push_back(handler); |
1025 | 28 | }; | |
1026 | |||
1027 | 21 | return token(); | |
1028 | } | ||
1029 | |||
1030 | StmtNode* Parser::parse_try(Node* parent, int depth) { | ||
1031 | TRACE_START(); | ||
1032 | |||
1033 |
1/1✓ Branch 1 taken 35 times.
|
35 | auto stmt = parent->new_object<Try>(); |
1034 |
4/5✓ Branch 1 taken 35 times.
✓ Branch 4 taken 35 times.
✓ Branch 6 taken 35 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 35 times.
|
35 | start_code_loc(stmt, token()); |
1035 |
1/1✓ Branch 1 taken 35 times.
|
35 | next_token(); |
1036 | |||
1037 | expect_token(':', true, stmt, LOC); | ||
1038 | expect_comment_or_newline(stmt, depth, LOC); | ||
1039 | expect_token(tok_indent, true, stmt, LOC); | ||
1040 | |||
1041 |
1/1✓ Branch 1 taken 31 times.
|
32 | auto last = parse_body(stmt, stmt->body, depth + 1); |
1042 | |||
1043 | expect_token(tok_except, false, stmt, LOC); | ||
1044 |
1/1✓ Branch 1 taken 21 times.
|
28 | parse_except_handler(stmt, stmt->handlers, depth + 1); |
1045 | |||
1046 |
3/3✓ Branch 1 taken 21 times.
✓ Branch 4 taken 18 times.
✓ Branch 5 taken 3 times.
|
21 | if (token().type() == tok_else) { |
1047 |
1/1✓ Branch 1 taken 18 times.
|
18 | next_token(); // else |
1048 | expect_token(':', true, stmt, LOC); | ||
1049 | |||
1050 |
4/4✓ Branch 1 taken 17 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 16 times.
✓ Branch 7 taken 1 times.
|
17 | MAYBE_COMMENT(stmt, else_comment); |
1051 | expect_newline(stmt, LOC); | ||
1052 | |||
1053 | expect_token(tok_indent, true, stmt, LOC); | ||
1054 |
1/1✓ Branch 1 taken 14 times.
|
15 | parse_body(stmt, stmt->orelse, depth + 1); |
1055 | } | ||
1056 | |||
1057 |
3/3✓ Branch 1 taken 17 times.
✓ Branch 4 taken 11 times.
✓ Branch 5 taken 6 times.
|
17 | if (token().type() == tok_finally) { |
1058 |
1/1✓ Branch 1 taken 11 times.
|
11 | next_token(); // finally |
1059 | expect_token(':', true, stmt, LOC); | ||
1060 | |||
1061 |
4/4✓ Branch 1 taken 10 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 9 times.
✓ Branch 7 taken 1 times.
|
10 | MAYBE_COMMENT(stmt, finally_comment); |
1062 | expect_newline(stmt, LOC); | ||
1063 | |||
1064 | expect_token(tok_indent, true, stmt, LOC); | ||
1065 |
1/1✓ Branch 1 taken 7 times.
|
8 | parse_body(stmt, stmt->finalbody, depth + 1); |
1066 | } | ||
1067 | |||
1068 |
4/5✓ Branch 1 taken 13 times.
✓ Branch 4 taken 13 times.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 13 times.
|
13 | end_code_loc(stmt, token()); |
1069 | 13 | return stmt; | |
1070 | 31 | } | |
1071 | |||
1072 | StmtNode* Parser::parse_assert(Node* parent, int depth) { | ||
1073 | TRACE_START(); | ||
1074 | |||
1075 | 20 | auto stmt = parent->new_object<Assert>(); | |
1076 |
4/5✓ Branch 1 taken 20 times.
✓ Branch 4 taken 20 times.
✓ Branch 6 taken 20 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 20 times.
|
20 | start_code_loc(stmt, token()); |
1077 | 20 | next_token(); | |
1078 | |||
1079 | // | ||
1080 | 20 | stmt->test = parse_expression(stmt, depth + 1); | |
1081 | // | ||
1082 | |||
1083 |
2/2✓ Branch 2 taken 11 times.
✓ Branch 3 taken 7 times.
|
18 | if (token().type() == tok_comma) { |
1084 | 11 | next_token(); | |
1085 |
2/2✓ Branch 1 taken 10 times.
✓ Branch 4 taken 10 times.
|
11 | stmt->msg = parse_expression(stmt, depth + 1); |
1086 | } | ||
1087 | |||
1088 |
4/5✓ Branch 1 taken 17 times.
✓ Branch 4 taken 17 times.
✓ Branch 6 taken 17 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 17 times.
|
17 | end_code_loc(stmt, token()); |
1089 | 17 | return stmt; | |
1090 | } | ||
1091 | |||
1092 | bool is_dot(Token const& tok) { | ||
1093 |
3/6✗ Branch 1 not taken.
✓ Branch 2 taken 438 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 8 taken 43 times.
✓ Branch 9 taken 395 times.
|
438 | return (tok.type() == tok_operator && tok.operator_name() == ".") || tok.type() == tok_dot; |
1094 | } | ||
1095 | |||
1096 | String Parser::parse_module_path(Node* parent, int& level, int depth) { | ||
1097 | 179 | level = 0; | |
1098 | 179 | Array<String> path; | |
1099 | 179 | bool last_was_dot = false; | |
1100 | |||
1101 | // import <path> as adasd | ||
1102 | // from <path> import cd as xyz | ||
1103 | |||
1104 | while (true) { | ||
1105 | // relative path | ||
1106 |
4/8✓ Branch 1 taken 219 times.
✓ Branch 4 taken 219 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 219 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✓ Branch 12 taken 219 times.
|
219 | if (is_dot(token()) && path.size() <= 0) { |
1107 | ✗ | level += 1; | |
1108 | ✗ | next_token(); | |
1109 | } | ||
1110 | |||
1111 | // module name | ||
1112 |
3/3✓ Branch 1 taken 219 times.
✓ Branch 4 taken 217 times.
✓ Branch 5 taken 2 times.
|
219 | if (token().type() == tok_identifier) { |
1113 |
2/2✓ Branch 1 taken 217 times.
✓ Branch 4 taken 217 times.
|
217 | path.push_back(get_identifier()); |
1114 |
1/1✓ Branch 1 taken 217 times.
|
217 | next_token(); |
1115 | } | ||
1116 | |||
1117 | // separator | ||
1118 |
4/4✓ Branch 1 taken 219 times.
✓ Branch 4 taken 219 times.
✓ Branch 6 taken 43 times.
✓ Branch 7 taken 176 times.
|
219 | if (is_dot(token())) { |
1119 |
1/1✓ Branch 1 taken 43 times.
|
43 | next_token(); |
1120 | |||
1121 | // need an identifier after a `.` | ||
1122 |
3/3✓ Branch 1 taken 43 times.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 40 times.
|
43 | if (token().type() != tok_identifier) { |
1123 |
2/2✓ Branch 2 taken 3 times.
✓ Branch 6 taken 3 times.
|
6 | ParsingError& error = parser_kwerror( // |
1124 | LOC, // | ||
1125 | "SyntaxError", // | ||
1126 | "expect name after ." // | ||
1127 | ); | ||
1128 |
1/1✓ Branch 1 taken 3 times.
|
3 | add_wip_expr(error, parent); |
1129 |
1/1✓ Branch 2 taken 3 times.
|
3 | PARSER_THROW(SyntaxError, error); |
1130 | } | ||
1131 | } | ||
1132 | |||
1133 | // we have reached the en dof the path | ||
1134 |
4/4✓ Branch 1 taken 216 times.
✓ Branch 5 taken 216 times.
✓ Branch 7 taken 175 times.
✓ Branch 8 taken 41 times.
|
216 | if (in(token().type(), tok_import, tok_as, tok_newline, tok_eof)) { |
1135 | 175 | break; | |
1136 | } | ||
1137 | |||
1138 | // | ||
1139 | expect_tokens({tok_dot, tok_identifier}, false, parent, LOC); | ||
1140 | 40 | } | |
1141 | |||
1142 |
2/2✓ Branch 2 taken 175 times.
✓ Branch 5 taken 175 times.
|
350 | return join(".", path); |
1143 | 179 | } | |
1144 | |||
1145 | void Parser::parse_alias(Node* parent, Array<Alias>& out, int depth) { | ||
1146 | TRACE_START(); | ||
1147 | |||
1148 |
2/2✓ Branch 1 taken 135 times.
✓ Branch 2 taken 4 times.
|
139 | while (!is_tok_statement_ender()) { |
1149 |
1/1✓ Branch 1 taken 135 times.
|
135 | Alias alias; |
1150 | |||
1151 | 135 | int level = 0; | |
1152 |
2/2✓ Branch 1 taken 132 times.
✓ Branch 4 taken 132 times.
|
135 | alias.name = parse_module_path(parent, level, depth); |
1153 | |||
1154 |
3/3✓ Branch 1 taken 132 times.
✓ Branch 4 taken 119 times.
✓ Branch 5 taken 13 times.
|
132 | if (token().type() == tok_as) { |
1155 |
1/1✓ Branch 1 taken 119 times.
|
119 | next_token(); |
1156 |
3/3✓ Branch 1 taken 119 times.
✓ Branch 4 taken 119 times.
✓ Branch 7 taken 119 times.
|
119 | alias.asname = get_identifier(); |
1157 | expect_token(tok_identifier, true, parent, LOC); | ||
1158 | } | ||
1159 | |||
1160 |
1/1✓ Branch 1 taken 122 times.
|
122 | out.push_back(alias); |
1161 | |||
1162 |
3/3✓ Branch 1 taken 122 times.
✓ Branch 4 taken 77 times.
✓ Branch 5 taken 45 times.
|
122 | if (token().type() == ',') { |
1163 |
1/1✓ Branch 1 taken 77 times.
|
77 | next_token(); |
1164 |
3/3✓ Branch 1 taken 77 times.
✓ Branch 4 taken 6 times.
✓ Branch 5 taken 71 times.
|
77 | if (token().type() != tok_identifier) { |
1165 |
2/2✓ Branch 2 taken 6 times.
✓ Branch 6 taken 6 times.
|
12 | ParsingError& error = parser_kwerror( // |
1166 | LOC, // | ||
1167 | "SyntaxError", // | ||
1168 | "Expect identifier after ," // | ||
1169 | ); | ||
1170 |
1/1✓ Branch 1 taken 6 times.
|
6 | add_wip_expr(error, parent); |
1171 |
1/1✓ Branch 2 taken 6 times.
|
6 | PARSER_THROW(SyntaxError, error); |
1172 | } | ||
1173 | } else { | ||
1174 | 45 | break; | |
1175 | } | ||
1176 | 135 | } | |
1177 | |||
1178 |
2/2✓ Branch 1 taken 4 times.
✓ Branch 2 taken 45 times.
|
49 | if (out.size() <= 0) { |
1179 |
2/2✓ Branch 2 taken 4 times.
✓ Branch 6 taken 4 times.
|
8 | ParsingError& error = parser_kwerror( // |
1180 | LOC, // | ||
1181 | "SyntaxError", // | ||
1182 | "Expect packages" // | ||
1183 | ); | ||
1184 | 4 | add_wip_expr(error, parent); | |
1185 |
1/1✓ Branch 2 taken 4 times.
|
4 | PARSER_THROW(SyntaxError, error); |
1186 | } | ||
1187 | 45 | } | |
1188 | |||
1189 | StmtNode* Parser::parse_import(Node* parent, int depth) { | ||
1190 | TRACE_START(); | ||
1191 | |||
1192 | 30 | auto stmt = parent->new_object<Import>(); | |
1193 |
4/5✓ Branch 1 taken 30 times.
✓ Branch 4 taken 30 times.
✓ Branch 6 taken 30 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 30 times.
|
30 | start_code_loc(stmt, token()); |
1194 | 30 | next_token(); | |
1195 | |||
1196 | 30 | parse_alias(stmt, stmt->names, depth + 1); | |
1197 | |||
1198 |
4/5✓ Branch 1 taken 21 times.
✓ Branch 4 taken 21 times.
✓ Branch 6 taken 21 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 21 times.
|
21 | end_code_loc(stmt, token()); |
1199 | 21 | add_inline_comment(stmt, depth); | |
1200 | expect_tokens({tok_newline, tok_eof}, true, stmt, LOC); | ||
1201 | 21 | return stmt; | |
1202 | } | ||
1203 | |||
1204 | StmtNode* Parser::parse_import_from(Node* parent, int depth) { | ||
1205 | TRACE_START(); | ||
1206 | |||
1207 |
1/1✓ Branch 1 taken 44 times.
|
44 | auto stmt = parent->new_object<ImportFrom>(); |
1208 |
4/5✓ Branch 1 taken 44 times.
✓ Branch 4 taken 44 times.
✓ Branch 6 taken 44 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 44 times.
|
44 | start_code_loc(stmt, token()); |
1209 |
1/1✓ Branch 1 taken 44 times.
|
44 | next_token(); |
1210 | |||
1211 | 44 | int level = 0; | |
1212 |
3/3✓ Branch 1 taken 43 times.
✓ Branch 4 taken 43 times.
✓ Branch 7 taken 43 times.
|
44 | stmt->module = parse_module_path(parent, level, depth); |
1213 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 43 times.
|
43 | if (level > 0) { |
1214 | ✗ | stmt->level = level; | |
1215 | } | ||
1216 | |||
1217 | expect_token(tok_import, true, stmt, LOC); | ||
1218 |
1/1✓ Branch 1 taken 24 times.
|
38 | parse_alias(stmt, stmt->names, depth + 1); |
1219 | |||
1220 |
4/5✓ Branch 1 taken 24 times.
✓ Branch 4 taken 24 times.
✓ Branch 6 taken 24 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 24 times.
|
24 | end_code_loc(stmt, token()); |
1221 |
1/1✓ Branch 1 taken 24 times.
|
24 | add_inline_comment(stmt, depth); |
1222 | expect_tokens({tok_newline, tok_eof}, true, stmt, LOC); | ||
1223 | 24 | return stmt; | |
1224 | } | ||
1225 | |||
1226 | StmtNode* Parser::parse_global(Node* parent, int depth) { | ||
1227 | TRACE_START(); | ||
1228 | |||
1229 | 6 | auto stmt = parent->new_object<Global>(); | |
1230 |
4/5✓ Branch 1 taken 6 times.
✓ Branch 4 taken 6 times.
✓ Branch 6 taken 6 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 6 times.
|
6 | start_code_loc(stmt, token()); |
1231 | 6 | next_token(); | |
1232 | |||
1233 |
1/2✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
|
6 | while (token().type() != tok_newline) { |
1234 |
3/3✓ Branch 1 taken 6 times.
✓ Branch 4 taken 6 times.
✓ Branch 7 taken 6 times.
|
6 | stmt->names.push_back(get_identifier()); |
1235 | expect_token(tok_identifier, true, parent, LOC); | ||
1236 | |||
1237 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 5 times.
|
5 | if (token().type() == ',') { |
1238 | ✗ | next_token(); | |
1239 | } else { | ||
1240 | 5 | break; | |
1241 | } | ||
1242 | } | ||
1243 | |||
1244 |
4/5✓ Branch 1 taken 5 times.
✓ Branch 4 taken 5 times.
✓ Branch 6 taken 5 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 5 times.
|
5 | end_code_loc(stmt, token()); |
1245 | 5 | return stmt; | |
1246 | } | ||
1247 | |||
1248 | StmtNode* Parser::parse_nonlocal(Node* parent, int depth) { | ||
1249 | TRACE_START(); | ||
1250 | |||
1251 | 6 | auto stmt = parent->new_object<Nonlocal>(); | |
1252 |
4/5✓ Branch 1 taken 6 times.
✓ Branch 4 taken 6 times.
✓ Branch 6 taken 6 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 6 times.
|
6 | start_code_loc(stmt, token()); |
1253 | 6 | next_token(); | |
1254 | |||
1255 |
1/2✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
|
6 | while (token().type() != tok_newline) { |
1256 |
3/3✓ Branch 1 taken 6 times.
✓ Branch 4 taken 6 times.
✓ Branch 7 taken 6 times.
|
6 | stmt->names.push_back(get_identifier()); |
1257 | expect_token(tok_identifier, true, parent, LOC); | ||
1258 | |||
1259 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 5 times.
|
5 | if (token().type() == ',') { |
1260 | ✗ | next_token(); | |
1261 | } else { | ||
1262 | 5 | break; | |
1263 | } | ||
1264 | } | ||
1265 | |||
1266 |
4/5✓ Branch 1 taken 5 times.
✓ Branch 4 taken 5 times.
✓ Branch 6 taken 5 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 5 times.
|
5 | end_code_loc(stmt, token()); |
1267 | 5 | return stmt; | |
1268 | } | ||
1269 | |||
1270 | StmtNode* Parser::parse_return(Node* parent, int depth) { | ||
1271 | TRACE_START(); | ||
1272 | |||
1273 | 286 | auto stmt = parent->new_object<Return>(); | |
1274 |
4/5✓ Branch 1 taken 286 times.
✓ Branch 4 taken 286 times.
✓ Branch 6 taken 286 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 286 times.
|
286 | start_code_loc(stmt, token()); |
1275 | 286 | next_token(); | |
1276 | |||
1277 |
2/2✓ Branch 1 taken 277 times.
✓ Branch 2 taken 9 times.
|
286 | if (!is_tok_statement_ender()) { |
1278 |
2/2✓ Branch 1 taken 268 times.
✓ Branch 4 taken 268 times.
|
277 | stmt->value = parse_expression(stmt, depth + 1, true); |
1279 |
4/5✓ Branch 1 taken 268 times.
✓ Branch 4 taken 268 times.
✓ Branch 6 taken 268 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 268 times.
|
268 | end_code_loc(stmt, token()); |
1280 | } else { | ||
1281 |
4/5✓ Branch 1 taken 9 times.
✓ Branch 4 taken 9 times.
✓ Branch 6 taken 9 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 9 times.
|
9 | end_code_loc(stmt, token()); |
1282 | |||
1283 |
1/2✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
|
9 | if (token().type() != tok_comment) { |
1284 | 9 | next_token(); | |
1285 | } | ||
1286 | } | ||
1287 | |||
1288 | TRACE_END(); | ||
1289 | 277 | return stmt; | |
1290 | } | ||
1291 | |||
1292 | StmtNode* Parser::parse_del(Node* parent, int depth) { | ||
1293 | TRACE_START(); | ||
1294 | |||
1295 | 9 | auto stmt = parent->new_object<Delete>(); | |
1296 |
4/5✓ Branch 1 taken 9 times.
✓ Branch 4 taken 9 times.
✓ Branch 6 taken 9 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 9 times.
|
9 | start_code_loc(stmt, token()); |
1297 | |||
1298 |
2/2✓ Branch 1 taken 16 times.
✓ Branch 2 taken 7 times.
|
23 | while (!is_tok_statement_ender()) { |
1299 |
1/1✓ Branch 1 taken 16 times.
|
16 | next_token(); |
1300 | |||
1301 |
1/1✓ Branch 1 taken 14 times.
|
16 | auto expr = parse_expression(stmt, depth + 1); |
1302 |
1/1✓ Branch 1 taken 14 times.
|
14 | stmt->targets.push_back(expr); |
1303 | |||
1304 |
3/3✓ Branch 1 taken 14 times.
✓ Branch 4 taken 7 times.
✓ Branch 5 taken 7 times.
|
14 | if (token().type() == ',') { |
1305 | 7 | continue; | |
1306 | } | ||
1307 | } | ||
1308 | |||
1309 |
4/5✓ Branch 1 taken 7 times.
✓ Branch 4 taken 7 times.
✓ Branch 6 taken 7 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 7 times.
|
7 | end_code_loc(stmt, token()); |
1310 | 7 | return stmt; | |
1311 | } | ||
1312 | |||
1313 | StmtNode* Parser::parse_pass(Node* parent, int depth) { | ||
1314 | TRACE_START(); | ||
1315 | |||
1316 | 301 | auto stmt = parent->new_object<Pass>(); | |
1317 |
4/5✓ Branch 1 taken 301 times.
✓ Branch 4 taken 301 times.
✓ Branch 6 taken 301 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 301 times.
|
301 | start_code_loc(stmt, token()); |
1318 |
4/5✓ Branch 1 taken 301 times.
✓ Branch 4 taken 301 times.
✓ Branch 6 taken 301 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 301 times.
|
301 | end_code_loc(stmt, token()); |
1319 | 301 | next_token(); | |
1320 | 301 | return stmt; | |
1321 | } | ||
1322 | |||
1323 | StmtNode* Parser::parse_break(Node* parent, int depth) { | ||
1324 | TRACE_START(); | ||
1325 | |||
1326 | #if AVOID_DUPLICATE_CONST | ||
1327 | static Break b; | ||
1328 | return &b; | ||
1329 | #endif | ||
1330 | |||
1331 | 6 | auto stmt = parent->new_object<Break>(); | |
1332 |
4/5✓ Branch 1 taken 6 times.
✓ Branch 4 taken 6 times.
✓ Branch 6 taken 6 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 6 times.
|
6 | start_code_loc(stmt, token()); |
1333 |
4/5✓ Branch 1 taken 6 times.
✓ Branch 4 taken 6 times.
✓ Branch 6 taken 6 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 6 times.
|
6 | end_code_loc(stmt, token()); |
1334 | 6 | next_token(); | |
1335 | 6 | return stmt; | |
1336 | } | ||
1337 | |||
1338 | StmtNode* Parser::parse_continue(Node* parent, int depth) { | ||
1339 | TRACE_START(); | ||
1340 | |||
1341 | #if AVOID_DUPLICATE_CONST | ||
1342 | static Continue c; | ||
1343 | return &c; | ||
1344 | #endif | ||
1345 | |||
1346 | 7 | auto stmt = parent->new_object<Continue>(); | |
1347 |
4/5✓ Branch 1 taken 7 times.
✓ Branch 4 taken 7 times.
✓ Branch 6 taken 7 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 7 times.
|
7 | start_code_loc(stmt, token()); |
1348 |
4/5✓ Branch 1 taken 7 times.
✓ Branch 4 taken 7 times.
✓ Branch 6 taken 7 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 7 times.
|
7 | end_code_loc(stmt, token()); |
1349 | 7 | next_token(); | |
1350 | 7 | return stmt; | |
1351 | } | ||
1352 | |||
1353 | // Statement_2 | ||
1354 | StmtNode* Parser::parse_assign(Node* parent, ExprNode* expr, int depth) { | ||
1355 | TRACE_START(); | ||
1356 | |||
1357 | 342 | auto stmt = parent->new_object<Assign>(); | |
1358 | 342 | set_context(expr, ExprContext::Store); | |
1359 | 342 | stmt->targets.push_back(expr); | |
1360 | |||
1361 | // FIXME: this is the location of '=' not the start of the full expression | ||
1362 |
4/5✓ Branch 1 taken 342 times.
✓ Branch 4 taken 342 times.
✓ Branch 6 taken 342 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 342 times.
|
342 | start_code_loc(stmt, token()); |
1363 | 342 | next_token(); | |
1364 | |||
1365 | 342 | stmt->value = parse_expression(stmt, depth + 1, true); | |
1366 |
4/5✓ Branch 1 taken 254 times.
✓ Branch 4 taken 254 times.
✓ Branch 6 taken 254 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 254 times.
|
254 | end_code_loc(stmt, token()); |
1367 | 254 | return stmt; | |
1368 | } | ||
1369 | |||
1370 | StmtNode* Parser::parse_augassign(Node* parent, ExprNode* expr, int depth) { | ||
1371 | TRACE_START(); | ||
1372 | |||
1373 |
1/1✓ Branch 1 taken 26 times.
|
26 | auto stmt = parent->new_object<AugAssign>(); |
1374 | |||
1375 | // this is a load-store | ||
1376 | // set_context(expr, ExprContext::Load); | ||
1377 | 26 | stmt->target = expr; | |
1378 | |||
1379 | // FIXME: this is the location of the operator not the start of the full expression | ||
1380 |
4/5✓ Branch 1 taken 26 times.
✓ Branch 4 taken 26 times.
✓ Branch 6 taken 26 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 26 times.
|
26 | start_code_loc(stmt, token()); |
1381 | |||
1382 |
2/2✓ Branch 1 taken 26 times.
✓ Branch 4 taken 26 times.
|
26 | auto conf = get_operator_config(token()); |
1383 | 26 | stmt->op = conf.binarykind; | |
1384 |
1/1✓ Branch 1 taken 26 times.
|
26 | next_token(); |
1385 | |||
1386 |
1/1✓ Branch 1 taken 24 times.
|
26 | stmt->value = parse_expression(stmt, depth + 1); |
1387 |
4/5✓ Branch 1 taken 24 times.
✓ Branch 4 taken 24 times.
✓ Branch 6 taken 24 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 24 times.
|
24 | end_code_loc(stmt, token()); |
1388 | 24 | return stmt; | |
1389 | } | ||
1390 | |||
1391 | StmtNode* Parser::parse_annassign(Node* parent, ExprNode* expr, int depth) { | ||
1392 | TRACE_START(); | ||
1393 | |||
1394 | 115 | auto stmt = parent->new_object<AnnAssign>(); | |
1395 | 115 | set_context(expr, ExprContext::Store); | |
1396 | 115 | stmt->target = expr; | |
1397 | |||
1398 | // FIXME: this is the location of :' not the start of the full expression | ||
1399 |
4/5✓ Branch 1 taken 115 times.
✓ Branch 4 taken 115 times.
✓ Branch 6 taken 115 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 115 times.
|
115 | start_code_loc(stmt, token()); |
1400 | 115 | next_token(); | |
1401 | |||
1402 | 115 | stmt->annotation = parse_expression(stmt, depth + 1); | |
1403 | |||
1404 |
2/2✓ Branch 2 taken 103 times.
✓ Branch 3 taken 6 times.
|
109 | if (token().type() == tok_assign) { |
1405 | expect_token(tok_assign, true, stmt, LOC); | ||
1406 |
2/2✓ Branch 1 taken 96 times.
✓ Branch 4 taken 96 times.
|
103 | stmt->value = parse_expression(stmt, depth + 1); |
1407 | } | ||
1408 | |||
1409 |
4/5✓ Branch 1 taken 102 times.
✓ Branch 4 taken 102 times.
✓ Branch 6 taken 102 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 102 times.
|
102 | end_code_loc(stmt, token()); |
1410 | 102 | return stmt; | |
1411 | } | ||
1412 | |||
1413 | // parse_expression_1 | ||
1414 | ExprNode* Parser::parse_name(Node* parent, int depth) { | ||
1415 | TRACE_START(); | ||
1416 | |||
1417 | 3580 | auto expr = parent->new_object<Name>(); | |
1418 |
4/5✓ Branch 1 taken 3580 times.
✓ Branch 4 taken 3580 times.
✓ Branch 6 taken 3580 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 3580 times.
|
3580 | start_code_loc(expr, token()); |
1419 | |||
1420 |
2/2✓ Branch 1 taken 3580 times.
✓ Branch 4 taken 3580 times.
|
3580 | expr->id = get_identifier(); |
1421 | 3580 | expr->ctx = context(); | |
1422 | |||
1423 |
4/5✓ Branch 1 taken 3580 times.
✓ Branch 4 taken 3580 times.
✓ Branch 6 taken 3580 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 3580 times.
|
3580 | end_code_loc(expr, token()); |
1424 | expect_token(tok_identifier, true, expr, LOC); | ||
1425 | 3580 | return expr; | |
1426 | } | ||
1427 | |||
1428 | #define LY_UINT64_MAX sizeof("18446744073709551615") / sizeof(char) | ||
1429 | #define LY_UINT32_MAX sizeof("4294967295") / sizeof(char) | ||
1430 | #define LY_UINT16_MAX sizeof("65535") / sizeof(char) | ||
1431 | #define LY_UINT8_MAX sizeof("255") / sizeof(char) | ||
1432 | |||
1433 | // +1 char for the minus | ||
1434 | #define LY_INT64_MAX sizeof("9223372036854775807") / sizeof(char) | ||
1435 | #define LY_INT32_MAX sizeof("2147483647") / sizeof(char) | ||
1436 | #define LY_INT16_MAX sizeof("32767") / sizeof(char) | ||
1437 | #define LY_INT8_MAX sizeof("255") / sizeof(char) | ||
1438 | |||
1439 | bool Parser::is_valid_value() { | ||
1440 | 780 | String const& value = token().identifier(); | |
1441 |
2/4✓ Branch 1 taken 780 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 780 times.
|
780 | int has_sign = value[0] == '-' || value[0] == '+'; |
1442 | |||
1443 |
4/5✓ Branch 2 taken 74 times.
✓ Branch 3 taken 541 times.
✓ Branch 4 taken 108 times.
✓ Branch 5 taken 57 times.
✗ Branch 6 not taken.
|
780 | switch (token().type()) { |
1444 | 74 | case tok_string: { | |
1445 | 74 | return true; | |
1446 | } | ||
1447 | 541 | case tok_int: { | |
1448 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 541 times.
|
541 | if (value.size() > 18 + has_sign) { |
1449 | ✗ | return false; | |
1450 | } | ||
1451 | 541 | return true; | |
1452 | } | ||
1453 | 108 | case tok_float: { | |
1454 | // Max numbers of digits | ||
1455 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 108 times.
|
108 | if (value.size() > 16 + has_sign) { |
1456 | ✗ | return false; | |
1457 | } | ||
1458 | 108 | return true; | |
1459 | } | ||
1460 | 57 | case tok_none: | |
1461 | case tok_true: | ||
1462 | 57 | case tok_false: return true; | |
1463 | } | ||
1464 | |||
1465 | ✗ | return false; | |
1466 | } | ||
1467 | |||
1468 | ConstantValue Parser::get_value(Node* parent) { | ||
1469 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 780 times.
|
780 | if (!is_valid_value()) { |
1470 | ✗ | ParsingError& error = parser_kwerror( // | |
1471 | LOC, // | ||
1472 | "SyntaxError", // | ||
1473 | "Value is out of range" // | ||
1474 | ); | ||
1475 | ✗ | add_wip_expr(error, parent); | |
1476 | ✗ | PARSER_THROW(SyntaxError, error); | |
1477 | } | ||
1478 | |||
1479 |
6/7✓ Branch 2 taken 74 times.
✓ Branch 3 taken 541 times.
✓ Branch 4 taken 108 times.
✓ Branch 5 taken 6 times.
✓ Branch 6 taken 41 times.
✓ Branch 7 taken 10 times.
✗ Branch 8 not taken.
|
780 | switch (token().type()) { |
1480 | |||
1481 | 74 | case tok_string: { | |
1482 |
3/3✓ Branch 1 taken 74 times.
✓ Branch 5 taken 74 times.
✓ Branch 8 taken 74 times.
|
74 | return ConstantValue(token().identifier()); |
1483 | } | ||
1484 | 541 | case tok_int: { | |
1485 | // FIXME handle different sizes | ||
1486 | 541 | return ConstantValue(int32(token().as_integer())); | |
1487 | } | ||
1488 | 108 | case tok_float: { | |
1489 | 108 | return ConstantValue(token().as_float()); | |
1490 | } | ||
1491 | 6 | case tok_none: return ConstantValue(ConstantValue::none_t()); | |
1492 | |||
1493 | 41 | case tok_true: return ConstantValue(true); | |
1494 | |||
1495 | 10 | case tok_false: return ConstantValue(false); | |
1496 | } | ||
1497 | |||
1498 | ✗ | return ConstantValue(); | |
1499 | } | ||
1500 | |||
1501 | ExprNode* Parser::parse_constant(Node* parent, int depth) { | ||
1502 | TRACE_START(); | ||
1503 | |||
1504 | #if AVOID_DUPLICATE_CONST | ||
1505 | // Shortcut | ||
1506 | static Constant none = Constant(ConstantValue::none_t()); | ||
1507 | static Constant truev = Constant(true); | ||
1508 | static Constant falsev = Constant(false); | ||
1509 | |||
1510 | switch (token().type()) { | ||
1511 | case tok_none: return none; | ||
1512 | |||
1513 | case tok_true: return truev; | ||
1514 | |||
1515 | case tok_false: return falsev; | ||
1516 | } | ||
1517 | // | ||
1518 | #endif | ||
1519 | 644 | auto expr = parent->new_object<Constant>(); | |
1520 |
4/5✓ Branch 1 taken 644 times.
✓ Branch 4 taken 644 times.
✓ Branch 6 taken 644 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 644 times.
|
644 | start_code_loc(expr, token()); |
1521 | |||
1522 |
2/2✓ Branch 1 taken 644 times.
✓ Branch 4 taken 644 times.
|
644 | expr->value = get_value(expr); |
1523 | |||
1524 |
4/5✓ Branch 1 taken 644 times.
✓ Branch 4 taken 644 times.
✓ Branch 6 taken 644 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 644 times.
|
644 | end_code_loc(expr, token()); |
1525 | 644 | next_token(); | |
1526 | 644 | return expr; | |
1527 | } | ||
1528 | |||
1529 | ExprNode* Parser::parse_await(Node* parent, int depth) { | ||
1530 | TRACE_START(); | ||
1531 | |||
1532 | 7 | auto expr = parent->new_object<Await>(); | |
1533 |
4/5✓ Branch 1 taken 7 times.
✓ Branch 4 taken 7 times.
✓ Branch 6 taken 7 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 7 times.
|
7 | start_code_loc(expr, token()); |
1534 | 7 | next_token(); | |
1535 | |||
1536 | 7 | expr->value = parse_expression(expr, depth + 1); | |
1537 |
4/5✓ Branch 1 taken 6 times.
✓ Branch 4 taken 6 times.
✓ Branch 6 taken 6 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 6 times.
|
6 | end_code_loc(expr, token()); |
1538 | 6 | return expr; | |
1539 | } | ||
1540 | |||
1541 | ExprNode* Parser::parse_yield(Node* parent, int depth) { | ||
1542 | TRACE_START(); | ||
1543 | |||
1544 |
2/2✓ Branch 2 taken 7 times.
✓ Branch 3 taken 23 times.
|
30 | if (peek_token().type() == tok_from) { |
1545 | 7 | return parse_yield_from(parent, depth); | |
1546 | } | ||
1547 | |||
1548 | 23 | auto expr = parent->new_object<Yield>(); | |
1549 |
4/5✓ Branch 1 taken 23 times.
✓ Branch 4 taken 23 times.
✓ Branch 6 taken 23 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 23 times.
|
23 | start_code_loc(expr, token()); |
1550 | 23 | next_token(); | |
1551 | |||
1552 |
2/2✓ Branch 1 taken 14 times.
✓ Branch 2 taken 9 times.
|
23 | if (!is_tok_statement_ender()) { |
1553 |
2/2✓ Branch 1 taken 13 times.
✓ Branch 4 taken 13 times.
|
14 | expr->value = parse_expression(expr, depth + 1, true); |
1554 |
4/5✓ Branch 1 taken 13 times.
✓ Branch 4 taken 13 times.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 13 times.
|
13 | end_code_loc(expr, token()); |
1555 | } else { | ||
1556 |
4/5✓ Branch 1 taken 9 times.
✓ Branch 4 taken 9 times.
✓ Branch 6 taken 9 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 9 times.
|
9 | end_code_loc(expr, token()); |
1557 | |||
1558 |
2/2✓ Branch 2 taken 8 times.
✓ Branch 3 taken 1 times.
|
9 | if (token().type() != tok_comment) { |
1559 | 8 | next_token(); | |
1560 | } | ||
1561 | } | ||
1562 | |||
1563 | 22 | return expr; | |
1564 | } | ||
1565 | |||
1566 | ExprNode* Parser::parse_yield_from(Node* parent, int depth) { | ||
1567 | TRACE_START(); | ||
1568 | |||
1569 | 7 | auto expr = parent->new_object<YieldFrom>(); | |
1570 |
4/5✓ Branch 1 taken 7 times.
✓ Branch 4 taken 7 times.
✓ Branch 6 taken 7 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 7 times.
|
7 | start_code_loc(expr, token()); |
1571 | 7 | next_token(); // eat yield | |
1572 | |||
1573 | expect_token(tok_from, true, expr, LOC); | ||
1574 | 7 | expr->value = parse_expression(expr, depth + 1); | |
1575 |
4/5✓ Branch 1 taken 6 times.
✓ Branch 4 taken 6 times.
✓ Branch 6 taken 6 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 6 times.
|
6 | end_code_loc(expr, token()); |
1576 | 6 | return expr; | |
1577 | } | ||
1578 | |||
1579 | bool is_star(Token const& tok) { return tok.type() == tok_operator && tok.operator_name() == "*"; } | ||
1580 | |||
1581 | bool is_starstar(Token const& tok) { | ||
1582 |
3/4✓ Branch 1 taken 17 times.
✓ Branch 2 taken 288 times.
✓ Branch 5 taken 17 times.
✗ Branch 6 not taken.
|
305 | return tok.type() == tok_operator && tok.operator_name() == "**"; |
1583 | } | ||
1584 | |||
1585 | Arguments Parser::parse_arguments(Node* parent, char kind, int depth) { | ||
1586 | TRACE_START(); | ||
1587 | |||
1588 | 219 | Arguments args; | |
1589 | // | ||
1590 | |||
1591 | 219 | bool keywords = false; | |
1592 | |||
1593 |
3/3✓ Branch 1 taken 494 times.
✓ Branch 4 taken 305 times.
✓ Branch 5 taken 189 times.
|
494 | while (token().type() != kind) { |
1594 | 305 | ExprNode* value = nullptr; | |
1595 | |||
1596 |
1/1✓ Branch 1 taken 305 times.
|
305 | Arg arg; |
1597 | |||
1598 | 305 | bool vararg = false; | |
1599 | 305 | bool kwarg = false; | |
1600 | |||
1601 |
3/3✓ Branch 1 taken 305 times.
✓ Branch 4 taken 139 times.
✓ Branch 5 taken 166 times.
|
305 | if (token().type() == tok_comma) { |
1602 |
1/1✓ Branch 1 taken 139 times.
|
139 | next_token(); |
1603 | } | ||
1604 | |||
1605 |
4/4✓ Branch 1 taken 305 times.
✓ Branch 4 taken 305 times.
✓ Branch 6 taken 24 times.
✓ Branch 7 taken 281 times.
|
305 | if (is_star(token())) { |
1606 |
1/1✓ Branch 1 taken 24 times.
|
24 | next_token(); |
1607 | 24 | vararg = true; | |
1608 | } | ||
1609 | |||
1610 |
4/4✓ Branch 1 taken 305 times.
✓ Branch 4 taken 305 times.
✓ Branch 6 taken 17 times.
✓ Branch 7 taken 288 times.
|
305 | if (is_starstar(token())) { |
1611 |
1/1✓ Branch 1 taken 17 times.
|
17 | next_token(); |
1612 | 17 | kwarg = true; | |
1613 | } | ||
1614 | |||
1615 |
3/3✓ Branch 1 taken 305 times.
✓ Branch 4 taken 305 times.
✓ Branch 7 taken 305 times.
|
305 | start_code_loc(&arg, token()); |
1616 |
2/2✓ Branch 1 taken 305 times.
✓ Branch 4 taken 305 times.
|
305 | arg.arg = get_identifier(); |
1617 | expect_token(tok_identifier, true, parent, LOC); | ||
1618 | |||
1619 |
7/7✓ Branch 1 taken 280 times.
✓ Branch 4 taken 126 times.
✓ Branch 5 taken 154 times.
✓ Branch 6 taken 119 times.
✓ Branch 7 taken 7 times.
✓ Branch 8 taken 119 times.
✓ Branch 9 taken 161 times.
|
280 | if (token().type() == ':' && kind != ':') { |
1620 |
1/1✓ Branch 1 taken 119 times.
|
119 | next_token(); |
1621 |
2/2✓ Branch 1 taken 117 times.
✓ Branch 4 taken 117 times.
|
119 | arg.annotation = parse_expression(parent, depth + 1); |
1622 | } | ||
1623 | |||
1624 |
3/3✓ Branch 1 taken 278 times.
✓ Branch 4 taken 62 times.
✓ Branch 5 taken 216 times.
|
278 | if (token().type() == tok_assign) { |
1625 |
1/1✓ Branch 1 taken 62 times.
|
62 | next_token(); |
1626 |
1/1✓ Branch 1 taken 59 times.
|
62 | value = parse_expression(parent, depth + 1); |
1627 | } | ||
1628 | |||
1629 |
2/2✓ Branch 0 taken 23 times.
✓ Branch 1 taken 252 times.
|
275 | if (vararg) { |
1630 |
1/1✓ Branch 1 taken 23 times.
|
23 | args.vararg = arg; |
1631 | // only kwargs from that point onward | ||
1632 | 23 | keywords = true; | |
1633 |
2/2✓ Branch 0 taken 16 times.
✓ Branch 1 taken 236 times.
|
252 | } else if (kwarg) { |
1634 |
1/1✓ Branch 1 taken 16 times.
|
16 | args.kwarg = arg; |
1635 |
2/2✓ Branch 0 taken 216 times.
✓ Branch 1 taken 20 times.
|
236 | } else if (!keywords) { |
1636 |
1/1✓ Branch 1 taken 216 times.
|
216 | args.args.push_back(arg); |
1637 |
2/2✓ Branch 0 taken 40 times.
✓ Branch 1 taken 176 times.
|
216 | if (value) { |
1638 |
1/1✓ Branch 1 taken 40 times.
|
40 | args.defaults.push_back(value); |
1639 | } | ||
1640 |
3/3✓ Branch 1 taken 216 times.
✓ Branch 4 taken 216 times.
✓ Branch 7 taken 216 times.
|
216 | end_code_loc(&arg, token()); |
1641 | } else { | ||
1642 |
1/1✓ Branch 1 taken 20 times.
|
20 | args.kwonlyargs.push_back(arg); |
1643 | // NB: value can be null here | ||
1644 |
1/1✓ Branch 1 taken 20 times.
|
20 | args.kw_defaults.push_back(value); |
1645 | } | ||
1646 | 305 | } | |
1647 | |||
1648 | // | ||
1649 | expect_token(kind, true, parent, LOC); | ||
1650 | 189 | return args; | |
1651 | 30 | } | |
1652 | |||
1653 | ExprNode* Parser::parse_lambda(Node* parent, int depth) { | ||
1654 | TRACE_START(); | ||
1655 | |||
1656 | 9 | auto expr = parent->new_object<Lambda>(); | |
1657 |
4/5✓ Branch 1 taken 9 times.
✓ Branch 4 taken 9 times.
✓ Branch 6 taken 9 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 9 times.
|
9 | start_code_loc(expr, token()); |
1658 | 9 | next_token(); | |
1659 | |||
1660 |
2/2✓ Branch 1 taken 7 times.
✓ Branch 4 taken 7 times.
|
9 | expr->args = parse_arguments(expr, ':', depth + 1); |
1661 | 7 | expr->body = parse_expression(expr, depth + 1); | |
1662 |
4/5✓ Branch 1 taken 6 times.
✓ Branch 4 taken 6 times.
✓ Branch 6 taken 6 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 6 times.
|
6 | end_code_loc(expr, token()); |
1663 | 6 | return expr; | |
1664 | } | ||
1665 | |||
1666 | ExprNode* Parser::parse_starred(Node* parent, int depth) { | ||
1667 | TRACE_START(); | ||
1668 | |||
1669 | 8 | auto expr = parent->new_object<Starred>(); | |
1670 | 8 | next_token(); | |
1671 | |||
1672 | 8 | expr->value = parse_expression(expr, depth + 1); | |
1673 | 7 | return expr; | |
1674 | } | ||
1675 | |||
1676 | void Parser::parse_comprehension(Node* parent, Array<Comprehension>& out, char kind, int depth) { | ||
1677 | TRACE_START(); | ||
1678 | |||
1679 |
1/1✓ Branch 1 taken 56 times.
|
56 | PopGuard _(parsing_context, ParsingContext::Comprehension); |
1680 | |||
1681 |
3/3✓ Branch 1 taken 92 times.
✓ Branch 4 taken 68 times.
✓ Branch 5 taken 24 times.
|
92 | while (token().type() != kind) { |
1682 | expect_token(tok_for, true, parent, LOC); | ||
1683 | 56 | Comprehension cmp; | |
1684 | |||
1685 |
1/1✓ Branch 1 taken 52 times.
|
56 | cmp.target = parse_star_targets(parent, depth + 1); |
1686 |
1/1✓ Branch 1 taken 52 times.
|
52 | set_context(cmp.target, ExprContext::Store); |
1687 | |||
1688 | expect_token(tok_in, true, parent, LOC); | ||
1689 |
1/1✓ Branch 1 taken 44 times.
|
48 | cmp.iter = parse_expression(parent, depth + 1); |
1690 | |||
1691 |
3/3✓ Branch 1 taken 76 times.
✓ Branch 4 taken 40 times.
✓ Branch 5 taken 36 times.
|
76 | while (token().type() == tok_if) { |
1692 |
1/1✓ Branch 1 taken 40 times.
|
40 | next_token(); |
1693 |
2/2✓ Branch 1 taken 32 times.
✓ Branch 4 taken 32 times.
|
40 | cmp.ifs.push_back(parse_expression(parent, depth + 1)); |
1694 | } | ||
1695 | |||
1696 |
1/1✓ Branch 1 taken 36 times.
|
36 | cmp.is_async = async(); |
1697 |
1/1✓ Branch 1 taken 36 times.
|
36 | out.push_back(cmp); |
1698 | 56 | } | |
1699 | 56 | } | |
1700 | |||
1701 | template <typename Comp> | ||
1702 | ExprNode* parse_comprehension(Parser* parser, Node* parent, ExprNode* child, char kind, int depth) { | ||
1703 | 84 | auto expr = parent->new_object<Comp>(); | |
1704 | |||
1705 | 84 | expr->elt = child; | |
1706 | 84 | parser->parse_comprehension(expr, expr->generators, kind, depth); | |
1707 |
4/5✓ Branch 1 taken 18 times.
✓ Branch 4 taken 18 times.
✓ Branch 6 taken 18 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 18 times.
|
36 | parser->end_code_loc(expr, parser->token()); |
1708 | |||
1709 |
2/2✓ Branch 1 taken 18 times.
✓ Branch 4 taken 18 times.
|
54 | parser->expect_token(kind, true, parent, LOC); |
1710 | 36 | return expr; | |
1711 | } | ||
1712 | |||
1713 | ExprNode* parse_dictcomprehension( | ||
1714 | Parser* parser, Node* parent, ExprNode* key, ExprNode* value, char kind, int depth) { | ||
1715 | 14 | auto expr = parent->new_object<DictComp>(); | |
1716 | |||
1717 | 14 | expr->key = key; | |
1718 | 14 | expr->value = value; | |
1719 | 14 | parser->parse_comprehension(expr, expr->generators, kind, depth); | |
1720 |
4/5✓ Branch 1 taken 6 times.
✓ Branch 4 taken 6 times.
✓ Branch 6 taken 6 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 6 times.
|
6 | parser->end_code_loc(expr, parser->token()); |
1721 | |||
1722 | parser->expect_token(kind, true, parent, LOC); | ||
1723 | 6 | return expr; | |
1724 | } | ||
1725 | |||
1726 | template <typename Literal> | ||
1727 | ExprNode* parse_literal(Parser* parser, Node* parent, ExprNode* child, char kind, int depth) { | ||
1728 |
6/7✓ Branch 3 taken 169 times.
✓ Branch 7 taken 169 times.
✓ Branch 11 taken 169 times.
✓ Branch 14 taken 169 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 169 times.
✓ Branch 20 taken 169 times.
|
845 | TRACE_START2(parser->token()); |
1729 | |||
1730 | // This is a tuple | ||
1731 | 338 | auto expr = parent->new_object<Literal>(); | |
1732 | |||
1733 |
1/2✓ Branch 0 taken 169 times.
✗ Branch 1 not taken.
|
338 | if (child) { |
1734 | 338 | expr->elts.push_back(child); | |
1735 | } | ||
1736 | // {a, b, c} | ||
1737 | // [a, b, c] | ||
1738 | // (a, b, c) | ||
1739 | 104 | while (true) { | |
1740 |
2/2✓ Branch 1 taken 193 times.
✓ Branch 4 taken 193 times.
|
442 | expr->elts.push_back(parser->parse_expression(parent, depth + 1)); |
1741 | |||
1742 |
2/2✓ Branch 2 taken 52 times.
✓ Branch 3 taken 141 times.
|
386 | if (parser->token().type() == ',') { |
1743 | 104 | parser->next_token(); | |
1744 | } else { | ||
1745 |
2/2✓ Branch 0 taken 76 times.
✓ Branch 1 taken 65 times.
|
282 | if (kind) { |
1746 |
2/2✓ Branch 1 taken 76 times.
✓ Branch 4 taken 65 times.
|
228 | parser->expect_token(kind, true, expr, LOC); |
1747 | } | ||
1748 | 260 | break; | |
1749 | } | ||
1750 | } | ||
1751 | |||
1752 |
4/5✓ Branch 1 taken 130 times.
✓ Branch 4 taken 130 times.
✓ Branch 6 taken 130 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 130 times.
|
260 | parser->end_code_loc(expr, parser->token()); |
1753 |
6/7✓ Branch 1 taken 130 times.
✓ Branch 5 taken 130 times.
✓ Branch 9 taken 130 times.
✓ Branch 12 taken 130 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 130 times.
✓ Branch 18 taken 130 times.
|
650 | TRACE_END2(parser->token()); |
1754 | 260 | return expr; | |
1755 | } | ||
1756 | |||
1757 | ExprNode* parse_dictliteral( | ||
1758 | Parser* parser, Node* parent, ExprNode* key, ExprNode* value, char kind, int depth) { | ||
1759 | // This is a tuple | ||
1760 | 37 | auto expr = parent->new_object<DictExpr>(); | |
1761 | 37 | expr->keys.push_back(key); | |
1762 | 37 | expr->values.push_back(value); | |
1763 | |||
1764 | // {a: b, c: d} | ||
1765 |
1/2✓ Branch 2 taken 37 times.
✗ Branch 3 not taken.
|
37 | while (parser->token().type() != kind) { |
1766 |
2/2✓ Branch 1 taken 33 times.
✓ Branch 4 taken 33 times.
|
37 | expr->keys.push_back(parser->parse_expression(parent, depth + 1)); |
1767 | parser->expect_token(':', true, expr, LOC); | ||
1768 | |||
1769 |
2/2✓ Branch 1 taken 25 times.
✓ Branch 4 taken 25 times.
|
29 | expr->values.push_back(parser->parse_expression(parent, depth + 1)); |
1770 | |||
1771 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 25 times.
|
25 | if (parser->token().type() == ',') { |
1772 | ✗ | parser->next_token(); | |
1773 | } else { | ||
1774 | parser->expect_token(kind, true, expr, LOC); | ||
1775 | 21 | break; | |
1776 | } | ||
1777 | } | ||
1778 | |||
1779 |
4/5✓ Branch 1 taken 21 times.
✓ Branch 4 taken 21 times.
✓ Branch 6 taken 21 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 21 times.
|
21 | parser->end_code_loc(expr, parser->token()); |
1780 | 21 | return expr; | |
1781 | } | ||
1782 | |||
1783 | template <typename Comp, typename Literal> | ||
1784 | ExprNode* | ||
1785 | parse_comprehension_or_literal(Parser* parser, Node* parent, int tok, char kind, int depth) { | ||
1786 | // Save the start token to set the code loc when we know if this is a tuple or a generator | ||
1787 |
2/2✓ Branch 1 taken 233 times.
✓ Branch 4 taken 233 times.
|
466 | auto start_tok = parser->token(); |
1788 |
3/3✓ Branch 1 taken 233 times.
✓ Branch 4 taken 233 times.
✓ Branch 7 taken 233 times.
|
1165 | SHOW_TOK(start_tok); |
1789 |
2/2✓ Branch 1 taken 233 times.
✓ Branch 4 taken 233 times.
|
699 | parser->expect_token(tok, true, nullptr, LOC); // eat ( [ { |
1790 | |||
1791 | // Warning: the parent is wrong but we need to parse the expression right now | ||
1792 |
1/1✓ Branch 1 taken 214 times.
|
466 | auto child = parser->parse_expression(parent, depth + 1); |
1793 | 428 | ExprNode* value = nullptr; | |
1794 | 428 | bool dictionary = false; | |
1795 | |||
1796 | // Dictionary | ||
1797 |
3/3✓ Branch 1 taken 214 times.
✓ Branch 4 taken 61 times.
✓ Branch 5 taken 153 times.
|
428 | if (parser->token().type() == ':') { |
1798 |
1/1✓ Branch 1 taken 61 times.
|
122 | parser->next_token(); |
1799 |
1/1✓ Branch 1 taken 56 times.
|
122 | value = parser->parse_expression(parent, depth + 1); |
1800 | 112 | dictionary = true; | |
1801 | } | ||
1802 | // ---- | ||
1803 | |||
1804 | // | ||
1805 | 418 | ExprNode* expr = nullptr; | |
1806 |
3/3✓ Branch 1 taken 209 times.
✓ Branch 4 taken 56 times.
✓ Branch 5 taken 153 times.
|
418 | if (parser->token().type() == tok_for) { |
1807 | // This is generator comprehension | ||
1808 |
2/2✓ Branch 0 taken 14 times.
✓ Branch 1 taken 42 times.
|
112 | if (dictionary) { |
1809 |
1/1✓ Branch 1 taken 6 times.
|
28 | expr = parse_dictcomprehension(parser, parent, child, value, kind, depth); |
1810 | } else { | ||
1811 |
1/1✓ Branch 1 taken 18 times.
|
84 | expr = parse_comprehension<Comp>(parser, parent, child, kind, depth); |
1812 |
3/3✓ Branch 1 taken 18 times.
✓ Branch 4 taken 18 times.
✓ Branch 7 taken 18 times.
|
90 | kwerror("Done {}", str(expr)); |
1813 | } | ||
1814 |
3/3✓ Branch 1 taken 153 times.
✓ Branch 4 taken 124 times.
✓ Branch 5 taken 29 times.
|
306 | } else if (parser->token().type() == ',') { |
1815 |
1/1✓ Branch 1 taken 124 times.
|
248 | parser->next_token(); |
1816 | |||
1817 |
2/2✓ Branch 0 taken 37 times.
✓ Branch 1 taken 87 times.
|
248 | if (dictionary) { |
1818 |
1/1✓ Branch 1 taken 21 times.
|
74 | expr = parse_dictliteral(parser, parent, child, value, kind, depth); |
1819 | } else { | ||
1820 |
1/1✓ Branch 1 taken 65 times.
|
174 | expr = parse_literal<Literal>(parser, parent, child, kind, depth); |
1821 | } | ||
1822 | } else { | ||
1823 | // This is not a literal nor a list-comprehension | ||
1824 | // (2 + 1) | ||
1825 |
3/4✓ Branch 0 taken 9 times.
✓ Branch 1 taken 20 times.
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
|
58 | if (kind == ')' && !dictionary) { |
1826 |
1/1✓ Branch 1 taken 9 times.
|
18 | auto p = parser->parse_expression_1(parent, child, 0, depth); |
1827 |
2/2✓ Branch 1 taken 9 times.
✓ Branch 4 taken 6 times.
|
27 | parser->expect_token(')', true, parent, LOC); |
1828 | 12 | return p; | |
1829 | } | ||
1830 | |||
1831 |
2/2✓ Branch 1 taken 20 times.
✓ Branch 4 taken 20 times.
|
60 | kwerror("Unhandled list-comprehension case"); |
1832 | } | ||
1833 | |||
1834 |
2/2✓ Branch 0 taken 20 times.
✓ Branch 1 taken 110 times.
|
260 | if (expr == nullptr) { |
1835 |
2/2✓ Branch 2 taken 20 times.
✓ Branch 6 taken 20 times.
|
80 | ParsingError& error = parser->parser_kwerror( // |
1836 |
2/2✓ Branch 1 taken 20 times.
✓ Branch 4 taken 20 times.
|
60 | LOC, // |
1837 | "SyntaxError", // | ||
1838 | "Comprehension is null" // | ||
1839 | ); | ||
1840 |
1/1✓ Branch 1 taken 20 times.
|
40 | add_wip_expr(error, parent); |
1841 |
1/1✓ Branch 2 taken 20 times.
|
40 | PARSER_THROW(SyntaxError, error); |
1842 | } | ||
1843 | |||
1844 | // fix the things we could not do at the begining | ||
1845 |
4/5✓ Branch 1 taken 110 times.
✓ Branch 4 taken 110 times.
✓ Branch 6 taken 110 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 110 times.
|
220 | parser->end_code_loc(expr, parser->token()); |
1846 |
3/4✓ Branch 1 taken 110 times.
✓ Branch 3 taken 110 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 110 times.
|
220 | parser->start_code_loc(expr, start_tok); |
1847 |
1/1✓ Branch 1 taken 110 times.
|
220 | child->move(expr); |
1848 | // ---------------------------------------------- | ||
1849 | |||
1850 |
4/4✓ Branch 1 taken 110 times.
✓ Branch 4 taken 110 times.
✓ Branch 7 taken 110 times.
✓ Branch 10 taken 110 times.
|
550 | SHOW_TOK(parser->token()); |
1851 | 220 | return expr; | |
1852 | 466 | } | |
1853 | |||
1854 | // [a, b] or [a for b in c] | ||
1855 | ExprNode* Parser::parse_list(Node* parent, int depth) { | ||
1856 | TRACE_START(); | ||
1857 | 56 | return parse_comprehension_or_literal<ListComp, ListExpr>( | |
1858 | 27 | this, parent, tok_square, ']', depth + 1); | |
1859 | } | ||
1860 | |||
1861 | // (a, b) or (a for b in c) | ||
1862 | ExprNode* Parser::parse_tuple_generator(Node* parent, int depth) { | ||
1863 | TRACE_START(); | ||
1864 | 53 | return parse_comprehension_or_literal<GeneratorExp, TupleExpr>( | |
1865 | 35 | this, parent, tok_parens, ')', depth + 1); | |
1866 | } | ||
1867 | |||
1868 | // {a, b} or {a for b in c} or {a: b, c: d} or {a: b for a, b in c} | ||
1869 | ExprNode* Parser::parse_set_dict(Node* parent, int depth) { | ||
1870 | TRACE_START(); | ||
1871 | 124 | return parse_comprehension_or_literal<SetComp, SetExpr>(this, parent, tok_curly, '}', depth); | |
1872 | } | ||
1873 | |||
1874 | ExprNode* Parser::parse_ifexp(Node* parent, ExprNode* primary, int depth) { | ||
1875 | |||
1876 | // if is part of the comprehension | ||
1877 |
4/4✓ Branch 1 taken 40 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 40 times.
✓ Branch 4 taken 10 times.
|
90 | if (parsing_context.size() > 0 && |
1878 |
1/2✓ Branch 2 taken 40 times.
✗ Branch 3 not taken.
|
40 | parsing_context[parsing_context.size() - 1] == ParsingContext::Comprehension) { |
1879 | 40 | return primary; | |
1880 | } | ||
1881 | |||
1882 | // body if test else body | ||
1883 | 10 | IfExp* expr = parent->new_object<IfExp>(); | |
1884 |
4/5✓ Branch 1 taken 10 times.
✓ Branch 4 taken 10 times.
✓ Branch 6 taken 10 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 10 times.
|
10 | start_code_loc(expr, token()); |
1885 | 10 | next_token(); | |
1886 | |||
1887 | 10 | primary->move(expr); | |
1888 | 10 | expr->body = primary; | |
1889 | |||
1890 | 10 | expr->test = parse_expression(expr, depth + 1); | |
1891 | |||
1892 | expect_token(tok_else, true, expr, LOC); | ||
1893 | 8 | expr->orelse = parse_expression(expr, depth + 1); | |
1894 | |||
1895 |
4/5✓ Branch 1 taken 7 times.
✓ Branch 4 taken 7 times.
✓ Branch 6 taken 7 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 7 times.
|
7 | end_code_loc(expr, token()); |
1896 | 7 | return expr; | |
1897 | } | ||
1898 | |||
1899 | // parse_expression_2 | ||
1900 | ExprNode* Parser::parse_named_expr(Node* parent, ExprNode* primary, int depth) { | ||
1901 | TRACE_START(); | ||
1902 | |||
1903 | 7 | auto expr = parent->new_object<NamedExpr>(); | |
1904 | 7 | expr->target = primary; | |
1905 | |||
1906 | // FIXME: this is the location of ':=' not the start of the full expression | ||
1907 |
4/5✓ Branch 1 taken 7 times.
✓ Branch 4 taken 7 times.
✓ Branch 6 taken 7 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 7 times.
|
7 | start_code_loc(expr, token()); |
1908 | 7 | next_token(); | |
1909 | |||
1910 | 7 | expr->value = parse_expression(parent, depth + 1); | |
1911 | |||
1912 |
4/5✓ Branch 1 taken 6 times.
✓ Branch 4 taken 6 times.
✓ Branch 6 taken 6 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 6 times.
|
6 | end_code_loc(expr, token()); |
1913 | 6 | return expr; | |
1914 | } | ||
1915 | |||
1916 | ExprNode* Parser::parse_bool_operator(Node* parent, ExprNode* primary, int depth) { | ||
1917 | TRACE_START(); | ||
1918 | ✗ | return not_implemented_expr(parent); | |
1919 | } | ||
1920 | ExprNode* Parser::parse_binary_operator(Node* parent, ExprNode* primary, int depth) { | ||
1921 | TRACE_START(); | ||
1922 | ✗ | return not_implemented_expr(parent); | |
1923 | } | ||
1924 | ExprNode* Parser::parse_compare_operator(Node* parent, ExprNode* primary, int depth) { | ||
1925 | TRACE_START(); | ||
1926 | ✗ | return not_implemented_expr(parent); | |
1927 | } | ||
1928 | ExprNode* Parser::parse_suffix_unary(Node* parent, ExprNode* primary, int depth) { | ||
1929 | TRACE_START(); | ||
1930 | ✗ | return not_implemented_expr(parent); | |
1931 | } | ||
1932 | |||
1933 | ExprNode* Parser::parse_prefix_unary(Node* parent, int depth) { | ||
1934 | TRACE_START(); | ||
1935 |
1/1✓ Branch 1 taken 39 times.
|
39 | auto expr = parent->new_object<UnaryOp>(); |
1936 |
4/5✓ Branch 1 taken 39 times.
✓ Branch 4 taken 39 times.
✓ Branch 6 taken 39 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 39 times.
|
39 | start_code_loc(expr, token()); |
1937 | |||
1938 |
2/2✓ Branch 1 taken 39 times.
✓ Branch 4 taken 39 times.
|
39 | auto conf = get_operator_config(token()); |
1939 | |||
1940 |
3/3✓ Branch 1 taken 39 times.
✓ Branch 5 taken 8 times.
✓ Branch 6 taken 31 times.
|
39 | if (token().operator_name() == "*") { |
1941 |
1/1✓ Branch 1 taken 7 times.
|
8 | return parse_starred(parent, depth); |
1942 | } | ||
1943 | |||
1944 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
|
31 | if (conf.unarykind == UnaryOperator::None) { |
1945 | ✗ | ParsingError& error = parser_kwerror( // | |
1946 | LOC, // | ||
1947 | "SyntaxError", // | ||
1948 | ✗ | fmtstr("Expected an unary operator not {}", // | |
1949 | ✗ | str(token()))); | |
1950 | |||
1951 | ✗ | add_wip_expr(error, parent); | |
1952 | ✗ | PARSER_THROW(SyntaxError, error); | |
1953 | } | ||
1954 | |||
1955 |
1/1✓ Branch 1 taken 31 times.
|
31 | next_token(); |
1956 | |||
1957 | 31 | expr->op = conf.unarykind; | |
1958 |
1/1✓ Branch 1 taken 27 times.
|
31 | expr->operand = parse_expression(expr, depth + 1); |
1959 | |||
1960 |
4/5✓ Branch 1 taken 27 times.
✓ Branch 4 taken 27 times.
✓ Branch 6 taken 27 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 27 times.
|
27 | end_code_loc(expr, token()); |
1961 | 27 | return expr; | |
1962 | } | ||
1963 | |||
1964 | Token Parser::parse_call_args(Node* expr, | ||
1965 | Array<ExprNode*>& args, | ||
1966 | Array<Keyword>& keywords, | ||
1967 | int depth) { | ||
1968 | TRACE_START(); | ||
1969 | |||
1970 | 193 | bool keyword = false; | |
1971 |
2/2✓ Branch 2 taken 309 times.
✓ Branch 3 taken 51 times.
|
360 | while (token().type() != ')') { |
1972 | |||
1973 | // if not in keyword mode check if next argument is one | ||
1974 |
2/2✓ Branch 0 taken 308 times.
✓ Branch 1 taken 1 times.
|
309 | if (keyword == false) { |
1975 |
2/2✓ Branch 1 taken 308 times.
✓ Branch 4 taken 308 times.
|
308 | auto lookahead = _lex.peek_token(); |
1976 |
7/7✓ Branch 1 taken 308 times.
✓ Branch 4 taken 257 times.
✓ Branch 5 taken 51 times.
✓ Branch 7 taken 78 times.
✓ Branch 8 taken 179 times.
✓ Branch 9 taken 78 times.
✓ Branch 10 taken 230 times.
|
308 | if (token().type() == tok_identifier && lookahead.type() == tok_assign) { |
1977 | 78 | keyword = true; | |
1978 | } | ||
1979 | 308 | } | |
1980 | |||
1981 |
2/2✓ Branch 0 taken 230 times.
✓ Branch 1 taken 79 times.
|
309 | if (!keyword) { |
1982 |
1/1✓ Branch 1 taken 219 times.
|
230 | auto arg = parse_expression(expr, depth + 1); |
1983 |
1/1✓ Branch 1 taken 219 times.
|
219 | args.push_back(arg); |
1984 | } else { | ||
1985 |
1/1✓ Branch 1 taken 79 times.
|
79 | auto kwarg = Keyword(); |
1986 |
2/2✓ Branch 1 taken 79 times.
✓ Branch 4 taken 79 times.
|
79 | kwarg.arg = get_identifier(); // <= NB: this checks for tok_identifier |
1987 | // if not returns a dummy identifier | ||
1988 | expect_token(tok_identifier, true, expr, LOC); | ||
1989 | expect_token(tok_assign, true, expr, LOC); | ||
1990 | |||
1991 |
1/1✓ Branch 1 taken 75 times.
|
79 | kwarg.value = parse_expression(expr, depth + 1); |
1992 |
1/1✓ Branch 1 taken 75 times.
|
75 | keywords.push_back(kwarg); |
1993 | 79 | } | |
1994 | |||
1995 |
2/2✓ Branch 2 taken 167 times.
✓ Branch 3 taken 127 times.
|
294 | if (token().type() == ',') { |
1996 | 167 | next_token(); | |
1997 | } else { | ||
1998 | 127 | break; | |
1999 | } | ||
2000 | } | ||
2001 | |||
2002 | 178 | auto last = token(); | |
2003 | expect_token(')', true, expr, LOC); | ||
2004 | 163 | return last; | |
2005 | 15 | } | |
2006 | |||
2007 | ExprNode* Parser::parse_call(Node* parent, ExprNode* primary, int depth) { | ||
2008 | TRACE_START(); | ||
2009 | |||
2010 |
1/1✓ Branch 1 taken 175 times.
|
175 | auto expr = parent->new_object<Call>(); |
2011 |
4/5✓ Branch 1 taken 175 times.
✓ Branch 4 taken 175 times.
✓ Branch 6 taken 175 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 175 times.
|
175 | start_code_loc(expr, token()); |
2012 | 175 | expr->func = primary; | |
2013 | |||
2014 | // FIXME: this is the location of '(' not the start of the full expression | ||
2015 |
4/5✓ Branch 1 taken 175 times.
✓ Branch 4 taken 175 times.
✓ Branch 6 taken 175 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 175 times.
|
175 | start_code_loc(expr, token()); |
2016 | expect_token(tok_parens, true, expr, LOC); | ||
2017 | |||
2018 |
1/1✓ Branch 1 taken 151 times.
|
175 | auto last = parse_call_args(expr, expr->args, expr->keywords, depth + 1); |
2019 |
3/4✓ Branch 1 taken 151 times.
✓ Branch 3 taken 151 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 151 times.
|
151 | end_code_loc(expr, last); |
2020 | |||
2021 | TRACE_END(); | ||
2022 | 151 | return expr; | |
2023 | 151 | } | |
2024 | |||
2025 | ExprNode* Parser::parse_attribute(Node* parent, ExprNode* primary, int depth) { | ||
2026 | TRACE_START(); | ||
2027 | |||
2028 | 49 | auto expr = parent->new_object<Attribute>(); | |
2029 | 49 | expr->value = primary; | |
2030 | |||
2031 | // FIXME: this is the location of '.' not the start of the full expression | ||
2032 |
4/5✓ Branch 1 taken 49 times.
✓ Branch 4 taken 49 times.
✓ Branch 6 taken 49 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 49 times.
|
49 | start_code_loc(expr, token()); |
2033 | 49 | next_token(); | |
2034 | |||
2035 |
2/2✓ Branch 1 taken 49 times.
✓ Branch 4 taken 49 times.
|
49 | expr->attr = get_identifier(); |
2036 | |||
2037 |
4/5✓ Branch 1 taken 49 times.
✓ Branch 4 taken 49 times.
✓ Branch 6 taken 49 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 49 times.
|
49 | end_code_loc(expr, token()); |
2038 | expect_token(tok_identifier, true, expr, LOC); | ||
2039 | |||
2040 | // expr->ctx = ; | ||
2041 | 45 | return expr; | |
2042 | } | ||
2043 | |||
2044 | ExprNode* Parser::parse_subscript(Node* parent, ExprNode* primary, int depth) { | ||
2045 | TRACE_START(); | ||
2046 | |||
2047 |
1/1✓ Branch 1 taken 21 times.
|
21 | auto expr = parent->new_object<Subscript>(); |
2048 | 21 | expr->value = primary; | |
2049 | |||
2050 | // FIXME: this is the location of '[' not the start of the full expression | ||
2051 |
4/5✓ Branch 1 taken 21 times.
✓ Branch 4 taken 21 times.
✓ Branch 6 taken 21 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 21 times.
|
21 | start_code_loc(expr, token()); |
2052 | expect_token(tok_square, true, expr, LOC); | ||
2053 | |||
2054 | // We do not allocate the TupleExpr unless required | ||
2055 | 21 | Array<ExprNode*> elts; | |
2056 | |||
2057 | // a[2:3] => Slice(2, 3) | ||
2058 | // a[1:2, 2:3] => Tuple(Slice(1, 2), Slice(2, 3)) | ||
2059 | // a[1:2, 2:3] => Tuple(Slice(1, 2), Slice(2, 3)) | ||
2060 | // a[1, 2, 3] => Tuple(1, 2, 3) | ||
2061 | // | ||
2062 | { | ||
2063 |
1/1✓ Branch 1 taken 21 times.
|
21 | PopGuard _(parsing_context, ParsingContext::Slice); |
2064 | |||
2065 |
2/3✓ Branch 1 taken 21 times.
✓ Branch 4 taken 21 times.
✗ Branch 5 not taken.
|
21 | while (token().type() != ']') { |
2066 |
2/2✓ Branch 1 taken 17 times.
✓ Branch 4 taken 17 times.
|
21 | elts.push_back(parse_expression(expr, depth + 1)); |
2067 | |||
2068 |
2/3✓ Branch 1 taken 17 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 17 times.
|
17 | if (token().type() == ',') { |
2069 | ✗ | next_token(); | |
2070 | } else { | ||
2071 | expect_token(']', true, expr, LOC); | ||
2072 | 13 | break; | |
2073 | } | ||
2074 | } | ||
2075 | 21 | } | |
2076 | |||
2077 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 13 times.
|
13 | if (elts.size() == 0) { |
2078 | ✗ | ParsingError& error = parser_kwerror( // | |
2079 | LOC, // | ||
2080 | "SyntaxError", // | ||
2081 | "Substript needs at least one argument" // | ||
2082 | ); | ||
2083 | ✗ | add_wip_expr(error, parent); | |
2084 | ✗ | PARSER_THROW(SyntaxError, error); | |
2085 | } | ||
2086 | |||
2087 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | if (elts.size() == 1) { |
2088 | 13 | expr->slice = elts[0]; | |
2089 | } | ||
2090 | |||
2091 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 13 times.
|
13 | if (elts.size() > 1) { |
2092 | ✗ | auto tuple = expr->new_object<TupleExpr>(); | |
2093 | ✗ | tuple->elts = elts; | |
2094 | ✗ | expr->slice = tuple; | |
2095 | } | ||
2096 | |||
2097 |
4/5✓ Branch 1 taken 13 times.
✓ Branch 4 taken 13 times.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 13 times.
|
13 | end_code_loc(expr, token()); |
2098 | 13 | return expr; | |
2099 | 21 | } | |
2100 | |||
2101 | void Parser::error_recovery(ParsingError* error) { | ||
2102 |
4/4✓ Branch 1 taken 607 times.
✓ Branch 5 taken 607 times.
✓ Branch 7 taken 42 times.
✓ Branch 8 taken 565 times.
|
607 | while (!in(token().type(), tok_newline, tok_eof)) { |
2103 | 42 | error->remaining.push_back(token()); | |
2104 | 42 | next_token(); | |
2105 | } | ||
2106 | 565 | error->line = currentline.tokens; | |
2107 | |||
2108 |
2/2✓ Branch 1 taken 526 times.
✓ Branch 2 taken 39 times.
|
565 | if (error->line.size() > 0) { |
2109 | 526 | Token const& start = error->line[0]; | |
2110 | 526 | Token const& end = error->line[int(error->line.size() - 1)]; | |
2111 | |||
2112 | // then we got a new line | ||
2113 |
2/2✓ Branch 1 taken 519 times.
✓ Branch 2 taken 7 times.
|
526 | if (!error->received_token.isbetween(start, end)) { |
2114 | 519 | error->received_token = end; | |
2115 | } | ||
2116 | } else { | ||
2117 | kwerror("Was not able to retrieve the tok line for an error"); | ||
2118 | } | ||
2119 | 565 | } | |
2120 | |||
2121 | ExprNode* Parser::parse_slice(Node* parent, ExprNode* primary, int depth) { | ||
2122 | TRACE_START(); | ||
2123 | |||
2124 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 18 times.
|
18 | if (!allow_slice()) { |
2125 | ✗ | ParsingError& error = parser_kwerror( // | |
2126 | LOC, // | ||
2127 | "SyntaxError", // | ||
2128 | "Slice is not allowed in this context" // | ||
2129 | ); | ||
2130 | ✗ | add_wip_expr(error, primary); | |
2131 | ✗ | PARSER_THROW(SyntaxError, error); | |
2132 | |||
2133 | // fallback to primary | ||
2134 | return primary; | ||
2135 | } | ||
2136 | |||
2137 | 18 | auto expr = parent->new_object<Slice>(); | |
2138 |
4/5✓ Branch 1 taken 18 times.
✓ Branch 4 taken 18 times.
✓ Branch 6 taken 18 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 18 times.
|
18 | start_code_loc(expr, token()); |
2139 | |||
2140 | 18 | expr->lower = primary; | |
2141 | expect_token(':', true, expr, LOC); | ||
2142 | |||
2143 |
2/2✓ Branch 1 taken 15 times.
✓ Branch 4 taken 15 times.
|
18 | expr->upper = parse_expression(expr, depth + 1); |
2144 | |||
2145 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 15 times.
|
15 | if (token().type() == ':') { |
2146 | ✗ | next_token(); | |
2147 | ✗ | expr->step = parse_expression(expr, depth + 1); | |
2148 | } | ||
2149 | 15 | return expr; | |
2150 | } | ||
2151 | |||
2152 | void set_decorators(StmtNode* stmt, Array<Decorator>& decorators) { | ||
2153 |
2/2✓ Branch 1 taken 19 times.
✓ Branch 2 taken 1817 times.
|
1836 | if (decorators.size() > 0) { |
2154 |
2/2✓ Branch 0 taken 13 times.
✓ Branch 1 taken 6 times.
|
19 | if (stmt->kind == NodeKind::FunctionDef) { |
2155 | 13 | auto fun = cast<FunctionDef>(stmt); | |
2156 | 13 | fun->decorator_list = decorators; | |
2157 | |||
2158 |
1/2✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
|
6 | } else if (stmt->kind == NodeKind::ClassDef) { |
2159 | 6 | auto cls = cast<ClassDef>(stmt); | |
2160 | 6 | cls->decorator_list = decorators; | |
2161 | } | ||
2162 | } | ||
2163 | 1836 | } | |
2164 | |||
2165 | StmtNode* Parser::parse_statement(Node* parent, int depth) { | ||
2166 | |||
2167 | TRACE_START(); | ||
2168 | |||
2169 | 2395 | Array<Decorator> decorators; | |
2170 |
3/3✓ Branch 1 taken 2530 times.
✓ Branch 4 taken 156 times.
✓ Branch 5 taken 2374 times.
|
2530 | while (token().type() == tok_decorator) { |
2171 |
1/1✓ Branch 1 taken 156 times.
|
156 | next_token(); |
2172 | |||
2173 | 156 | Comment* comment = nullptr; | |
2174 |
1/1✓ Branch 1 taken 135 times.
|
156 | auto fun = parse_expression(parent, depth); |
2175 | |||
2176 |
3/3✓ Branch 1 taken 135 times.
✓ Branch 4 taken 5 times.
✓ Branch 5 taken 130 times.
|
135 | if (token().type() == tok_comment) { |
2177 |
1/1✓ Branch 1 taken 5 times.
|
5 | comment = parse_comment(fun, depth); |
2178 | } | ||
2179 | |||
2180 |
1/1✓ Branch 1 taken 135 times.
|
135 | decorators.emplace_back(fun, comment); |
2181 | |||
2182 |
3/3✓ Branch 1 taken 135 times.
✓ Branch 4 taken 128 times.
✓ Branch 5 taken 7 times.
|
135 | if (token().type() == tok_newline) { |
2183 |
1/1✓ Branch 1 taken 128 times.
|
128 | next_token(); |
2184 | } | ||
2185 | } | ||
2186 | |||
2187 |
1/1✓ Branch 1 taken 1836 times.
|
2374 | auto stmt = parse_statement_primary(parent, depth + 1); |
2188 |
1/1✓ Branch 1 taken 1836 times.
|
1836 | set_decorators(stmt, decorators); |
2189 | |||
2190 |
3/3✓ Branch 1 taken 1836 times.
✓ Branch 4 taken 1823 times.
✓ Branch 5 taken 13 times.
|
1836 | if (token().type() != ';') { |
2191 | TRACE_END(); | ||
2192 | 1823 | return stmt; | |
2193 | } | ||
2194 | |||
2195 | 13 | Array<StmtNode*> body; | |
2196 |
1/1✓ Branch 1 taken 13 times.
|
13 | body.push_back(stmt); |
2197 | |||
2198 |
3/3✓ Branch 1 taken 30 times.
✓ Branch 4 taken 21 times.
✓ Branch 5 taken 9 times.
|
30 | while (token().type() == ';') { |
2199 |
1/1✓ Branch 1 taken 21 times.
|
21 | next_token(); |
2200 | |||
2201 |
3/3✓ Branch 1 taken 21 times.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 19 times.
|
21 | if (is_tok_statement_ender()) { |
2202 | 2 | break; | |
2203 | } | ||
2204 | |||
2205 |
1/1✓ Branch 1 taken 17 times.
|
19 | stmt = parse_statement_primary(parent, depth + 1); |
2206 |
1/1✓ Branch 1 taken 17 times.
|
17 | body.push_back(stmt); |
2207 | } | ||
2208 | |||
2209 | 11 | stmt = nullptr; | |
2210 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 10 times.
|
11 | if (body.size() == 1) { |
2211 | 1 | stmt = body[0]; | |
2212 | } else { | ||
2213 |
1/1✓ Branch 1 taken 10 times.
|
10 | auto inlinestmt = parent->new_object<Inline>(); |
2214 |
1/1✓ Branch 1 taken 10 times.
|
10 | inlinestmt->body = body; |
2215 | 10 | stmt = inlinestmt; | |
2216 | } | ||
2217 | |||
2218 | TRACE_END(); | ||
2219 | 11 | return stmt; | |
2220 | 2397 | } | |
2221 | |||
2222 | StmtNode* Parser::parse_yield_stmt(Node* parent, int depth) { | ||
2223 | // yield is an expression in the AST but it can be parsed | ||
2224 | // as simple_statement or an expression | ||
2225 | 30 | auto stmt = parent->new_object<Expr>(); | |
2226 | 30 | stmt->value = parse_yield(stmt, depth); | |
2227 | 28 | return stmt; | |
2228 | } | ||
2229 | |||
2230 | StmtNode* Parser::parse_comment_stmt(Node* parent, int depth) { | ||
2231 | 116 | Expr* comment_stmt = parent->new_object<Expr>(); | |
2232 | 116 | ExprNode* comment = parse_comment(comment_stmt, depth); | |
2233 | |||
2234 | 116 | comment_stmt->value = comment; | |
2235 | |||
2236 | expect_tokens({tok_newline, tok_eof}, true, comment_stmt, LOC); | ||
2237 | 116 | return comment_stmt; | |
2238 | } | ||
2239 | |||
2240 | StmtNode* Parser::parse_statement_primary(Node* parent, int depth) { | ||
2241 | TRACE_START(); | ||
2242 | |||
2243 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 2393 times.
|
2393 | if (previous == token()) { |
2244 | ✗ | ParsingError& error = parser_kwerror( // | |
2245 | LOC, // | ||
2246 | "SyntaxError", // | ||
2247 | ✗ | fmtstr("Unhandled token {} `{}` previous tok was `{}`", // | |
2248 | ✗ | token().type(), // | |
2249 | ✗ | str(token()), // | |
2250 | ✗ | str(previous) // | |
2251 | ) // | ||
2252 | ); | ||
2253 | ✗ | add_wip_expr(error, parent); | |
2254 | ✗ | PARSER_THROW(SyntaxError, error); | |
2255 | } else { | ||
2256 | 2393 | previous = token(); | |
2257 | } | ||
2258 | |||
2259 | // Statement we can guess rightaway from the current token we are seeing | ||
2260 |
21/23✗ Branch 2 not taken.
✓ Branch 3 taken 286 times.
✓ Branch 4 taken 30 times.
✓ Branch 5 taken 44 times.
✓ Branch 6 taken 16 times.
✓ Branch 7 taken 301 times.
✓ Branch 8 taken 9 times.
✓ Branch 9 taken 30 times.
✓ Branch 10 taken 20 times.
✓ Branch 11 taken 6 times.
✓ Branch 12 taken 7 times.
✓ Branch 13 taken 6 times.
✓ Branch 14 taken 6 times.
✓ Branch 15 taken 216 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 33 times.
✓ Branch 18 taken 76 times.
✓ Branch 19 taken 52 times.
✓ Branch 20 taken 48 times.
✓ Branch 21 taken 35 times.
✓ Branch 22 taken 25 times.
✓ Branch 23 taken 141 times.
✓ Branch 24 taken 1006 times.
|
2393 | switch (token().type()) { |
2261 | // clang-format off | ||
2262 | |||
2263 | // Small Statement | ||
2264 | // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> | ||
2265 | // assignment: | ||
2266 | // | NAME ':' expression ['=' annotated_rhs ] | ||
2267 | // | single_target ':' expression ['=' annotated_rhs ] | ||
2268 | // | (star_targets '=' )+ (yield_expr | star_expressions) !'=' [TYPE_COMMENT] | ||
2269 | // | single_target augassign ~ (yield_expr | star_expressions) | ||
2270 | // | ||
2271 | // single_target: | ||
2272 | // | single_subscript_attribute_target | ||
2273 | // | NAME | ||
2274 | // | '(' single_target ')' | ||
2275 | // | ||
2276 | // single_subscript_attribute_target: | ||
2277 | // | t_primary '.' NAME !t_lookahead | ||
2278 | // | t_primary '[' slices ']' !t_lookahead | ||
2279 | // | ||
2280 | // star_targets: | ||
2281 | // | star_target !',' | ||
2282 | // | star_target (',' star_target )* [','] | ||
2283 | |||
2284 | // star_target: | ||
2285 | // | '*' (!'*' star_target) | ||
2286 | // | target_with_star_atom | ||
2287 | // target_with_star_atom: | ||
2288 | // | t_primary '.' NAME !t_lookahead | ||
2289 | // | t_primary '[' slices ']' !t_lookahead | ||
2290 | // | star_atom | ||
2291 | // star_atom: | ||
2292 | // | NAME | ||
2293 | // | '(' target_with_star_atom ')' | ||
2294 | // | '(' [star_targets_tuple_seq] ')' | ||
2295 | // | '[' [star_targets_list_seq] ']' | ||
2296 | // star_targets_list_seq: ','.star_target+ [','] | ||
2297 | // star_targets_tuple_seq: | ||
2298 | // | star_target (',' star_target )+ [','] | ||
2299 | // | star_target ',' | ||
2300 | |||
2301 | // star_expressions | ||
2302 | // | ||
2303 | |||
2304 | // clang-format on | ||
2305 | ✗ | case tok_comment: return parse_comment_stmt(parent, depth); | |
2306 | 286 | case tok_return: return parse_return(parent, depth); | |
2307 | 30 | case tok_import: return parse_import(parent, depth); | |
2308 | 44 | case tok_from: return parse_import_from(parent, depth); | |
2309 | 16 | case tok_raise: return parse_raise(parent, depth); | |
2310 | 301 | case tok_pass: return parse_pass(parent, depth); | |
2311 | 9 | case tok_del: return parse_del(parent, depth); | |
2312 | 30 | case tok_yield: return parse_yield_stmt(parent, depth); | |
2313 | 20 | case tok_assert: return parse_assert(parent, depth); | |
2314 | 6 | case tok_break: return parse_break(parent, depth); | |
2315 | 7 | case tok_continue: return parse_continue(parent, depth); | |
2316 | 6 | case tok_global: return parse_global(parent, depth); | |
2317 | 6 | case tok_nonlocal: return parse_nonlocal(parent, depth); | |
2318 | // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< | ||
2319 | |||
2320 | // Compound Statement | ||
2321 | // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> | ||
2322 | // def <name>(... | ||
2323 | 216 | case tok_def: return parse_function_def(parent, false, depth); | |
2324 | // async def <name>(... | ||
2325 | ✗ | case tok_async: return parse_function_def(parent, true, depth); | |
2326 | 33 | case tok_if: return parse_if_alt(parent, depth); | |
2327 | 76 | case tok_class: return parse_class_def(parent, depth); | |
2328 | 52 | case tok_with: return parse_with(parent, depth); | |
2329 | |||
2330 | // Async for: only valid inside async function | ||
2331 | 48 | case tok_for: return parse_for(parent, depth); | |
2332 | 35 | case tok_try: return parse_try(parent, depth); | |
2333 | 25 | case tok_while: return parse_while(parent, depth); | |
2334 | 141 | case tok_match: return parse_match(parent, depth); | |
2335 | } | ||
2336 | |||
2337 | 1006 | auto expr = parse_expression(parent, depth); | |
2338 | TRACE_START(); | ||
2339 | |||
2340 | // allow unpacking | ||
2341 | // promote to a tuple expression | ||
2342 |
2/2✓ Branch 2 taken 47 times.
✓ Branch 3 taken 840 times.
|
887 | if (token().type() == tok_comma) { |
2343 | 47 | next_token(); | |
2344 | 47 | expr = parse_literal<TupleExpr>(this, parent, expr, 0, depth); | |
2345 | } | ||
2346 | |||
2347 |
4/4✓ Branch 2 taken 342 times.
✓ Branch 3 taken 26 times.
✓ Branch 4 taken 115 times.
✓ Branch 5 taken 393 times.
|
876 | switch (token().type()) { |
2348 | // <expr> = <> | ||
2349 | 342 | case tok_assign: return parse_assign(parent, expr, depth); | |
2350 | // <expr> += <> | ||
2351 | 26 | case tok_augassign: return parse_augassign(parent, expr, depth); | |
2352 | // <expr>: type = <> | ||
2353 | 115 | case ':': | |
2354 | 115 | case tok_annassign: return parse_annassign(parent, expr, depth); | |
2355 | } | ||
2356 | |||
2357 | // fallback to standard expression | ||
2358 | 393 | auto stmt_expr = parent->new_object<Expr>(); | |
2359 | 393 | stmt_expr->value = expr; | |
2360 | TRACE_END(); | ||
2361 | 393 | return stmt_expr; | |
2362 | } | ||
2363 | |||
2364 | // Precedence climbing method | ||
2365 | // I liked shunting yard algorithm better has it was not recursive | ||
2366 | // but it got issues with some edge cases. | ||
2367 | // | ||
2368 | // https://en.wikipedia.org/wiki/Operator-precedence_parser#:~:text=The%20precedence%20climbing%20method%20is%20a%20compact%2C%20efficient%2C,in%20EBNF%20format%20will%20usually%20look%20like%20this%3A | ||
2369 | ExprNode* Parser::parse_operators(Node* og_parent, ExprNode* lhs, int min_precedence, int depth) { | ||
2370 | TRACE_START(); | ||
2371 | |||
2372 | 299 | Node* parent = og_parent; | |
2373 | 299 | BinOp* binop = nullptr; | |
2374 | 299 | Compare* comp = nullptr; | |
2375 | 299 | BoolOp* boolop = nullptr; | |
2376 | |||
2377 | // FIXME: For error reporting we need to catch th error here and build the partia expression | ||
2378 | while (true) { | ||
2379 |
2/2✓ Branch 1 taken 565 times.
✓ Branch 4 taken 565 times.
|
565 | Token lookahead = token(); |
2380 |
1/1✓ Branch 1 taken 565 times.
|
565 | OpConfig const& op_conf = get_operator_config(lookahead); |
2381 | 565 | int oppred = op_conf.precedence; | |
2382 | |||
2383 |
2/2✓ Branch 0 taken 256 times.
✓ Branch 1 taken 309 times.
|
565 | if (op_conf.type == tok_eof) { |
2384 | 256 | return lhs; | |
2385 | } | ||
2386 | |||
2387 | // lookahead is a binary operator whose precedence is >= min_precedence | ||
2388 |
5/6✓ Branch 1 taken 299 times.
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 299 times.
✓ Branch 5 taken 10 times.
✓ Branch 6 taken 299 times.
|
309 | if (!(is_binary_operator_family(op_conf) && oppred >= min_precedence)) { |
2389 | 10 | break; | |
2390 | } | ||
2391 | |||
2392 | // we are going to build the operator for sure | ||
2393 | // create the operator right away so we can use save what we have so far for error reporting | ||
2394 |
2/2✓ Branch 0 taken 154 times.
✓ Branch 1 taken 145 times.
|
299 | if (op_conf.binarykind != BinaryOperator::None) { |
2395 |
1/1✓ Branch 1 taken 154 times.
|
154 | binop = parent->new_object<BinOp>(); |
2396 | 154 | binop->left = lhs; | |
2397 | 154 | binop->op = op_conf.binarykind; | |
2398 | |||
2399 | 154 | parent = binop; | |
2400 | } | ||
2401 | |||
2402 |
2/2✓ Branch 0 taken 111 times.
✓ Branch 1 taken 34 times.
|
145 | else if (op_conf.cmpkind != CmpOperator::None) { |
2403 | // parent is a Comparison (1 < ?expr < ) and we are doing chained comparison | ||
2404 |
1/1✓ Branch 1 taken 111 times.
|
111 | Compare* lhs_parent = cast<Compare>(parent); |
2405 |
2/2✓ Branch 0 taken 22 times.
✓ Branch 1 taken 89 times.
|
111 | if (lhs_parent != nullptr) { |
2406 | 22 | comp = lhs_parent; | |
2407 |
2/3✓ Branch 1 taken 22 times.
✓ Branch 3 taken 22 times.
✗ Branch 4 not taken.
|
22 | if (comp->safe_comparator_add(lhs)) { |
2408 |
1/1✓ Branch 1 taken 22 times.
|
22 | comp->ops.push_back(op_conf.cmpkind); |
2409 | } else { | ||
2410 | ✗ | ParsingError& err = parser_kwerror( // | |
2411 | LOC, // | ||
2412 | "SyntaxError", // | ||
2413 | ✗ | fmtstr("Unable to parse comparators") // | |
2414 | ); | ||
2415 | ✗ | add_wip_expr(err, parent); | |
2416 | ✗ | PARSER_THROW(SyntaxError, err); | |
2417 | } | ||
2418 | } else { | ||
2419 |
1/1✓ Branch 1 taken 89 times.
|
89 | comp = parent->new_object<Compare>(); |
2420 | 89 | comp->left = lhs; | |
2421 |
1/1✓ Branch 1 taken 89 times.
|
89 | comp->ops.push_back(op_conf.cmpkind); |
2422 | } | ||
2423 | |||
2424 | 111 | parent = comp; | |
2425 | } | ||
2426 | |||
2427 |
1/2✓ Branch 0 taken 34 times.
✗ Branch 1 not taken.
|
34 | else if (op_conf.boolkind != BoolOperator::None) { |
2428 |
1/1✓ Branch 1 taken 34 times.
|
34 | BoolOp* lhs_parent = cast<BoolOp>(parent); |
2429 | |||
2430 |
3/4✓ Branch 0 taken 7 times.
✓ Branch 1 taken 27 times.
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
|
34 | if (lhs_parent != nullptr && lhs_parent->op == op_conf.boolkind) { |
2431 | 7 | boolop = lhs_parent; | |
2432 | |||
2433 |
2/3✓ Branch 1 taken 7 times.
✓ Branch 3 taken 7 times.
✗ Branch 4 not taken.
|
7 | if (boolop->safe_value_add(lhs)) { |
2434 | 7 | boolop->opcount += 1; | |
2435 | } else { | ||
2436 | ✗ | ParsingError& err = parser_kwerror( // | |
2437 | LOC, // | ||
2438 | "SyntaxError", // | ||
2439 | ✗ | fmtstr("Unable to finish parsing bool operator") // | |
2440 | ); | ||
2441 | ✗ | add_wip_expr(err, parent); | |
2442 | ✗ | PARSER_THROW(SyntaxError, err); | |
2443 | } | ||
2444 | |||
2445 | 7 | } else { | |
2446 |
1/1✓ Branch 1 taken 27 times.
|
27 | boolop = parent->new_object<BoolOp>(); |
2447 | 27 | boolop->op = op_conf.boolkind; | |
2448 |
1/1✓ Branch 1 taken 27 times.
|
27 | boolop->values = {lhs}; |
2449 | 27 | boolop->opcount = 1; | |
2450 | } | ||
2451 | |||
2452 | 34 | parent = boolop; | |
2453 | } | ||
2454 | |||
2455 |
1/1✓ Branch 1 taken 299 times.
|
299 | next_token(); |
2456 | // in the case of 1 < 2 < 3 | ||
2457 | |||
2458 |
1/1✓ Branch 1 taken 266 times.
|
299 | auto* rhs = parse_expression(parent, depth); |
2459 |
2/2✓ Branch 1 taken 266 times.
✓ Branch 4 taken 266 times.
|
266 | lookahead = token(); |
2460 | |||
2461 |
1/1✓ Branch 1 taken 266 times.
|
266 | auto lookconf = get_operator_config(lookahead); |
2462 | 266 | auto lookpred = lookconf.precedence; | |
2463 | 266 | auto right_assoc = !lookconf.left_associative; | |
2464 | |||
2465 | // lookahead is a binary operator whose precedence is greater | ||
2466 | // than op's, or a right-associative operator | ||
2467 | // whose precedence is equal to op's | ||
2468 |
2/8✗ Branch 1 not taken.
✓ Branch 2 taken 266 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 266 times.
|
266 | while (lookahead.type() == tok_operator && is_binary_operator_family(lookconf) && |
2469 | ✗ | (lookpred > oppred || (right_assoc && lookpred == oppred))) { | |
2470 | ✗ | rhs = parse_expression_1(parent, rhs, oppred, depth + 1); | |
2471 | |||
2472 | ✗ | lookahead = token(); | |
2473 | |||
2474 | ✗ | lookconf = get_operator_config(lookahead); | |
2475 | ✗ | lookpred = lookconf.precedence; | |
2476 | ✗ | right_assoc = !lookconf.left_associative; | |
2477 | } | ||
2478 | |||
2479 | // the result of applying op with operands lhs and rhs | ||
2480 |
2/2✓ Branch 0 taken 140 times.
✓ Branch 1 taken 126 times.
|
266 | if (op_conf.binarykind != BinaryOperator::None) { |
2481 | 140 | binop->right = rhs; | |
2482 | 140 | lhs = binop; | |
2483 |
2/2✓ Branch 0 taken 97 times.
✓ Branch 1 taken 29 times.
|
126 | } else if (op_conf.cmpkind != CmpOperator::None) { |
2484 | // rhs can be comp if it was a nested comparison | ||
2485 | // but it does not have to be | ||
2486 |
2/2✓ Branch 0 taken 78 times.
✓ Branch 1 taken 19 times.
|
97 | if (rhs != comp) { |
2487 |
1/1✓ Branch 1 taken 78 times.
|
78 | comp->safe_comparator_add(rhs); |
2488 | } | ||
2489 | // | ||
2490 | 97 | lhs = comp; | |
2491 | |||
2492 |
1/2✓ Branch 0 taken 29 times.
✗ Branch 1 not taken.
|
29 | } else if (op_conf.boolkind != BoolOperator::None) { |
2493 |
2/2✓ Branch 0 taken 23 times.
✓ Branch 1 taken 6 times.
|
29 | if (rhs != boolop) { |
2494 |
1/1✓ Branch 1 taken 23 times.
|
23 | boolop->values.push_back(rhs); |
2495 | } | ||
2496 | 29 | lhs = boolop; | |
2497 | } else { | ||
2498 | kwerror("unknow operator {}", str(op_conf)); | ||
2499 | } | ||
2500 | 831 | } | |
2501 | |||
2502 | TRACE_END(); | ||
2503 | 10 | return lhs; | |
2504 | } | ||
2505 | |||
2506 | Comment* Parser::parse_comment(Node* parent, int depth) { | ||
2507 | TRACE_START(); | ||
2508 | |||
2509 | 278 | Comment* com = parent->new_object<Comment>(); | |
2510 | assert(token().type() == tok_comment, "Need a comment token"); | ||
2511 | |||
2512 | 278 | com->comment = token().identifier(); | |
2513 | 278 | next_token(); | |
2514 | |||
2515 | // while (!in(token().type(), tok_newline, tok_eof)) { | ||
2516 | // com->tokens.push_back(token()); | ||
2517 | // next_token(); | ||
2518 | // } | ||
2519 | |||
2520 | 278 | return com; | |
2521 | } | ||
2522 | |||
2523 | ExprNode* Parser::parse_expression(Node* parent, int depth, bool comma) { | ||
2524 | TRACE_START(); | ||
2525 | |||
2526 | 4206 | expression_depth += 1; | |
2527 | // parse primary | ||
2528 | 4206 | auto primary = parse_expression_primary(parent, depth); | |
2529 | |||
2530 |
3/3✓ Branch 2 taken 175 times.
✓ Branch 3 taken 49 times.
✓ Branch 4 taken 3644 times.
|
3868 | switch (token().type()) { |
2531 | |||
2532 | // <expr>(args...) | ||
2533 | 175 | case tok_parens: { | |
2534 | 175 | primary = parse_call(parent, primary, depth); | |
2535 | 151 | break; | |
2536 | } | ||
2537 | |||
2538 | // <expr>.<identifier> | ||
2539 | 49 | case tok_dot: { | |
2540 | 49 | primary = parse_attribute(parent, primary, depth); | |
2541 | 45 | break; | |
2542 | } | ||
2543 | } | ||
2544 | |||
2545 | 3840 | primary = parse_expression_1(parent, primary, 0, depth, comma); | |
2546 | |||
2547 | 3786 | expression_depth -= 1; | |
2548 | 3786 | return primary; | |
2549 | } | ||
2550 | |||
2551 | // Expression we can guess rightaway from the current token we are seeing | ||
2552 | ExprNode* Parser::parse_expression_primary(Node* parent, int depth) { | ||
2553 | |||
2554 |
11/13✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3580 times.
✓ Branch 5 taken 644 times.
✓ Branch 6 taken 18 times.
✓ Branch 7 taken 56 times.
✓ Branch 8 taken 53 times.
✓ Branch 9 taken 124 times.
✓ Branch 10 taken 9 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 1 times.
✓ Branch 13 taken 39 times.
✓ Branch 14 taken 248 times.
|
4779 | switch (token().type()) { |
2555 | // await <expr> | ||
2556 | 7 | case tok_await: return parse_await(parent, depth); | |
2557 | |||
2558 | // yield from <expr> | ||
2559 | // yield <expr> | ||
2560 | ✗ | case tok_yield_from: | |
2561 | ✗ | case tok_yield: return parse_yield(parent, depth); | |
2562 | |||
2563 | // atom: | ||
2564 | // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> | ||
2565 | // Name: <identifier> | ||
2566 | 3580 | case tok_identifier: return parse_name(parent, depth); | |
2567 | |||
2568 | 644 | case tok_none: | |
2569 | case tok_true: | ||
2570 | case tok_false: | ||
2571 | case tok_int: | ||
2572 | case tok_float: | ||
2573 | 644 | case tok_string: return parse_constant(parent, depth); | |
2574 | 18 | case tok_formatstr: return parse_special_string(parent, depth); | |
2575 | |||
2576 | // List: [a, b] | ||
2577 | // Comprehension [a for a in b] | ||
2578 | 56 | case tok_square: return parse_list(parent, depth); | |
2579 | |||
2580 | // Tuple: (a, b) | ||
2581 | // Generator Comprehension: (a for a in b) | ||
2582 | // can be (1 + b) | ||
2583 | 53 | case tok_parens: return parse_tuple_generator(parent, depth); | |
2584 | |||
2585 | // Set: {a, b} | ||
2586 | // Comprehension {a for a in b} | ||
2587 | // OR | ||
2588 | // Dict: {a : b} | ||
2589 | // Comprehension {a: b for a, b in c} | ||
2590 | 124 | case tok_curly: return parse_set_dict(parent, depth); | |
2591 | |||
2592 | // TODO: add elipsis | ||
2593 | |||
2594 | // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< | ||
2595 | // lambda <name>: | ||
2596 | 9 | case tok_lambda: return parse_lambda(parent, depth); | |
2597 | |||
2598 | // f" | ||
2599 | ✗ | case tok_fstring: return parse_joined_string(parent, depth); | |
2600 | |||
2601 | // not python syntax | ||
2602 | // if <expr> else <expr> | ||
2603 | 1 | case tok_if: { | |
2604 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | if (with_extension) |
2605 | 1 | return parse_ifexp_ext(parent, depth); | |
2606 | } | ||
2607 | |||
2608 | // *<expr> | ||
2609 | case tok_star: | ||
2610 | 39 | case tok_operator: return parse_prefix_unary(parent, depth); | |
2611 | } | ||
2612 | |||
2613 | // Left Unary operator | ||
2614 | // + <expr> | - <expr> | ! <expr> | ~ <expr> | ||
2615 | |||
2616 |
2/2✓ Branch 2 taken 248 times.
✓ Branch 6 taken 248 times.
|
496 | ParsingError& error = parser_kwerror( // |
2617 | LOC, // | ||
2618 | "SyntaxError", // | ||
2619 | // fmtstr("Could not deduce the expression {}", str(TokenType(token().type()))) // | ||
2620 | "Expected an expression" // | ||
2621 | ); | ||
2622 | 248 | add_wip_expr(error, parent); | |
2623 |
1/1✓ Branch 2 taken 248 times.
|
248 | PARSER_THROW(SyntaxError, error); |
2624 | } | ||
2625 | |||
2626 | ExprNode* Parser::parse_expression_1( | ||
2627 | Node* parent, ExprNode* primary, int min_precedence, int depth, bool comma) { | ||
2628 | // | ||
2629 |
7/8✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 50 times.
✓ Branch 5 taken 299 times.
✓ Branch 6 taken 21 times.
✓ Branch 7 taken 524 times.
✓ Branch 8 taken 580 times.
✓ Branch 9 taken 2368 times.
|
3849 | switch (token().type()) { |
2630 | // <expr> := <expr> | ||
2631 | // assign expression instead of the usual assign statement | ||
2632 | 7 | case tok_walrus: return parse_named_expr(parent, primary, depth); | |
2633 | |||
2634 | // <expr> boolop <expr> | ||
2635 | /* | ||
2636 | case tok_boolop: | ||
2637 | return parse_bool_operator(parent, primary, depth); | ||
2638 | case tok_binaryop: | ||
2639 | return parse_binary_operator(parent, primary, depth); | ||
2640 | case tok_compareop: | ||
2641 | return parse_compare_operator(parent, primary, depth); | ||
2642 | */ | ||
2643 | ✗ | case tok_unaryop: return parse_suffix_unary(parent, primary, depth); | |
2644 | |||
2645 | 50 | case tok_if: return parse_ifexp(parent, primary, depth); | |
2646 | 299 | case tok_in: | |
2647 | 299 | case tok_operator: return parse_operators(parent, primary, min_precedence, depth); | |
2648 | |||
2649 | // <expr>[ | ||
2650 | 21 | case tok_square: return parse_subscript(parent, primary, depth); | |
2651 | |||
2652 | // this causes more issues than it solves | ||
2653 | // to allow unpacking we will need to move this to somewhere more specific | ||
2654 | 524 | case tok_comma: { | |
2655 | // If we are going deeper we neeed the user to use ( explicitly | ||
2656 |
2/2✓ Branch 0 taken 35 times.
✓ Branch 1 taken 489 times.
|
524 | if (comma) { |
2657 | 35 | next_token(); | |
2658 | |||
2659 | 35 | auto expr = parse_literal<TupleExpr>(this, parent, primary, '\0', depth); | |
2660 | 29 | return expr; | |
2661 | } | ||
2662 | } | ||
2663 | |||
2664 | // ':' is only valid inside a subscript | ||
2665 | case ':': { | ||
2666 |
2/2✓ Branch 1 taken 18 times.
✓ Branch 2 taken 1051 times.
|
1069 | if (allow_slice()) |
2667 | 18 | return parse_slice(parent, primary, depth); | |
2668 | } | ||
2669 | } | ||
2670 | |||
2671 | 3419 | return primary; | |
2672 | } | ||
2673 | |||
2674 | ExprNode* Parser::parse_special_string(Node* parent, int depth) { | ||
2675 | TRACE_START(); | ||
2676 | |||
2677 |
2/2✓ Branch 1 taken 18 times.
✓ Branch 5 taken 18 times.
|
18 | String format_type = token().identifier(); |
2678 | |||
2679 |
1/2✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
|
18 | if (format_type == "f") { |
2680 |
1/1✓ Branch 1 taken 18 times.
|
18 | return parse_joined_string(parent, depth); |
2681 | } | ||
2682 | |||
2683 | ✗ | if (format_type == "b") { | |
2684 | ✗ | next_token(); | |
2685 | ✗ | return parse_constant(parent, depth); | |
2686 | } | ||
2687 | |||
2688 | ✗ | if (format_type == "r") { | |
2689 | ✗ | next_token(); | |
2690 | ✗ | return parse_constant(parent, depth); | |
2691 | } | ||
2692 | |||
2693 | ✗ | return nullptr; | |
2694 | 18 | } | |
2695 | |||
2696 | struct SetLexerMode { | ||
2697 | SetLexerMode(AbstractLexer& lexer, LexerMode mode): lexer(lexer) { | ||
2698 | 58 | old_mode = int(lexer.get_mode()); | |
2699 | 58 | lexer.set_mode(int(mode)); | |
2700 | 58 | } | |
2701 | |||
2702 | ~SetLexerMode() { lexer.set_mode(old_mode); } | ||
2703 | |||
2704 | int old_mode; | ||
2705 | AbstractLexer& lexer; | ||
2706 | }; | ||
2707 | |||
2708 | // FIXME: this can be simplified if the fmtstr lexer tokenize more | ||
2709 | ExprNode* Parser::parse_joined_string(Node* parent, int depth) { | ||
2710 |
2/2✓ Branch 1 taken 18 times.
✓ Branch 4 taken 18 times.
|
18 | Token tok = token(); // `f` |
2711 | |||
2712 |
1/1✓ Branch 1 taken 18 times.
|
18 | JoinedStr* expr = parent->new_object<JoinedStr>(); |
2713 |
4/5✓ Branch 1 taken 18 times.
✓ Branch 4 taken 18 times.
✓ Branch 6 taken 18 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 18 times.
|
18 | start_code_loc(expr, token()); |
2714 | int8 endquote; | ||
2715 | |||
2716 | { | ||
2717 |
1/1✓ Branch 1 taken 18 times.
|
18 | SetLexerMode _(_lex, LexerMode::Character); |
2718 |
2/2✓ Branch 1 taken 18 times.
✓ Branch 4 taken 18 times.
|
18 | tok = next_token(); // Quote |
2719 |
1/1✓ Branch 1 taken 18 times.
|
18 | endquote = token().type(); |
2720 | |||
2721 |
2/2✓ Branch 1 taken 18 times.
✓ Branch 4 taken 18 times.
|
18 | tok = next_token(); |
2722 | 18 | String buffer; | |
2723 | |||
2724 | auto pushbuffer = [&]() { | ||
2725 |
2/2✓ Branch 1 taken 20 times.
✓ Branch 2 taken 13 times.
|
33 | if (!buffer.empty()) { |
2726 | 20 | Constant* cst = expr->new_object<Constant>(); | |
2727 |
3/3✓ Branch 1 taken 20 times.
✓ Branch 4 taken 20 times.
✓ Branch 7 taken 20 times.
|
20 | cst->value = ConstantValue(buffer); |
2728 |
1/1✓ Branch 1 taken 20 times.
|
20 | expr->values.push_back(cst); |
2729 | 20 | buffer.clear(); | |
2730 | } | ||
2731 | 33 | }; | |
2732 | |||
2733 |
2/2✓ Branch 1 taken 115 times.
✓ Branch 2 taken 18 times.
|
133 | while (tok.type() != endquote) { |
2734 | |||
2735 |
2/2✓ Branch 1 taken 20 times.
✓ Branch 2 taken 95 times.
|
115 | if (tok.type() == '{') { |
2736 |
1/1✓ Branch 1 taken 20 times.
|
20 | char c = _lex.peekc(); |
2737 |
2/2✓ Branch 0 taken 5 times.
✓ Branch 1 taken 15 times.
|
20 | if (c == '{') { |
2738 |
1/1✓ Branch 1 taken 5 times.
|
5 | buffer.push_back('{'); |
2739 |
1/1✓ Branch 1 taken 5 times.
|
5 | buffer.push_back('{'); |
2740 | |||
2741 |
2/2✓ Branch 1 taken 5 times.
✓ Branch 4 taken 5 times.
|
5 | tok = next_token(); |
2742 |
2/2✓ Branch 1 taken 5 times.
✓ Branch 4 taken 5 times.
|
5 | tok = next_token(); |
2743 | 5 | continue; | |
2744 | } | ||
2745 | |||
2746 |
1/1✓ Branch 1 taken 15 times.
|
15 | pushbuffer(); |
2747 | // Parse FormattedValue | ||
2748 |
2/2✓ Branch 1 taken 15 times.
✓ Branch 4 taken 15 times.
|
15 | expr->values.push_back(parse_formatted_value_string(expr, depth + 1)); |
2749 |
2/2✓ Branch 1 taken 15 times.
✓ Branch 4 taken 15 times.
|
15 | tok = token(); |
2750 | 15 | continue; | |
2751 | 15 | } | |
2752 | |||
2753 |
1/1✓ Branch 2 taken 95 times.
|
95 | buffer.push_back(tok.type()); |
2754 |
2/2✓ Branch 1 taken 95 times.
✓ Branch 4 taken 95 times.
|
95 | tok = next_token(); |
2755 | } | ||
2756 |
1/1✓ Branch 1 taken 18 times.
|
18 | pushbuffer(); |
2757 | 18 | } | |
2758 | |||
2759 |
4/5✓ Branch 1 taken 18 times.
✓ Branch 4 taken 18 times.
✓ Branch 6 taken 18 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 18 times.
|
18 | end_code_loc(expr, token()); |
2760 | expect_token(endquote, true, expr, LOC); | ||
2761 | 18 | return expr; | |
2762 | 18 | } | |
2763 | |||
2764 | ExprNode* Parser::parse_formatted_value_string(Node* parent, int depth) { | ||
2765 | // {<value>(:<formatspec>)?} | ||
2766 | TRACE_START(); | ||
2767 | |||
2768 | 15 | FormattedValue* expr = parent->new_object<FormattedValue>(); | |
2769 |
4/5✓ Branch 1 taken 15 times.
✓ Branch 4 taken 15 times.
✓ Branch 6 taken 15 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 15 times.
|
15 | start_code_loc(expr, token()); |
2770 | |||
2771 | { | ||
2772 |
1/1✓ Branch 1 taken 15 times.
|
15 | SetLexerMode _(_lex, LexerMode::Default); |
2773 | expect_token('{', true, expr, LOC); | ||
2774 |
1/1✓ Branch 1 taken 15 times.
|
15 | expr->value = parse_expression(expr, depth + 1); |
2775 | 15 | } | |
2776 | |||
2777 |
1/2✓ Branch 2 taken 15 times.
✗ Branch 3 not taken.
|
15 | if (token().type() == ':') { |
2778 | 15 | next_token(); // eat ':' so we get next character | |
2779 | 15 | expr->format_spec = parse_format_spec(expr, depth); | |
2780 | } | ||
2781 | |||
2782 |
4/5✓ Branch 1 taken 15 times.
✓ Branch 4 taken 15 times.
✓ Branch 6 taken 15 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 15 times.
|
15 | end_code_loc(expr, token()); |
2783 | expect_token('}', true, expr, LOC); | ||
2784 | |||
2785 | 15 | return expr; | |
2786 | } | ||
2787 | |||
2788 | JoinedStr* Parser::parse_format_spec(Node* parent, int depth) { | ||
2789 | // [[fill]align][sign][#][0][minimumwidth][.precision][type] | ||
2790 | // https://peps.python.org/pep-3101/ | ||
2791 | TRACE_START(); | ||
2792 | |||
2793 | // str{<something>}end | ||
2794 |
1/1✓ Branch 1 taken 15 times.
|
15 | JoinedStr* expr = parent->new_object<JoinedStr>(); |
2795 |
4/5✓ Branch 1 taken 15 times.
✓ Branch 4 taken 15 times.
✓ Branch 6 taken 15 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 15 times.
|
15 | start_code_loc(expr, token()); |
2796 | |||
2797 | 15 | String buffer; | |
2798 | |||
2799 | auto pushbuffer = [&]() { | ||
2800 |
2/2✓ Branch 1 taken 15 times.
✓ Branch 2 taken 10 times.
|
25 | if (!buffer.empty()) { |
2801 | 15 | Constant* cst = expr->new_object<Constant>(); | |
2802 |
3/3✓ Branch 1 taken 15 times.
✓ Branch 4 taken 15 times.
✓ Branch 7 taken 15 times.
|
15 | cst->value = ConstantValue(buffer); |
2803 |
1/1✓ Branch 1 taken 15 times.
|
15 | expr->values.push_back(cst); |
2804 | 15 | buffer.clear(); | |
2805 | } | ||
2806 | 25 | }; | |
2807 | |||
2808 | // Get Current token | ||
2809 |
1/1✓ Branch 1 taken 15 times.
|
15 | char c = token().type(); |
2810 | 15 | bool first = true; | |
2811 |
2/2✓ Branch 0 taken 30 times.
✓ Branch 1 taken 15 times.
|
45 | while (c != '}') { |
2812 | |||
2813 |
2/2✓ Branch 0 taken 10 times.
✓ Branch 1 taken 20 times.
|
30 | if (c == '{') { |
2814 |
1/1✓ Branch 1 taken 10 times.
|
10 | pushbuffer(); |
2815 | { | ||
2816 |
1/1✓ Branch 1 taken 10 times.
|
10 | SetLexerMode _(_lex, LexerMode::Default); |
2817 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
|
10 | if (!first) { |
2818 | ✗ | next_token(); // token is now { | |
2819 | } | ||
2820 | expect_token('{', true, expr, LOC); | ||
2821 |
2/2✓ Branch 1 taken 10 times.
✓ Branch 4 taken 10 times.
|
10 | expr->values.push_back(parse_expression(expr, depth + 1)); |
2822 | 10 | } | |
2823 | |||
2824 | expect_token('}', true, expr, LOC); | ||
2825 |
1/1✓ Branch 1 taken 10 times.
|
10 | c = token().type(); |
2826 | 10 | first = true; | |
2827 | 10 | continue; | |
2828 | 10 | } | |
2829 | |||
2830 |
2/2✓ Branch 0 taken 5 times.
✓ Branch 1 taken 15 times.
|
20 | if (!first) { |
2831 |
1/1✓ Branch 1 taken 5 times.
|
5 | c = next_token().type(); |
2832 | } | ||
2833 |
1/1✓ Branch 1 taken 20 times.
|
20 | buffer.push_back(c); |
2834 |
1/1✓ Branch 1 taken 20 times.
|
20 | c = _lex.peekc(); |
2835 | 20 | first = false; | |
2836 | } | ||
2837 | |||
2838 |
1/1✓ Branch 1 taken 15 times.
|
15 | pushbuffer(); |
2839 | |||
2840 |
1/1✓ Branch 1 taken 15 times.
|
15 | next_token(); // Current token becomes '}' |
2841 | |||
2842 | { | ||
2843 |
1/1✓ Branch 1 taken 15 times.
|
15 | SetLexerMode _(_lex, LexerMode::Default); |
2844 | expect_token('}', false, expr, LOC); | ||
2845 | 15 | } | |
2846 | 15 | return expr; | |
2847 | 15 | } | |
2848 | |||
2849 | Token const& Parser::next_token() { | ||
2850 | // add current token to the line and fetch next one | ||
2851 | COZ_BEGIN("T::Lexer::next_token"); | ||
2852 | |||
2853 | // desindent are issued right after newlines | ||
2854 |
2/2✓ Branch 1 taken 19696 times.
✓ Branch 5 taken 19696 times.
|
19696 | is_empty_line = in(token().type(), tok_newline, tok_desindent, tok_indent); |
2855 | |||
2856 | 19696 | currentline.add(token()); | |
2857 | 19696 | Token const& tok = _lex.next_token(); | |
2858 | |||
2859 | COZ_PROGRESS_NAMED("Lexer::next_token"); | ||
2860 | COZ_END("T::Lexer::next_token"); | ||
2861 | 19696 | return tok; | |
2862 | } | ||
2863 | |||
2864 | } // namespace lython | ||
2865 |