diff options
Diffstat (limited to 'lib/Parser')
| -rw-r--r-- | lib/Parser/Parser.cc | 11 | ||||
| -rw-r--r-- | lib/Parser/ParserFunction.cc | 9 | ||||
| -rw-r--r-- | lib/Parser/ParserType.cc | 15 |
3 files changed, 28 insertions, 7 deletions
diff --git a/lib/Parser/Parser.cc b/lib/Parser/Parser.cc index ad2e408..227e309 100644 --- a/lib/Parser/Parser.cc +++ b/lib/Parser/Parser.cc @@ -50,7 +50,7 @@ void Parser::syncToStatementStart() { case tok_delete: case tok_constant: case tok_declare: case tok_identifier: case tok_operator: case tok_input: case tok_output: case tok_case: case tok_endcase: case tok_otherwise: case tok_if: case tok_while: case tok_repeat: case tok_for: - case tok_template: case tok_overload: case tok_function: case tok_procedure: case tok_call: case tok_return: + case tok_template: case tok_implicit: case tok_overload: case tok_function: case tok_procedure: case tok_call: case tok_return: case tok_else: case tok_endif: case tok_endwhile: case tok_until: case tok_next: case tok_endfunction: case tok_endprocedure: case tok_openfile: case tok_readfile: case tok_writefile: case tok_closefile: @@ -157,9 +157,16 @@ std::unique_ptr<StmtAST> Parser::ParseStatementImpl() { else if (CurTok == tok_for) { return ParseForStmt(); } - else if (CurTok == tok_overload) { + else if (CurTok == tok_implicit || CurTok == tok_overload) { int Line = Lex.getLine(); + bool Overload = CurTok == tok_overload; getNextToken(); + bool Implicit = !Overload || CurTok == tok_implicit; + if (Overload && Implicit) getNextToken(); + if (Implicit) { + cps::sourceError(Line, "IMPLICIT is only allowed on a CLASS constructor NEW"); + return nullptr; + } if (CurTok == tok_function) return ParseFunction({}, true, true); if (CurTok == tok_procedure) return ParseProcedure({}, true, true); cps::sourceError(Line, "OVERLOAD must be followed by FUNCTION or PROCEDURE"); diff --git a/lib/Parser/ParserFunction.cc b/lib/Parser/ParserFunction.cc index 2f80c42..27be388 100644 --- a/lib/Parser/ParserFunction.cc +++ b/lib/Parser/ParserFunction.cc @@ -233,7 +233,7 @@ std::unique_ptr<FunctionDefAST> Parser::ParseFunction(const std::string &OwnerCl return Def; } -std::unique_ptr<FunctionDefAST> Parser::ParseProcedure(const std::string &OwnerClass, bool IsPublic, bool IsOverload) { +std::unique_ptr<FunctionDefAST> Parser::ParseProcedure(const std::string &OwnerClass, bool IsPublic, bool IsOverload, bool IsImplicit) { int Line = Lex.getLine(); getNextToken(); if (CurTok != tok_identifier && CurTok != tok_new && CurTok != tok_delete && CurTok != tok_operator) { @@ -265,12 +265,19 @@ std::unique_ptr<FunctionDefAST> Parser::ParseProcedure(const std::string &OwnerC auto Args = ParsePrototypeArgs(/*AllowByRef=*/true); if (!Args) return nullptr; + if (IsImplicit) { + for (const auto &P : *Args) if (P.IsPack) { + cps::sourceError(Line, "IMPLICIT constructor parameters cannot be packs"); + return nullptr; + } + } if (sameIdentifier(Name, "DELETE") && !Args->empty()) { cps::sourceError(Line, "destructor DELETE must have no parameters"); return nullptr; } auto Proto = std::make_unique<PrototypeAST>(Name, std::move(*Args), "VOID", false, OwnerClass, IsPublic, IsOverload); Proto->setOperator(Operator); + Proto->setImplicit(IsImplicit); return ParseFunctionBody(std::move(Proto), tok_endprocedure, "expected ENDPROCEDURE", Line); } diff --git a/lib/Parser/ParserType.cc b/lib/Parser/ParserType.cc index 976d165..df1fc8f 100644 --- a/lib/Parser/ParserType.cc +++ b/lib/Parser/ParserType.cc @@ -116,7 +116,7 @@ std::optional<std::vector<RecordFieldDecl>> Parser::ParseRecordBody( const char *EndKeyword = IsClass ? "ENDCLASS" : "ENDTYPE"; auto AtField = [&] { return IsClass ? (CurTok == tok_public || CurTok == tok_private || CurTok == tok_identifier || - CurTok == tok_overload || CurTok == tok_function || CurTok == tok_procedure) + CurTok == tok_implicit || CurTok == tok_overload || CurTok == tok_function || CurTok == tok_procedure) : CurTok == tok_declare; }; std::vector<RecordFieldDecl> Fields; @@ -135,18 +135,25 @@ std::optional<std::vector<RecordFieldDecl>> Parser::ParseRecordBody( // Class fields default to public, like record fields. bool IsPublic = CurTok != tok_private; if (IsClass && (CurTok == tok_public || CurTok == tok_private) && - (Lex.peekToken() == tok_overload || Lex.peekToken() == tok_function || Lex.peekToken() == tok_procedure)) + (Lex.peekToken() == tok_implicit || Lex.peekToken() == tok_overload || Lex.peekToken() == tok_function || Lex.peekToken() == tok_procedure)) getNextToken(); - if (IsClass && (CurTok == tok_overload || CurTok == tok_function || CurTok == tok_procedure)) { + if (IsClass && (CurTok == tok_implicit || CurTok == tok_overload || CurTok == tok_function || CurTok == tok_procedure)) { bool IsOverload = CurTok == tok_overload; if (IsOverload) getNextToken(); + bool IsImplicit = CurTok == tok_implicit; + if (IsImplicit) getNextToken(); + if (IsImplicit && CurTok != tok_procedure) { + cps::sourceError(Lex.getLine(), "IMPLICIT requires PROCEDURE NEW"); + HadFieldError = true; + continue; + } if (CurTok != tok_function && CurTok != tok_procedure) { cps::sourceError(Lex.getLine(), "OVERLOAD must be followed by FUNCTION or PROCEDURE"); HadFieldError = true; continue; } auto Method = CurTok == tok_function ? ParseFunction(Name, IsPublic, IsOverload) - : ParseProcedure(Name, IsPublic, IsOverload); + : ParseProcedure(Name, IsPublic, IsOverload, IsImplicit); if (Method && Methods) { Methods->push_back(std::move(Method)); continue; |
