From ad8a0ce1b432c21914c5b65118840888c6889556 Mon Sep 17 00:00:00 2001 From: Deukhoofd Date: Sat, 10 Oct 2020 16:20:56 +0200 Subject: [PATCH] Fixed issue with TypeMod. --- src/Parser/Parser.cpp | 16 +++---- src/Parser/Parser.hpp | 2 +- tests/ParserTests/FunctionTests.cpp | 71 +++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+), 9 deletions(-) diff --git a/src/Parser/Parser.cpp b/src/Parser/Parser.cpp index 912604a..8b60db8 100644 --- a/src/Parser/Parser.cpp +++ b/src/Parser/Parser.cpp @@ -345,7 +345,7 @@ namespace MalachScript::Parser { if (!ParseType((const ParsedStatement*&)parameter.GetTypeStatement(), currentToken)) { LogError(Diagnostics::DiagnosticType::UnexpectedToken, currentToken->GetSpan()); } - ParseTypeMod(parameter.GetTypeMod()); + ParseTypeMod(parameter.GetTypeMod(), currentToken); ParseIdentifier(parameter.GetIdentifier(), currentToken); PROGRESS_TOKEN(currentToken); if (currentToken->GetKind() != LexTokenKind::CommaSymbol) { @@ -402,23 +402,23 @@ namespace MalachScript::Parser { default: return false; } } - bool Parser::ParseTypeMod(TypeMod& typeMod) { - if (_currentToken->GetKind() != LexTokenKind::AmpersandSymbol) { + bool Parser::ParseTypeMod(TypeMod& typeMod, const LexToken*& currentToken) { + if (currentToken->GetKind() != LexTokenKind::AmpersandSymbol) { return false; } - PROGRESS_TOKEN(_currentToken); - switch (_currentToken->GetKind()) { + PROGRESS_TOKEN(currentToken); + switch (currentToken->GetKind()) { case LexTokenKind::InKeyword: typeMod = TypeMod::RefIn; - PROGRESS_TOKEN(_currentToken); + PROGRESS_TOKEN(currentToken); return true; case LexTokenKind::OutKeyword: typeMod = TypeMod::RefOut; - PROGRESS_TOKEN(_currentToken); + PROGRESS_TOKEN(currentToken); return true; case LexTokenKind::InoutKeyword: typeMod = TypeMod::RefInOut; - PROGRESS_TOKEN(_currentToken); + PROGRESS_TOKEN(currentToken); return true; default: typeMod = TypeMod::RefInOut; return true; } diff --git a/src/Parser/Parser.hpp b/src/Parser/Parser.hpp index 9dcc691..a90eb7a 100644 --- a/src/Parser/Parser.hpp +++ b/src/Parser/Parser.hpp @@ -29,7 +29,7 @@ namespace MalachScript::Parser { bool ParseType(const ParsedStatement*& out, const LexToken*& currentToken); bool ParseScope(std::vector& out, const LexToken*& currentToken); bool ParseParamList(const ParsedStatement*& out, const LexToken*& currentToken); - bool ParseTypeMod(TypeMod& typeMod); + bool ParseTypeMod(TypeMod& typeMod, const LexToken*& currentToken); bool ParseDataType(Identifier& out, const LexToken*& currentToken); bool ParseVirtProp(const ParsedStatement*& out); diff --git a/tests/ParserTests/FunctionTests.cpp b/tests/ParserTests/FunctionTests.cpp index 42cff1c..b834e9c 100644 --- a/tests/ParserTests/FunctionTests.cpp +++ b/tests/ParserTests/FunctionTests.cpp @@ -153,3 +153,74 @@ PARSER_TEST("Parse scoped function with parameters without body.", CHECK(funcStat->GetFuncAttr() == MalachScript::FuncAttr::None); CHECK(funcStat->GetStatBlock() == nullptr); }) + +PARSER_TEST("Parse scoped function with reference parameters without body.", + PARSER_TEST_TOKENS(new Parser::IdentifierToken(TextSpan(0, 0), u8"foo"), + new Parser::LexTokenImpl(TextSpan(0, 0)), + new Parser::IdentifierToken(TextSpan(0, 0), u8"bar"), + new Parser::LexTokenImpl(TextSpan(0, 0)), + new Parser::IdentifierToken(TextSpan(0, 0), u8"baz"), + new Parser::LexTokenImpl(TextSpan(0, 0)), + new Parser::IdentifierToken(TextSpan(0, 0), u8"foobar"), + new Parser::LexTokenImpl(TextSpan(0, 0)), + + new Parser::LexTokenImpl(TextSpan(0, 0)), + new Parser::LexTokenImpl(TextSpan(0, 0)), + new Parser::LexTokenImpl(TextSpan(0, 0)), + new Parser::LexTokenImpl(TextSpan(0, 0)), + new Parser::IdentifierToken(TextSpan(0, 0), u8"par1"), + + new Parser::LexTokenImpl(TextSpan(0, 0)), + + new Parser::LexTokenImpl(TextSpan(0, 0)), + new Parser::LexTokenImpl(TextSpan(0, 0)), + new Parser::LexTokenImpl(TextSpan(0, 0)), + new Parser::LexTokenImpl(TextSpan(0, 0)), + new Parser::IdentifierToken(TextSpan(0, 0), u8"par2"), + + new Parser::LexTokenImpl(TextSpan(0, 0)), + new Parser::LexTokenImpl(TextSpan(0, 0))), + { + REQUIRE(script->GetStatements().size() == 1); + REQUIRE(script->GetStatements()[0].get()->GetKind() == Parser::ParsedStatementKind::Func); + auto funcStat = (const MalachScript::Parser::ParsedFuncStatement*)script->GetStatements()[0].get(); + CHECK_FALSE(funcStat->IsShared()); + CHECK_FALSE(funcStat->IsExternal()); + CHECK(funcStat->GetAccess() == MalachScript::AccessModifier::Public); + auto type = (const MalachScript::Parser::ParsedTypeStatement*)funcStat->GetTypeStatement().get(); + CHECK_FALSE(type->IsConst()); + CHECK_FALSE(type->IsArray()); + CHECK_FALSE(type->IsHandle()); + auto& id = type->GetScopedIdentifier(); + CHECK(id.GetIdentifier().GetString() == u8"baz"); + CHECK(id.GetScope()[1].GetString() == u8"bar"); + CHECK(id.GetScope()[0].GetString() == u8"foo"); + CHECK_FALSE(funcStat->ReturnsReference()); + CHECK(funcStat->GetIdentifier().GetString() == u8"foobar"); + auto paramList = (const MalachScript::Parser::ParsedParamListStatement*)funcStat->GetParamList().get(); + CHECK(paramList->GetParameters().size() == 2); + + auto& par1 = paramList->GetParameters()[0]; + CHECK_FALSE(par1.GetTypeStatement()->IsConst()); + CHECK_FALSE(par1.GetTypeStatement()->IsArray()); + CHECK_FALSE(par1.GetTypeStatement()->IsHandle()); + auto& par1TypeId = par1.GetTypeStatement()->GetScopedIdentifier(); + CHECK(par1TypeId.GetIdentifier().GetString() == u8"int"); + CHECK(par1.GetTypeMod() == TypeMod::RefIn); + CHECK(par1.GetIdentifier().GetString() == u8"par1"); + CHECK(par1.GetDefaultExpression() == nullptr); + + auto& par2 = paramList->GetParameters()[1]; + CHECK_FALSE(par2.GetTypeStatement()->IsConst()); + CHECK_FALSE(par2.GetTypeStatement()->IsArray()); + CHECK_FALSE(par2.GetTypeStatement()->IsHandle()); + auto& par2TypeId = par2.GetTypeStatement()->GetScopedIdentifier(); + CHECK(par2TypeId.GetIdentifier().GetString() == u8"bool"); + CHECK(par2.GetTypeMod() == TypeMod::RefOut); + CHECK(par2.GetIdentifier().GetString() == u8"par2"); + CHECK(par2.GetDefaultExpression() == nullptr); + + CHECK_FALSE(funcStat->IsConst()); + CHECK(funcStat->GetFuncAttr() == MalachScript::FuncAttr::None); + CHECK(funcStat->GetStatBlock() == nullptr); + })