From d603a3bab5ee07e3fe8665a7dce8c80cb391ca08 Mon Sep 17 00:00:00 2001 From: _ov4 Date: Thu, 22 Oct 2026 03:42:49 +0000 Subject: refactor(parser): share callee-name parsing and make operator out-param optional ParseOperatorName() takes an optional int * so callers that ignore the operator token no longer declare a dummy. The identical identifier-or- OPERATOR prologues of assignment, identifier-expression and CALL parsing move into ParseCalleeName(). Co-Authored-By: Claude Opus 5.5 --- include/cps/Parser.h | 3 ++- lib/Parser/Parser.cc | 9 +-------- lib/Parser/ParserExpression.cc | 15 +++------------ lib/Parser/ParserFunction.cc | 29 +++++++++++++++++------------ 4 files changed, 23 insertions(+), 33 deletions(-) diff --git a/include/cps/Parser.h b/include/cps/Parser.h index 39adfd1..9bf8afb 100644 --- a/include/cps/Parser.h +++ b/include/cps/Parser.h @@ -46,7 +46,8 @@ class Parser { std::unique_ptr ParseNumberExpr(); std::unique_ptr ParseIdentifierExpr(); - std::string ParseOperatorName(int &Op); + std::string ParseOperatorName(int *Op = nullptr); + bool ParseCalleeName(std::string &Name); std::unique_ptr ParseParenExpr(); std::unique_ptr ParseMemberCall( const std::string &Name, std::vector Accesses, int Line); diff --git a/lib/Parser/Parser.cc b/lib/Parser/Parser.cc index 8b1c519..b81bf55 100644 --- a/lib/Parser/Parser.cc +++ b/lib/Parser/Parser.cc @@ -285,14 +285,7 @@ std::unique_ptr Parser::ParseStatementImpl() { std::unique_ptr Parser::ParseAssignStmt() { int Line = Lex.getLine(); std::string Name; - if (CurTok == tok_operator) { - int Op; - Name = ParseOperatorName(Op); - if (Name.empty()) return nullptr; - } else { - Name = Lex.IdentifierStr; - getNextToken(); - } + if (!ParseCalleeName(Name)) return nullptr; std::vector TemplateArgs; if (CurTok == '<') { diff --git a/lib/Parser/ParserExpression.cc b/lib/Parser/ParserExpression.cc index 25752b8..6ed3f1c 100644 --- a/lib/Parser/ParserExpression.cc +++ b/lib/Parser/ParserExpression.cc @@ -74,14 +74,7 @@ bool Parser::isTemplateCall() { std::unique_ptr Parser::ParseIdentifierExpr() { int Line = Lex.getLine(); std::string IdName; - if (CurTok == tok_operator) { - int Op; - IdName = ParseOperatorName(Op); - if (IdName.empty()) return nullptr; - } else { - IdName = Lex.IdentifierStr; - getNextToken(); - } + if (!ParseCalleeName(IdName)) return nullptr; if (PackNames.count(IdName)) { if (CurTok != tok_ellipsis) { @@ -173,8 +166,7 @@ bool Parser::ParseDesignatorSuffix(std::vector &Out) { DesignatorAccess A; A.Kind = AccessKind::Field; if (CurTok == tok_operator) { - int Op; - A.FieldName = ParseOperatorName(Op); + A.FieldName = ParseOperatorName(); if (A.FieldName.empty()) return false; } else { A.FieldName = CurTok == tok_new ? "NEW" : CurTok == tok_delete ? "DELETE" : Lex.IdentifierStr; @@ -227,8 +219,7 @@ std::unique_ptr Parser::ParseResultMethods(std::unique_ptr Exp getNextToken(); std::string Name; if (CurTok == tok_operator) { - int Op; - Name = ParseOperatorName(Op); + Name = ParseOperatorName(); if (Name.empty()) return nullptr; } else if (CurTok == tok_identifier || CurTok == tok_delete) { Name = CurTok == tok_delete ? "DELETE" : Lex.IdentifierStr; diff --git a/lib/Parser/ParserFunction.cc b/lib/Parser/ParserFunction.cc index f5ebee1..d71b16e 100644 --- a/lib/Parser/ParserFunction.cc +++ b/lib/Parser/ParserFunction.cc @@ -141,9 +141,10 @@ std::optional> Parser::ParsePrototypeArgs(bool AllowByRef return Params; } -std::string Parser::ParseOperatorName(int &Op) { +std::string Parser::ParseOperatorName(int *OpOut) { getNextToken(); // OPERATOR - Op = CurTok; + int Op = CurTok; + if (OpOut) *OpOut = Op; if (operatorSpelling(Op).empty()) { sourceError(Lex.getLine(), "Expected a supported operator after OPERATOR"); getNextToken(); @@ -157,6 +158,17 @@ std::string Parser::ParseOperatorName(int &Op) { return operatorName(Op); } +// A callee is an identifier or OPERATOR ; false means a diagnosed failure. +bool Parser::ParseCalleeName(std::string &Name) { + if (CurTok == tok_operator) { + Name = ParseOperatorName(); + return !Name.empty(); + } + Name = Lex.IdentifierStr; + getNextToken(); + return true; +} + std::unique_ptr Parser::ParseFunction(const std::string &OwnerClass, bool IsPublic, bool IsOverload) { int Line = Lex.getLine(); getNextToken(); @@ -176,7 +188,7 @@ std::unique_ptr Parser::ParseFunction(const std::string &OwnerCl int Operator = 0; std::string Name; if (CurTok == tok_operator) { - Name = ParseOperatorName(Operator); + Name = ParseOperatorName(&Operator); if (Name.empty()) return nullptr; if (!IsOverload) { sourceError(Line, "An operator function must be declared OVERLOAD"); @@ -236,7 +248,7 @@ std::unique_ptr Parser::ParseProcedure(const std::string &OwnerC bool IsOperator = CurTok == tok_operator; std::string OperatorName; if (IsOperator) { - OperatorName = ParseOperatorName(Operator); + OperatorName = ParseOperatorName(&Operator); if (OperatorName.empty()) return nullptr; if (Operator != tok_assign || OwnerClass.empty() || !IsOverload) { sourceError(Line, "Assignment operator must be an OVERLOAD member PROCEDURE"); @@ -376,14 +388,7 @@ std::unique_ptr Parser::ParseCallStmt() { } std::string Callee; - if (CurTok == tok_operator) { - int Op; - Callee = ParseOperatorName(Op); - if (Callee.empty()) return nullptr; - } else { - Callee = Lex.IdentifierStr; - getNextToken(); - } + if (!ParseCalleeName(Callee)) return nullptr; std::vector TemplateArgs; if (CurTok == '<') { -- cgit v1.3.1-4-g156e