From 3425b95cb654f8e1adc98365a4b370aa1fff8b4d Mon Sep 17 00:00:00 2001 From: _ov4 Date: Sat, 17 Oct 2026 06:02:21 +0000 Subject: feat(classes): support ordinary member methods and this references Co-Authored-By: Claude Fable 5.1 --- lib/Parser/ParserExpression.cc | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'lib/Parser/ParserExpression.cc') diff --git a/lib/Parser/ParserExpression.cc b/lib/Parser/ParserExpression.cc index b8952a8..e9b0dcc 100644 --- a/lib/Parser/ParserExpression.cc +++ b/lib/Parser/ParserExpression.cc @@ -59,6 +59,9 @@ std::unique_ptr Parser::ParseIdentifierExpr() { std::vector Accesses; if (!ParseDesignatorSuffix(Accesses)) return nullptr; + if (CurTok == '(' && !atCaseBoundary()) + return ParseMemberCall(IdName, std::move(Accesses), Line); + // Degrade rule: shapes that existed before designators keep their nodes. if (Accesses.empty()) return std::make_unique(IdName); @@ -67,6 +70,31 @@ std::unique_ptr Parser::ParseIdentifierExpr() { return std::make_unique(IdName, std::move(Accesses), Line); } +// The final field suffix names the method; preceding suffixes form its receiver. +std::unique_ptr Parser::ParseMemberCall( + const std::string &Name, std::vector Accesses, int Line) { + if (Accesses.empty() || Accesses.back().Kind != AccessKind::Field) { + fprintf(stderr, "error: Expected a method name after '.' at line %d\n", Line); + return nullptr; + } + std::string Method = Accesses.back().FieldName; + Accesses.pop_back(); + auto Receiver = std::make_unique(Name, std::move(Accesses), Line); + std::vector> Args; + if (CurTok == '(') { + getNextToken(); + auto Parsed = ParseExprList(')', true); + if (!Parsed) return nullptr; + Args = std::move(*Parsed); + } + if (CurTok == '[' || CurTok == '.' || CurTok == '^') { + fprintf(stderr, "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); +} + // Postfix accessor chain after an identifier: '[' exprs ']' | '.' IDENT | '^' bool Parser::ParseDesignatorSuffix(std::vector &Out) { while (true) { -- cgit v1.3.1-4-g156e