From e1fea0e3b49f3b9b3e8a317ceb1938d3d02bf0a0 Mon Sep 17 00:00:00 2001 From: _ov4 Date: Thu, 22 Oct 2026 04:05:31 +0000 Subject: refactor(parser): share the FUNCTION and PROCEDURE body tail ParseFunctionBody() scopes the prototype's pack parameters, parses the body up to ENDFUNCTION/ENDPROCEDURE, reports the same "expected ..." diagnostic and builds the FunctionDefAST for both declaration forms. Co-Authored-By: Claude Opus 5.5 --- include/cps/Parser.h | 2 ++ lib/Parser/ParserFunction.cc | 29 +++++++++++------------------ 2 files changed, 13 insertions(+), 18 deletions(-) diff --git a/include/cps/Parser.h b/include/cps/Parser.h index fbccb3c..eff25a5 100644 --- a/include/cps/Parser.h +++ b/include/cps/Parser.h @@ -93,6 +93,8 @@ class Parser { std::unique_ptr ParseFunction(const std::string &OwnerClass = {}, bool IsPublic = true, bool IsOverload = false); std::unique_ptr ParseProcedure(const std::string &OwnerClass = {}, bool IsPublic = true, bool IsOverload = false); + std::unique_ptr ParseFunctionBody( + std::unique_ptr Proto, int EndToken, const char *EndMessage, int Line); std::unique_ptr ParseExternDecl(); std::unique_ptr ParseCallStmt(); std::unique_ptr ParseReturnStmt(); diff --git a/lib/Parser/ParserFunction.cc b/lib/Parser/ParserFunction.cc index d71b16e..8f3a117 100644 --- a/lib/Parser/ParserFunction.cc +++ b/lib/Parser/ParserFunction.cc @@ -219,21 +219,7 @@ std::unique_ptr Parser::ParseFunction(const std::string &OwnerCl auto Proto = std::make_unique(Name, std::move(*Args), RetType, false, OwnerClass, IsPublic, IsOverload); Proto->setOperator(Operator); - auto SavedPacks = std::move(PackNames); - PackNames.clear(); - for (const auto &P : Proto->getParams()) if (P.IsPack) PackNames.insert(P.Name); - std::vector> Body = ParseBlock({tok_endfunction}); - PackNames = std::move(SavedPacks); - - if (CurTok != tok_endfunction) { - cps::sourceError(Lex.getLine(), "expected ENDFUNCTION"); - return nullptr; - } - getNextToken(); - - auto Def = std::make_unique(std::move(Proto), std::move(Body)); - Def->setLine(Line); - return Def; + return ParseFunctionBody(std::move(Proto), tok_endfunction, "expected ENDFUNCTION", Line); } std::unique_ptr Parser::ParseProcedure(const std::string &OwnerClass, bool IsPublic, bool IsOverload) { @@ -275,14 +261,21 @@ std::unique_ptr Parser::ParseProcedure(const std::string &OwnerC auto Proto = std::make_unique(Name, std::move(*Args), "VOID", false, OwnerClass, IsPublic, IsOverload); Proto->setOperator(Operator); + return ParseFunctionBody(std::move(Proto), tok_endprocedure, "expected ENDPROCEDURE", Line); +} + +// Shared FUNCTION/PROCEDURE tail: the body (with the prototype's pack +// parameters in scope) up to EndToken, which must be present. +std::unique_ptr Parser::ParseFunctionBody( + std::unique_ptr Proto, int EndToken, const char *EndMessage, int Line) { auto SavedPacks = std::move(PackNames); PackNames.clear(); for (const auto &P : Proto->getParams()) if (P.IsPack) PackNames.insert(P.Name); - std::vector> Body = ParseBlock({tok_endprocedure}); + std::vector> Body = ParseBlock({EndToken}); PackNames = std::move(SavedPacks); - if (CurTok != tok_endprocedure) { - cps::sourceError(Lex.getLine(), "expected ENDPROCEDURE"); + if (CurTok != EndToken) { + cps::sourceError(Lex.getLine(), "%s", EndMessage); return nullptr; } getNextToken(); -- cgit v1.3.1-4-g156e