Skip to content

Commit 690cdf3

Browse files
committed
Correctly handle EOF when the last entity is a function with a single-expression body that ends in an unnamed function
Before this, we emitted an "unexpected end of source file" in the specific case that the very last entity in a source file was a function with a single-expression body that ended in an unnamed function that also had a single-expression body that ended in an unnamed function -- I specifically don't require two `;` there, and making the second `;` optional exposes expression parsing to EOF. Solution: Check `done()` in the places that could be the end of an expression-statement, in case we consumed all the tokens already in this particular edge case.
1 parent 333ac9b commit 690cdf3

File tree

1 file changed

+6
-5
lines changed

1 file changed

+6
-5
lines changed

source/parse.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1635,7 +1635,7 @@ class parser
16351635
return {};
16361636
}
16371637

1638-
while (
1638+
while ( !done() && (
16391639
(is_postfix_operator(curr().type())
16401640
// Postfix operators must be lexically adjacent
16411641
&& curr().position().lineno == peek(-1)->position().lineno
@@ -1645,6 +1645,7 @@ class parser
16451645
curr().type() == lexeme::LeftParen ||
16461646
curr().type() == lexeme::Dot
16471647
)
1648+
)
16481649
{
16491650
// these can't be unary operators if followed by a (, identifier, or literal
16501651
if ((curr().type() == lexeme::Multiply || curr().type() == lexeme::Ampersand || curr().type() == lexeme::Tilde) &&
@@ -1773,7 +1774,7 @@ class parser
17731774
auto n = std::make_unique<Binary>();
17741775
if ( (n->expr = term()) )
17751776
{
1776-
while (true)
1777+
while (!done())
17771778
{
17781779
typename Binary::term t{};
17791780

@@ -2171,7 +2172,7 @@ class parser
21712172
auto is_found = false;
21722173
auto as_found = false;
21732174

2174-
while (curr() == "is" || curr() == "as")
2175+
while (!done() && (curr() == "is" || curr() == "as"))
21752176
{
21762177
if (curr() == "is") {
21772178
if (is_found) {
@@ -2412,7 +2413,7 @@ class parser
24122413
return {};
24132414
}
24142415

2415-
if (semicolon_required && curr().type() != lexeme::Semicolon &&
2416+
if (semicolon_required && (done() || curr().type() != lexeme::Semicolon) &&
24162417
peek(-1)->type() != lexeme::Semicolon
24172418
// this last peek(-1)-condition is a hack (? or is it just
24182419
// maybe elegant? I'm torn) so that code like
@@ -2426,7 +2427,7 @@ class parser
24262427
{
24272428
return {};
24282429
}
2429-
if (curr().type() == lexeme::Semicolon) {
2430+
if (!done() && curr().type() == lexeme::Semicolon) {
24302431
n->has_semicolon = true;
24312432
next();
24322433
}

0 commit comments

Comments
 (0)