Lots more tests for function statements, fixes several bugs.
This commit is contained in:
parent
dcf143b1b2
commit
f5baed48a9
|
@ -300,8 +300,8 @@ namespace MalachScript::Parser {
|
||||||
}
|
}
|
||||||
|
|
||||||
while (currentToken != nullptr && currentToken->GetKind() == LexTokenKind::ColonColonSymbol) {
|
while (currentToken != nullptr && currentToken->GetKind() == LexTokenKind::ColonColonSymbol) {
|
||||||
|
PROGRESS_TOKEN(currentToken);
|
||||||
const auto* n = currentToken;
|
const auto* n = currentToken;
|
||||||
PROGRESS_TOKEN(n);
|
|
||||||
if (ParseIdentifier(identifier, n)) {
|
if (ParseIdentifier(identifier, n)) {
|
||||||
PROGRESS_TOKEN(n);
|
PROGRESS_TOKEN(n);
|
||||||
if (n->GetKind() == LexTokenKind::ColonColonSymbol) {
|
if (n->GetKind() == LexTokenKind::ColonColonSymbol) {
|
||||||
|
@ -341,12 +341,13 @@ namespace MalachScript::Parser {
|
||||||
}
|
}
|
||||||
while (true) {
|
while (true) {
|
||||||
parameters.emplace_back();
|
parameters.emplace_back();
|
||||||
auto parameter = parameters.at(parameters.size() - 1);
|
auto& parameter = parameters.at(parameters.size() - 1);
|
||||||
if (!ParseType((const ParsedStatement*&)parameter.GetTypeStatement(), currentToken)) {
|
if (!ParseType((const ParsedStatement*&)parameter.GetTypeStatement(), currentToken)) {
|
||||||
LogError(Diagnostics::DiagnosticType::UnexpectedToken, currentToken->GetSpan());
|
LogError(Diagnostics::DiagnosticType::UnexpectedToken, currentToken->GetSpan());
|
||||||
}
|
}
|
||||||
ParseTypeMod(parameter.GetTypeMod());
|
ParseTypeMod(parameter.GetTypeMod());
|
||||||
ParseIdentifier(parameter.GetIdentifier(), currentToken);
|
ParseIdentifier(parameter.GetIdentifier(), currentToken);
|
||||||
|
PROGRESS_TOKEN(currentToken);
|
||||||
if (currentToken->GetKind() != LexTokenKind::CommaSymbol) {
|
if (currentToken->GetKind() != LexTokenKind::CommaSymbol) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -390,14 +391,14 @@ namespace MalachScript::Parser {
|
||||||
case LexTokenKind::Int16Keyword: out = PrimitiveTypes::Int16Name(); return true;
|
case LexTokenKind::Int16Keyword: out = PrimitiveTypes::Int16Name(); return true;
|
||||||
case LexTokenKind::Int32Keyword: out = PrimitiveTypes::Int32Name(); return true;
|
case LexTokenKind::Int32Keyword: out = PrimitiveTypes::Int32Name(); return true;
|
||||||
case LexTokenKind::Int64Keyword: out = PrimitiveTypes::Int64Name(); return true;
|
case LexTokenKind::Int64Keyword: out = PrimitiveTypes::Int64Name(); return true;
|
||||||
case LexTokenKind::UintKeyword: PrimitiveTypes::UintName(); return true;
|
case LexTokenKind::UintKeyword: out = PrimitiveTypes::UintName(); return true;
|
||||||
case LexTokenKind::Uint8Keyword: PrimitiveTypes::Uint8Name(); return true;
|
case LexTokenKind::Uint8Keyword: out = PrimitiveTypes::Uint8Name(); return true;
|
||||||
case LexTokenKind::Uint16Keyword: PrimitiveTypes::Uint16Name(); return true;
|
case LexTokenKind::Uint16Keyword: out = PrimitiveTypes::Uint16Name(); return true;
|
||||||
case LexTokenKind::Uint32Keyword: PrimitiveTypes::Uint32Name(); return true;
|
case LexTokenKind::Uint32Keyword: out = PrimitiveTypes::Uint32Name(); return true;
|
||||||
case LexTokenKind::Uint64Keyword: PrimitiveTypes::Uint64Name(); return true;
|
case LexTokenKind::Uint64Keyword: out = PrimitiveTypes::Uint64Name(); return true;
|
||||||
case LexTokenKind::FloatKeyword: PrimitiveTypes::FloatName(); return true;
|
case LexTokenKind::FloatKeyword: out = PrimitiveTypes::FloatName(); return true;
|
||||||
case LexTokenKind::DoubleKeyword: PrimitiveTypes::DoubleName(); return true;
|
case LexTokenKind::DoubleKeyword: out = PrimitiveTypes::DoubleName(); return true;
|
||||||
case LexTokenKind::BoolKeyword: PrimitiveTypes::BoolName(); return true;
|
case LexTokenKind::BoolKeyword: out = PrimitiveTypes::BoolName(); return true;
|
||||||
default: return false;
|
default: return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,7 +106,7 @@ namespace MalachScript::Parser {
|
||||||
class ParsedParameter {
|
class ParsedParameter {
|
||||||
private:
|
private:
|
||||||
const ParsedTypeStatement* _typeStatement = nullptr;
|
const ParsedTypeStatement* _typeStatement = nullptr;
|
||||||
TypeMod _typeMod;
|
TypeMod _typeMod = TypeMod::None;
|
||||||
Identifier _identifier;
|
Identifier _identifier;
|
||||||
const ParsedExpression* _defaultExpression = nullptr;
|
const ParsedExpression* _defaultExpression = nullptr;
|
||||||
|
|
||||||
|
@ -132,6 +132,8 @@ namespace MalachScript::Parser {
|
||||||
public:
|
public:
|
||||||
ParsedParamListStatement(TextSpan span, std::vector<ParsedParameter> parameters)
|
ParsedParamListStatement(TextSpan span, std::vector<ParsedParameter> parameters)
|
||||||
: ParsedStatementImpl<ParsedStatementKind::ParamList>(span), _parameters(std::move(parameters)){};
|
: ParsedStatementImpl<ParsedStatementKind::ParamList>(span), _parameters(std::move(parameters)){};
|
||||||
|
|
||||||
|
[[nodiscard]] const std::vector<ParsedParameter>& GetParameters() const noexcept { return _parameters; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class ParsedFuncStatement : public ParsedStatementImpl<ParsedStatementKind::Func> {
|
class ParsedFuncStatement : public ParsedStatementImpl<ParsedStatementKind::Func> {
|
||||||
|
|
|
@ -33,9 +33,26 @@ PARSER_TEST("Parse ``void foobar();``",
|
||||||
{
|
{
|
||||||
REQUIRE(script->GetStatements().size() == 1);
|
REQUIRE(script->GetStatements().size() == 1);
|
||||||
REQUIRE(script->GetStatements()[0].get()->GetKind() == Parser::ParsedStatementKind::Func);
|
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"void");
|
||||||
|
CHECK_FALSE(funcStat->ReturnsReference());
|
||||||
|
CHECK(funcStat->GetIdentifier().GetString() == u8"foobar");
|
||||||
|
auto paramList = (const MalachScript::Parser::ParsedParamListStatement*)funcStat->GetParamList().get();
|
||||||
|
CHECK(paramList->GetParameters().empty());
|
||||||
|
CHECK_FALSE(funcStat->IsConst());
|
||||||
|
CHECK(funcStat->GetFuncAttr() == MalachScript::FuncAttr::None);
|
||||||
|
CHECK(funcStat->GetStatBlock() == nullptr);
|
||||||
})
|
})
|
||||||
|
|
||||||
PARSER_TEST("Parse ``foo::bar::baz foobar();``",
|
PARSER_TEST("Parse scoped function without body.",
|
||||||
PARSER_TEST_TOKENS(new Parser::IdentifierToken(TextSpan(0, 0), u8"foo"),
|
PARSER_TEST_TOKENS(new Parser::IdentifierToken(TextSpan(0, 0), u8"foo"),
|
||||||
new Parser::LexTokenImpl<Parser::LexTokenKind::ColonColonSymbol>(TextSpan(0, 0)),
|
new Parser::LexTokenImpl<Parser::LexTokenKind::ColonColonSymbol>(TextSpan(0, 0)),
|
||||||
new Parser::IdentifierToken(TextSpan(0, 0), u8"bar"),
|
new Parser::IdentifierToken(TextSpan(0, 0), u8"bar"),
|
||||||
|
@ -49,4 +66,90 @@ PARSER_TEST("Parse ``foo::bar::baz foobar();``",
|
||||||
{
|
{
|
||||||
REQUIRE(script->GetStatements().size() == 1);
|
REQUIRE(script->GetStatements().size() == 1);
|
||||||
REQUIRE(script->GetStatements()[0].get()->GetKind() == Parser::ParsedStatementKind::Func);
|
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().empty());
|
||||||
|
CHECK_FALSE(funcStat->IsConst());
|
||||||
|
CHECK(funcStat->GetFuncAttr() == MalachScript::FuncAttr::None);
|
||||||
|
CHECK(funcStat->GetStatBlock() == nullptr);
|
||||||
|
})
|
||||||
|
|
||||||
|
PARSER_TEST("Parse scoped function with parameters without body.",
|
||||||
|
PARSER_TEST_TOKENS(new Parser::IdentifierToken(TextSpan(0, 0), u8"foo"),
|
||||||
|
new Parser::LexTokenImpl<Parser::LexTokenKind::ColonColonSymbol>(TextSpan(0, 0)),
|
||||||
|
new Parser::IdentifierToken(TextSpan(0, 0), u8"bar"),
|
||||||
|
new Parser::LexTokenImpl<Parser::LexTokenKind::ColonColonSymbol>(TextSpan(0, 0)),
|
||||||
|
new Parser::IdentifierToken(TextSpan(0, 0), u8"baz"),
|
||||||
|
new Parser::LexTokenImpl<Parser::LexTokenKind::Whitespace>(TextSpan(0, 0)),
|
||||||
|
new Parser::IdentifierToken(TextSpan(0, 0), u8"foobar"),
|
||||||
|
new Parser::LexTokenImpl<Parser::LexTokenKind::OpenParenthesisSymbol>(TextSpan(0, 0)),
|
||||||
|
|
||||||
|
new Parser::LexTokenImpl<Parser::LexTokenKind::IntKeyword>(TextSpan(0, 0)),
|
||||||
|
new Parser::LexTokenImpl<Parser::LexTokenKind::Whitespace>(TextSpan(0, 0)),
|
||||||
|
new Parser::IdentifierToken(TextSpan(0, 0), u8"par1"),
|
||||||
|
|
||||||
|
new Parser::LexTokenImpl<Parser::LexTokenKind::CommaSymbol>(TextSpan(0, 0)),
|
||||||
|
|
||||||
|
new Parser::LexTokenImpl<Parser::LexTokenKind::BoolKeyword>(TextSpan(0, 0)),
|
||||||
|
new Parser::LexTokenImpl<Parser::LexTokenKind::Whitespace>(TextSpan(0, 0)),
|
||||||
|
new Parser::IdentifierToken(TextSpan(0, 0), u8"par2"),
|
||||||
|
|
||||||
|
new Parser::LexTokenImpl<Parser::LexTokenKind::CloseParenthesisSymbol>(TextSpan(0, 0)),
|
||||||
|
new Parser::LexTokenImpl<Parser::LexTokenKind::SemicolonSymbol>(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::None);
|
||||||
|
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::None);
|
||||||
|
CHECK(par2.GetIdentifier().GetString() == u8"par2");
|
||||||
|
CHECK(par2.GetDefaultExpression() == nullptr);
|
||||||
|
|
||||||
|
CHECK_FALSE(funcStat->IsConst());
|
||||||
|
CHECK(funcStat->GetFuncAttr() == MalachScript::FuncAttr::None);
|
||||||
|
CHECK(funcStat->GetStatBlock() == nullptr);
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue