From 345e3d419eafb0e234aecb4a33f37efe2afbbf53 Mon Sep 17 00:00:00 2001 From: _ov4 Date: Sun, 18 Oct 2026 08:07:50 +0000 Subject: feat(classes): add copy constructors and statement-scoped temporaries Co-Authored-By: Claude Opus 5.5 --- lib/Parser/ParserExpression.cc | 38 +++++++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) (limited to 'lib/Parser/ParserExpression.cc') diff --git a/lib/Parser/ParserExpression.cc b/lib/Parser/ParserExpression.cc index 6cde5bf..7558c86 100644 --- a/lib/Parser/ParserExpression.cc +++ b/lib/Parser/ParserExpression.cc @@ -56,12 +56,12 @@ std::unique_ptr Parser::ParseIdentifierExpr() { getNextToken(); auto Args = ParseExprList(')', true); if (!Args) return nullptr; - if (CurTok == '[' || CurTok == '.' || CurTok == '^') { + if (CurTok == '[' || CurTok == '^') { cps::sourceDiagnostic(Lex.getLine(), "error: record/array/pointer access on a function result is not supported at line %d\n", Lex.getLine()); return nullptr; } - return std::make_unique(IdName, std::move(*Args), Line); + return ParseResultMethods(std::make_unique(IdName, std::move(*Args), Line), Line); } std::vector Accesses; @@ -95,12 +95,13 @@ std::unique_ptr Parser::ParseMemberCall( if (!Parsed) return nullptr; Args = std::move(*Parsed); } - if (CurTok == '[' || CurTok == '.' || CurTok == '^') { + if (CurTok == '[' || CurTok == '^') { cps::sourceDiagnostic(Lex.getLine(), "error: record/array/pointer access on a function result is not supported at line %d\n", Lex.getLine()); return nullptr; } - return std::make_unique(std::move(Receiver), Method, std::move(Args), Line); + auto Result = ParseResultMethods(std::make_unique(std::move(Receiver), Method, std::move(Args), Line), Line); + return std::unique_ptr(static_cast(Result.release())); } // Postfix accessor chain after an identifier: '[' exprs ']' | '.' IDENT | '^' @@ -173,11 +174,38 @@ std::unique_ptr Parser::ParseParenExpr() { return V; } +std::unique_ptr Parser::ParseResultMethods(std::unique_ptr Expr, int Line) { + while (CurTok == '.' && !atCaseBoundary()) { + getNextToken(); + std::string Name; + if (CurTok == tok_operator) { + int Op; + Name = ParseOperatorName(Op); + if (Name.empty()) return nullptr; + } else if (CurTok == tok_identifier || CurTok == tok_delete) { + Name = CurTok == tok_delete ? "DELETE" : Lex.IdentifierStr; + getNextToken(); + } else { + sourceDiagnostic(Lex.getLine(), "error: Expected method name at line %d\n", Lex.getLine()); + return nullptr; + } + if (CurTok != '(') { + sourceDiagnostic(Lex.getLine(), "error: Expected '(' after method name at line %d\n", Lex.getLine()); + return nullptr; + } + getNextToken(); + auto Args = ParseExprList(')', true); + if (!Args) return nullptr; + Expr = std::make_unique(std::move(Expr), Name, std::move(*Args), Line); + } + return Expr; +} + std::unique_ptr Parser::ParsePrimary() { int Line = Lex.getLine(); auto Expr = ParsePrimaryImpl(); if (Expr && !Expr->getLine()) Expr->setLine(Line); - return Expr; + return Expr ? ParseResultMethods(std::move(Expr), Line) : nullptr; } std::unique_ptr Parser::ParsePrimaryImpl() { -- cgit v1.3.1-4-g156e