Skip to content

Commit a4e5e17

Browse files
AkiSakuraiWerWolv
andauthored
evaluator: Fix type name for non-placement template variables (WerWolv#208)
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. Co-authored-by: Nik <werwolv98@gmail.com>
1 parent a0029aa commit a4e5e17

5 files changed

Lines changed: 40 additions & 13 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/ast/ast_node_variable_decl.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -128,13 +128,14 @@ namespace pl::core::ast {
128128

129129
auto startOffset = evaluator->getBitwiseReadOffset();
130130

131-
evaluator->createVariable(this->getName(), this->getType().get(), { }, this->m_outVariable, false, false, this->m_constant);
131+
auto evaluatedType = std::unique_ptr<ASTNodeTypeApplication>(dynamic_cast<ast::ASTNodeTypeApplication*>(this->getType()->evaluate(evaluator).release()));
132+
evaluator->createVariable(this->getName(), evaluatedType.get(), { }, this->m_outVariable, false, false, this->m_constant);
132133
auto &variable = evaluator->getScope(0).scope->back();
133134

134135
std::vector<std::shared_ptr<ptrn::Pattern>> initValues;
135136
if (this->m_placementOffset == nullptr) {
136137
evaluator->pushSectionId(ptrn::Pattern::InstantiationSectionId);
137-
this->getType()->createPatterns(evaluator, initValues);
138+
evaluatedType->createPatterns(evaluator, initValues);
138139
evaluator->popSectionId();
139140
} else {
140141
evaluator->pushSectionId(this->m_placementSection == nullptr ? ptrn::Pattern::MainSectionId : evaluator->getSectionId());
@@ -143,7 +144,7 @@ namespace pl::core::ast {
143144
ON_SCOPE_EXIT { evaluator->setBitwiseReadOffset(currOffset); };
144145

145146
evaluator->setReadOffset(u64(this->evaluatePlacementOffset(evaluator)));
146-
this->getType()->createPatterns(evaluator, initValues);
147+
evaluatedType->createPatterns(evaluator, initValues);
147148
evaluator->popSectionId();
148149
}
149150

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)