diff --git a/lib/source/pl/core/ast/ast_node_type_application.cpp b/lib/source/pl/core/ast/ast_node_type_application.cpp index b185ff90..40ef1750 100644 --- a/lib/source/pl/core/ast/ast_node_type_application.cpp +++ b/lib/source/pl/core/ast/ast_node_type_application.cpp @@ -25,6 +25,8 @@ namespace pl::core::ast { } } else if (auto typeNode = dynamic_cast(templateArgument.get()); typeNode != nullptr) { templateTypeString += fmt::format("{}, ", typeNode->getTypeName()); + } else { + templateTypeString += ", "; } } diff --git a/lib/source/pl/core/ast/ast_node_type_operator.cpp b/lib/source/pl/core/ast/ast_node_type_operator.cpp index 036247d0..f00a6105 100644 --- a/lib/source/pl/core/ast/ast_node_type_operator.cpp +++ b/lib/source/pl/core/ast/ast_node_type_operator.cpp @@ -43,6 +43,14 @@ namespace pl::core::ast { }; std::vector> patterns; + if (this->getOperator() == Token::Operator::TypeNameOf) { + if (auto typeApp = dynamic_cast(this->m_expression.get()); typeApp != nullptr) { + auto evaluatedType = typeApp->evaluate(evaluator); + result = dynamic_cast(evaluatedType.get())->getTypeName(); + return std::unique_ptr(new ASTNodeLiteral(result)); + } + } + this->m_expression->createPatterns(evaluator, patterns); if (patterns.empty()) err::E0005.throwError("'auto' can only be used with parameters.", { }, this->getLocation()); @@ -56,16 +64,9 @@ namespace pl::core::ast { case Token::Operator::SizeOf: result = u128(pattern->getSize()); break; - case Token::Operator::TypeNameOf: { - if (auto typeApp = dynamic_cast(this->m_expression.get()); typeApp != nullptr) { - auto evaluatedType = typeApp->evaluate(evaluator); - result = dynamic_cast(evaluatedType.get())->getTypeName(); - } else { - result = pattern->getTypeName(); - } - + case Token::Operator::TypeNameOf: + result = pattern->getTypeName(); break; - } default: err::E0001.throwError("Invalid type operation.", {}, this->getLocation()); } diff --git a/lib/source/pl/core/ast/ast_node_variable_decl.cpp b/lib/source/pl/core/ast/ast_node_variable_decl.cpp index 8e73416b..4fb3d2b4 100644 --- a/lib/source/pl/core/ast/ast_node_variable_decl.cpp +++ b/lib/source/pl/core/ast/ast_node_variable_decl.cpp @@ -128,13 +128,14 @@ namespace pl::core::ast { auto startOffset = evaluator->getBitwiseReadOffset(); - evaluator->createVariable(this->getName(), this->getType().get(), { }, this->m_outVariable, false, false, this->m_constant); + auto evaluatedType = std::unique_ptr(dynamic_cast(this->getType()->evaluate(evaluator).release())); + evaluator->createVariable(this->getName(), evaluatedType.get(), { }, this->m_outVariable, false, false, this->m_constant); auto &variable = evaluator->getScope(0).scope->back(); std::vector> initValues; if (this->m_placementOffset == nullptr) { evaluator->pushSectionId(ptrn::Pattern::InstantiationSectionId); - this->getType()->createPatterns(evaluator, initValues); + evaluatedType->createPatterns(evaluator, initValues); evaluator->popSectionId(); } else { evaluator->pushSectionId(this->m_placementSection == nullptr ? ptrn::Pattern::MainSectionId : evaluator->getSectionId()); @@ -143,7 +144,7 @@ namespace pl::core::ast { ON_SCOPE_EXIT { evaluator->setBitwiseReadOffset(currOffset); }; evaluator->setReadOffset(u64(this->evaluatePlacementOffset(evaluator))); - this->getType()->createPatterns(evaluator, initValues); + evaluatedType->createPatterns(evaluator, initValues); evaluator->popSectionId(); } diff --git a/lib/source/pl/core/parser.cpp b/lib/source/pl/core/parser.cpp index 41482d08..54c0a40f 100644 --- a/lib/source/pl/core/parser.cpp +++ b/lib/source/pl/core/parser.cpp @@ -1310,7 +1310,7 @@ namespace pl::core { size_t index = 0; for (const auto &templateParameter : this->m_currTemplateType.front()->getTemplateParameters()) { if (const auto templateType = dynamic_cast(templateParameter.get()); templateType != nullptr){ - if (templateType->getName().get() == baseTypeName) { + if (templateType->getName().get() == baseTypeName && templateType->isType()) { auto type = create(nullptr); type->setTemplateParameterIndex(index); return type; diff --git a/tests/include/test_patterns/test_pattern_typenameof.hpp b/tests/include/test_patterns/test_pattern_typenameof.hpp index 51f9d6b6..1fa4291e 100644 --- a/tests/include/test_patterns/test_pattern_typenameof.hpp +++ b/tests/include/test_patterns/test_pattern_typenameof.hpp @@ -25,12 +25,35 @@ namespace pl::test { }; u32 P = 16; + A q @ 0; + B r; TypeName a @ 0; TypeName b @ 0; TypeName, "B"> c @ 0; TypeName, 2>, "B, 2>"> d @ 0; TypeName , "TypeName"> e @ 0; + TypeName, "B"> f @ 0; std::assert(typenameof(B, 2>) == "B, 2>", "type name should match"); + std::assert(typenameof(B) == "B", "type name should match"); + + B t; + std::assert(typenameof(t) == "B", "type name should match"); + + struct S { + u32 e = 16; + B a = t; + str typename = typenameof(a); + }; + + S s @ 0; + std::assert(s.typename == "B", "type name should match"); + + struct U { + u8 size; + u32 value[size]; + }; + + std::assert(typenameof(U) == "U", "type name should match"); )"; } };