diff --git a/src/Parser/Parser.cpp b/src/Parser/Parser.cpp index c970789..21877eb 100644 --- a/src/Parser/Parser.cpp +++ b/src/Parser/Parser.cpp @@ -49,7 +49,6 @@ namespace MalachScript::Parser { const auto* current = _currentToken; auto start = current->GetSpan().GetStart(); bool lookingForClass = true; - bool encounteredError = false; while (lookingForClass) { switch (current->GetKind()) { case LexTokenKind::SharedKeyword: break; @@ -91,8 +90,7 @@ namespace MalachScript::Parser { inherits.push_back(id); PROGRESS_TOKEN(current); } - if (!encounteredError && current->GetKind() != LexTokenKind::OpenCurlyParenthesisSymbol) { - encounteredError = true; + if (current->GetKind() != LexTokenKind::OpenCurlyParenthesisSymbol) { LogError(Diagnostics::DiagnosticType::UnexpectedToken, current->GetSpan()); } // Intentionally don't break so we continue into the inner body statement. @@ -105,7 +103,7 @@ namespace MalachScript::Parser { PROGRESS_TOKEN(current); break; } - const ParsedStatement* statement; + const ParsedStatement* statement = nullptr; // TODO: Sort by if (!ParseVirtProp(statement) && !ParseFunc(statement) && !ParseVar(statement) && !ParseFuncDef(statement)) { @@ -154,7 +152,7 @@ namespace MalachScript::Parser { if (!ParseIdentifier(identifier, _currentToken)) { LogError(Diagnostics::DiagnosticType::UnexpectedToken, _currentToken->GetSpan()); } - auto script = ParseScript(); + const auto *script = ParseScript(); auto end = _currentToken->GetSpan().GetEnd(); PROGRESS_TOKEN(_currentToken); out = new ParsedNamespaceStatement(TextSpan(start, end), identifier, script); @@ -214,7 +212,7 @@ namespace MalachScript::Parser { PROGRESS_TOKEN(_currentToken); } bool lookingForFuncAttr = true; - FuncAttr funcAttr; + FuncAttr funcAttr = FuncAttr::None; while (lookingForFuncAttr) { switch (_currentToken->GetKind()) { case LexTokenKind::OverrideKeyword: @@ -325,7 +323,8 @@ namespace MalachScript::Parser { } auto start = currentToken->GetSpan().GetStart(); PROGRESS_TOKEN(currentToken); - std::vector parameters; + std::vector parameters; + if (currentToken->GetKind() == LexTokenKind::VoidKeyword) { PROGRESS_TOKEN(currentToken); if (currentToken->GetKind() != LexTokenKind::CloseParenthesisSymbol) { @@ -334,20 +333,28 @@ namespace MalachScript::Parser { PROGRESS_TOKEN(currentToken); out = new ParsedParamListStatement(TextSpan(start, currentToken->GetSpan().GetEnd()), parameters); return true; - } else if (currentToken->GetKind() == LexTokenKind::CloseParenthesisSymbol) { + } if (currentToken->GetKind() == LexTokenKind::CloseParenthesisSymbol) { out = new ParsedParamListStatement(TextSpan(start, currentToken->GetSpan().GetEnd()), parameters); PROGRESS_TOKEN(currentToken); return true; } while (true) { - parameters.emplace_back(); - auto& parameter = parameters.at(parameters.size() - 1); - if (!ParseType((const ParsedStatement*&)parameter.GetTypeStatement(), currentToken)) { + const ParsedStatement* typeStatement = nullptr; + TypeMod typeMod = TypeMod::None; + Identifier identifier; + const ParsedExpression* defaultExpression = nullptr; + + if (!ParseType(typeStatement, currentToken)) { LogError(Diagnostics::DiagnosticType::UnexpectedToken, currentToken->GetSpan()); } - ParseTypeMod(parameter.GetTypeMod(), currentToken); - ParseIdentifier(parameter.GetIdentifier(), currentToken); + ParseTypeMod(typeMod, currentToken); + ParseIdentifier(identifier, currentToken); PROGRESS_TOKEN(currentToken); + // TODO: Default expression + + parameters.push_back(new ParsedParamListStatement::ParsedParameter( + dynamic_cast(typeStatement), typeMod, identifier, defaultExpression)); + if (currentToken->GetKind() != LexTokenKind::CommaSymbol) { break; } diff --git a/src/Parser/Statements/ParsedStatement.hpp b/src/Parser/Statements/ParsedStatement.hpp index 15b874d..39376d9 100644 --- a/src/Parser/Statements/ParsedStatement.hpp +++ b/src/Parser/Statements/ParsedStatement.hpp @@ -105,16 +105,23 @@ namespace MalachScript::Parser { public: class ParsedParameter { private: - const ParsedTypeStatement* _typeStatement = nullptr; + std::unique_ptr _typeStatement = nullptr; TypeMod _typeMod = TypeMod::None; Identifier _identifier; - const ParsedExpression* _defaultExpression = nullptr; + std::unique_ptr _defaultExpression = nullptr; public: - ParsedParameter(){}; + ParsedParameter(const ParsedTypeStatement* typeStatement, TypeMod typeMod, const Identifier& identifier, + const ParsedExpression* defaultExpression) + : _typeStatement(typeStatement), _typeMod(typeMod), _identifier(identifier), + _defaultExpression(defaultExpression){}; - [[nodiscard]] const ParsedTypeStatement*& GetTypeStatement() noexcept { return _typeStatement; } - [[nodiscard]] const ParsedTypeStatement* GetTypeStatement() const noexcept { return _typeStatement; } + [[nodiscard]] std::unique_ptr& GetTypeStatement() noexcept { + return _typeStatement; + } + [[nodiscard]] const std::unique_ptr& GetTypeStatement() const noexcept { + return _typeStatement; + } [[nodiscard]] TypeMod& GetTypeMod() noexcept { return _typeMod; } [[nodiscard]] const TypeMod& GetTypeMod() const noexcept { return _typeMod; } @@ -122,18 +129,28 @@ namespace MalachScript::Parser { [[nodiscard]] Identifier& GetIdentifier() noexcept { return _identifier; } [[nodiscard]] const Identifier& GetIdentifier() const noexcept { return _identifier; } - [[nodiscard]] const ParsedExpression*& GetDefaultExpression() noexcept { return _defaultExpression; } - [[nodiscard]] const ParsedExpression* GetDefaultExpression() const noexcept { return _defaultExpression; } + [[nodiscard]] std::unique_ptr& GetDefaultExpression() noexcept { + return _defaultExpression; + } + [[nodiscard]] const std::unique_ptr& GetDefaultExpression() const noexcept { + return _defaultExpression; + } }; private: - std::vector _parameters; + std::vector> _parameters; public: - ParsedParamListStatement(TextSpan span, std::vector parameters) - : ParsedStatementImpl(span), _parameters(std::move(parameters)){}; + ParsedParamListStatement(TextSpan span, const std::vector& parameters) + : ParsedStatementImpl(span), _parameters(parameters.size()) { + for (size_t i = 0; i < parameters.size(); i++) { + _parameters[i] = std::unique_ptr(parameters[i]); + } + }; - [[nodiscard]] const std::vector& GetParameters() const noexcept { return _parameters; } + [[nodiscard]] const std::vector>& GetParameters() const noexcept { + return _parameters; + } }; class ParsedFuncStatement : public ParsedStatementImpl { @@ -145,7 +162,7 @@ namespace MalachScript::Parser { bool _returnsReference; Identifier _identifier; std::unique_ptr _paramList; - bool isConst; + bool _isConst; FuncAttr _funcAttr; std::unique_ptr _statBlock; @@ -156,7 +173,7 @@ namespace MalachScript::Parser { const ParsedStatement* statBlock) : ParsedStatementImpl(span), _isShared(isShared), _isExternal(isExternal), _access(access), _type(type), _returnsReference(returnsReference), _identifier(identifier), - _paramList(paramList), isConst(isConst), _funcAttr(funcAttr), _statBlock(statBlock) {} + _paramList(paramList), _isConst(isConst), _funcAttr(funcAttr), _statBlock(statBlock) {} [[nodiscard]] inline bool IsShared() const noexcept { return _isShared; } [[nodiscard]] inline bool IsExternal() const noexcept { return _isExternal; } @@ -169,7 +186,7 @@ namespace MalachScript::Parser { [[nodiscard]] inline const std::unique_ptr& GetParamList() const noexcept { return _paramList; } - [[nodiscard]] inline bool IsConst() const noexcept { return isConst; } + [[nodiscard]] inline bool IsConst() const noexcept { return _isConst; } [[nodiscard]] inline FuncAttr GetFuncAttr() const noexcept { return _funcAttr; } [[nodiscard]] inline const std::unique_ptr& GetStatBlock() const noexcept { return _statBlock; diff --git a/tests/ParserTests/FunctionTests.cpp b/tests/ParserTests/FunctionTests.cpp index b834e9c..f29e06a 100644 --- a/tests/ParserTests/FunctionTests.cpp +++ b/tests/ParserTests/FunctionTests.cpp @@ -129,7 +129,7 @@ PARSER_TEST("Parse scoped function with parameters without body.", auto paramList = (const MalachScript::Parser::ParsedParamListStatement*)funcStat->GetParamList().get(); CHECK(paramList->GetParameters().size() == 2); - auto& par1 = paramList->GetParameters()[0]; + auto& par1 = *paramList->GetParameters()[0]; CHECK_FALSE(par1.GetTypeStatement()->IsConst()); CHECK_FALSE(par1.GetTypeStatement()->IsArray()); CHECK_FALSE(par1.GetTypeStatement()->IsHandle()); @@ -139,7 +139,7 @@ PARSER_TEST("Parse scoped function with parameters without body.", CHECK(par1.GetIdentifier().GetString() == u8"par1"); CHECK(par1.GetDefaultExpression() == nullptr); - auto& par2 = paramList->GetParameters()[1]; + auto& par2 = *paramList->GetParameters()[1]; CHECK_FALSE(par2.GetTypeStatement()->IsConst()); CHECK_FALSE(par2.GetTypeStatement()->IsArray()); CHECK_FALSE(par2.GetTypeStatement()->IsHandle()); @@ -200,7 +200,7 @@ PARSER_TEST("Parse scoped function with reference parameters without body.", auto paramList = (const MalachScript::Parser::ParsedParamListStatement*)funcStat->GetParamList().get(); CHECK(paramList->GetParameters().size() == 2); - auto& par1 = paramList->GetParameters()[0]; + auto& par1 = *paramList->GetParameters()[0]; CHECK_FALSE(par1.GetTypeStatement()->IsConst()); CHECK_FALSE(par1.GetTypeStatement()->IsArray()); CHECK_FALSE(par1.GetTypeStatement()->IsHandle()); @@ -210,7 +210,7 @@ PARSER_TEST("Parse scoped function with reference parameters without body.", CHECK(par1.GetIdentifier().GetString() == u8"par1"); CHECK(par1.GetDefaultExpression() == nullptr); - auto& par2 = paramList->GetParameters()[1]; + auto& par2 = *paramList->GetParameters()[1]; CHECK_FALSE(par2.GetTypeStatement()->IsConst()); CHECK_FALSE(par2.GetTypeStatement()->IsArray()); CHECK_FALSE(par2.GetTypeStatement()->IsHandle());