diff options
Diffstat (limited to 'lib/Parser')
| -rw-r--r-- | lib/Parser/Parser.cc | 6 | ||||
| -rw-r--r-- | lib/Parser/ParserExpression.cc | 38 | ||||
| -rw-r--r-- | lib/Parser/ParserFunction.cc | 6 |
3 files changed, 45 insertions, 5 deletions
diff --git a/lib/Parser/Parser.cc b/lib/Parser/Parser.cc index afe0e80..48f4df4 100644 --- a/lib/Parser/Parser.cc +++ b/lib/Parser/Parser.cc @@ -299,6 +299,12 @@ std::unique_ptr<StmtAST> Parser::ParseAssignStmt() { getNextToken(); auto Args = ParseExprList(')', true); if (!Args) return nullptr; + if (CurTok == '.') { + auto Result = ParseResultMethods(std::make_unique<CallExprAST>(Name, std::move(*Args), Line), Line); + if (!Result) return nullptr; + return std::make_unique<MemberCallStmtAST>( + std::unique_ptr<MemberCallExprAST>(static_cast<MemberCallExprAST *>(Result.release()))); + } return std::make_unique<CallStmtAST>(Name, std::move(*Args), Line); } 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<ExprAST> 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<CallExprAST>(IdName, std::move(*Args), Line); + return ParseResultMethods(std::make_unique<CallExprAST>(IdName, std::move(*Args), Line), Line); } std::vector<DesignatorAccess> Accesses; @@ -95,12 +95,13 @@ std::unique_ptr<MemberCallExprAST> 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<MemberCallExprAST>(std::move(Receiver), Method, std::move(Args), Line); + auto Result = ParseResultMethods(std::make_unique<MemberCallExprAST>(std::move(Receiver), Method, std::move(Args), Line), Line); + return std::unique_ptr<MemberCallExprAST>(static_cast<MemberCallExprAST *>(Result.release())); } // Postfix accessor chain after an identifier: '[' exprs ']' | '.' IDENT | '^' @@ -173,11 +174,38 @@ std::unique_ptr<ExprAST> Parser::ParseParenExpr() { return V; } +std::unique_ptr<ExprAST> Parser::ParseResultMethods(std::unique_ptr<ExprAST> 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<MemberCallExprAST>(std::move(Expr), Name, std::move(*Args), Line); + } + return Expr; +} + std::unique_ptr<ExprAST> 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<ExprAST> Parser::ParsePrimaryImpl() { diff --git a/lib/Parser/ParserFunction.cc b/lib/Parser/ParserFunction.cc index dfb689a..65e0b85 100644 --- a/lib/Parser/ParserFunction.cc +++ b/lib/Parser/ParserFunction.cc @@ -374,6 +374,12 @@ std::unique_ptr<StmtAST> Parser::ParseCallStmt() { Args = std::move(*Parsed); } + if (CurTok == '.') { + auto Result = ParseResultMethods(std::make_unique<CallExprAST>(Callee, std::move(Args), Line), Line); + if (!Result) return nullptr; + return std::make_unique<MemberCallStmtAST>( + std::unique_ptr<MemberCallExprAST>(static_cast<MemberCallExprAST *>(Result.release()))); + } return std::make_unique<CallStmtAST>(Callee, std::move(Args), Line); } |
