aboutsummaryrefslogtreecommitdiff
path: root/lib/Parser
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Parser')
-rw-r--r--lib/Parser/Parser.cc11
-rw-r--r--lib/Parser/ParserFunction.cc9
-rw-r--r--lib/Parser/ParserType.cc15
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;