From ee615b2b3b2b7b336fdd4334dba68801681c9c7b Mon Sep 17 00:00:00 2001 From: _ov4 Date: Thu, 22 Oct 2026 15:11:15 +0000 Subject: fix(parser): accept bare NEXT and read its identifier only from the same line Co-Authored-By: Claude Sonnet 5.5 --- doc/language/keyword/cpsc-keyword-for.7.md | 4 ++-- lib/Parser/ParserControlFlow.cc | 19 +++++++++---------- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/doc/language/keyword/cpsc-keyword-for.7.md b/doc/language/keyword/cpsc-keyword-for.7.md index e278cd9..0a4e5c7 100644 --- a/doc/language/keyword/cpsc-keyword-for.7.md +++ b/doc/language/keyword/cpsc-keyword-for.7.md @@ -9,12 +9,12 @@ cpsc-keyword-for, cpsc-keyword-to, cpsc-keyword-step, cpsc-keyword-next - iterat ```text FOR variable <- start TO finish [STEP increment] statements -NEXT variable +NEXT [variable] ``` # DESCRIPTION -The loop variable must already be declared INTEGER. Both endpoints are inclusive. STEP defaults to 1; use a negative value to count down. STEP is evaluated once, while the finish expression is evaluated each iteration. NEXT must name the same variable. Use a nonzero STEP. TO, STEP, and NEXT belong to this syntax. +The loop variable must already be declared INTEGER. Both endpoints are inclusive. STEP defaults to 1; use a negative value to count down. STEP is evaluated once, while the finish expression is evaluated each iteration. The variable after NEXT is optional. If present, it must be on the same line as NEXT and name the loop variable. Use a nonzero STEP. TO, STEP, and NEXT belong to this syntax. # EXAMPLE diff --git a/lib/Parser/ParserControlFlow.cc b/lib/Parser/ParserControlFlow.cc index feedf44..7caf555 100644 --- a/lib/Parser/ParserControlFlow.cc +++ b/lib/Parser/ParserControlFlow.cc @@ -124,18 +124,17 @@ std::unique_ptr Parser::ParseForStmt() { return nullptr; } getNextToken(); - - if (CurTok != tok_identifier) { - cps::sourceError(Lex.getLine(), "expected identifier after NEXT (e.g., NEXT %s)", VarName.c_str()); - return nullptr; - } - if (!sameIdentifier(Lex.IdentifierStr, VarName)) { - cps::sourceError(Lex.getLine(), "NEXT identifier '%s' does not match FOR variable '%s'", - Lex.IdentifierStr.c_str(), VarName.c_str()); - return nullptr; + // The identifier after NEXT is optional; one on the next line starts a + // new statement. + if (CurTok == tok_identifier && !StartsLine) { + if (!sameIdentifier(Lex.IdentifierStr, VarName)) { + cps::sourceError(Lex.getLine(), "NEXT identifier '%s' does not match FOR variable '%s'", + Lex.IdentifierStr.c_str(), VarName.c_str()); + return nullptr; + } + getNextToken(); } - getNextToken(); return std::make_unique(VarName, std::move(Start), std::move(End), std::move(Step), std::move(Body)); } -- cgit v1.3.1-4-g156e