Skip to content

Commit fb00feb

Browse files
committed
evaluator: fix type name for non-placement template variablesFix type name for non-placement template variables
Fix the result of the type name for non-placement variables with template types. We still need to evaluate the arguments of the template before setting the type name. For typeNameOf the type, we can skip creating the pattern as only the arguments matter.
1 parent 3305788 commit fb00feb

5 files changed

Lines changed: 38 additions & 11 deletions

File tree

lib/source/pl/core/ast/ast_node_type_application.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ namespace pl::core::ast {
2525
}
2626
} else if (auto typeNode = dynamic_cast<ASTNodeTypeApplication*>(templateArgument.get()); typeNode != nullptr) {
2727
templateTypeString += fmt::format("{}, ", typeNode->getTypeName());
28+
} else {
29+
templateTypeString += ", ";
2830
}
2931
}
3032

lib/source/pl/core/ast/ast_node_type_operator.cpp

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,14 @@ namespace pl::core::ast {
4343
};
4444

4545
std::vector<std::shared_ptr<ptrn::Pattern>> patterns;
46+
if (this->getOperator() == Token::Operator::TypeNameOf) {
47+
if (auto typeApp = dynamic_cast<ASTNodeTypeApplication*>(this->m_expression.get()); typeApp != nullptr) {
48+
auto evaluatedType = typeApp->evaluate(evaluator);
49+
result = dynamic_cast<ASTNodeTypeApplication*>(evaluatedType.get())->getTypeName();
50+
return std::unique_ptr<ASTNode>(new ASTNodeLiteral(result));
51+
}
52+
}
53+
4654
this->m_expression->createPatterns(evaluator, patterns);
4755
if (patterns.empty())
4856
err::E0005.throwError("'auto' can only be used with parameters.", { }, this->getLocation());
@@ -56,16 +64,9 @@ namespace pl::core::ast {
5664
case Token::Operator::SizeOf:
5765
result = u128(pattern->getSize());
5866
break;
59-
case Token::Operator::TypeNameOf: {
60-
if (auto typeApp = dynamic_cast<ASTNodeTypeApplication*>(this->m_expression.get()); typeApp != nullptr) {
61-
auto evaluatedType = typeApp->evaluate(evaluator);
62-
result = dynamic_cast<ASTNodeTypeApplication*>(evaluatedType.get())->getTypeName();
63-
} else {
64-
result = pattern->getTypeName();
65-
}
66-
67+
case Token::Operator::TypeNameOf:
68+
result = pattern->getTypeName();
6769
break;
68-
}
6970
default:
7071
err::E0001.throwError("Invalid type operation.", {}, this->getLocation());
7172
}

lib/source/pl/core/evaluator.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,8 @@ namespace pl::core {
354354
}
355355
else {
356356
pattern = std::make_shared<ptrn::PatternPadding>(this, 0, 0, 0);
357-
pattern->setTypeName(type->getTypeName());
357+
auto evaluatedType = type->evaluate(this);
358+
pattern->setTypeName(dynamic_cast<ast::ASTNodeTypeApplication*>(evaluatedType.get())->getTypeName());
358359
}
359360
}
360361

lib/source/pl/core/parser.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1310,7 +1310,7 @@ namespace pl::core {
13101310
size_t index = 0;
13111311
for (const auto &templateParameter : this->m_currTemplateType.front()->getTemplateParameters()) {
13121312
if (const auto templateType = dynamic_cast<ast::ASTNodeTemplateParameter*>(templateParameter.get()); templateType != nullptr){
1313-
if (templateType->getName().get() == baseTypeName) {
1313+
if (templateType->getName().get() == baseTypeName && templateType->isType()) {
13141314
auto type = create<ast::ASTNodeTypeApplication>(nullptr);
13151315
type->setTemplateParameterIndex(index);
13161316
return type;

tests/include/test_patterns/test_pattern_typenameof.hpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,35 @@ namespace pl::test {
2525
};
2626
2727
u32 P = 16;
28+
A q @ 0;
29+
B<u32, q> r;
2830
TypeName<u32, "u32"> a @ 0;
2931
TypeName<A, "A"> b @ 0;
3032
TypeName<B<u32, 2>, "B<u32, 2>"> c @ 0;
3133
TypeName<B<B<u32, P>, 2>, "B<B<u32, 16>, 2>"> d @ 0;
3234
TypeName<TypeName<A, "A"> , "TypeName<A, \"A\">"> e @ 0;
35+
TypeName<B<u32, q>, "B<u32, A{ }>"> f @ 0;
3336
std::assert(typenameof(B<B<u32, P>, 2>) == "B<B<u32, 16>, 2>", "type name should match");
37+
std::assert(typenameof(B<u32, q>) == "B<u32, A{ }>", "type name should match");
38+
39+
B<u32, P> t;
40+
std::assert(typenameof(t) == "B<u32, 16>", "type name should match");
41+
42+
struct S {
43+
u32 e = 16;
44+
B<u32, e> a = t;
45+
str typename = typenameof(a);
46+
};
47+
48+
S s @ 0;
49+
std::assert(s.typename == "B<u32, 16>", "type name should match");
50+
51+
struct U {
52+
u8 size;
53+
u32 value[size];
54+
};
55+
56+
std::assert(typenameof(U) == "U", "type name should match");
3457
)";
3558
}
3659
};

0 commit comments

Comments
 (0)