| 6318 | } |
| 6319 | |
| 6320 | void parser:: |
| 6321 | parse_while (token& t, type& tt) |
| 6322 | { |
| 6323 | // while[!] [<val-attrs>] <value> |
| 6324 | // <line> |
| 6325 | // |
| 6326 | // while[!] [<val-attrs>] <value> |
| 6327 | // { |
| 6328 | // <block> |
| 6329 | // } |
| 6330 | |
| 6331 | string k (move (t.value)); |
| 6332 | bool neg (k.back () == '!'); |
| 6333 | |
| 6334 | // Similar to parse_for(), we will use the relex based approach. |
| 6335 | // |
| 6336 | // Note that since we need to re-evaluate the condition prior to each |
| 6337 | // iteration, we will save the condition as well. |
| 6338 | // |
| 6339 | |
| 6340 | // Parse the construct. |
| 6341 | // |
| 6342 | string cond_and_body; |
| 6343 | |
| 6344 | // Line and column of the first character to be saved. |
| 6345 | // |
| 6346 | uint64_t line (lexer_->line); |
| 6347 | uint64_t column (lexer_->column); |
| 6348 | |
| 6349 | lexer::save_guard sg (*lexer_, cond_and_body); |
| 6350 | |
| 6351 | skip_line (t, tt); // Skip the condition (the remaining part of the line). |
| 6352 | |
| 6353 | if (tt != type::newline) |
| 6354 | fail (t) << "expected newline instead of " << t << " after " << k |
| 6355 | << "-expression"; |
| 6356 | |
| 6357 | // This can be a block or a single line, similar to if-else. |
| 6358 | // |
| 6359 | bool block (next (t, tt) == type::lcbrace && peek () == type::newline); |
| 6360 | |
| 6361 | if (block) |
| 6362 | { |
| 6363 | next (t, tt); // Get newline. |
| 6364 | next (t, tt); |
| 6365 | |
| 6366 | skip_block (t, tt); |
| 6367 | sg.stop (); |
| 6368 | |
| 6369 | if (tt != type::rcbrace) |
| 6370 | fail (t) << "expected '}' instead of " << t << " at the end of " |
| 6371 | << k << "-block"; |
| 6372 | |
| 6373 | next (t, tt); // Presumably newline after '}'. |
| 6374 | next_after_newline (t, tt, '}'); // Should be on its own line. |
| 6375 | } |
| 6376 | else |
| 6377 | { |
nothing calls this directly
no test coverage detected