Make sure structs with same name but in different scopes are regarded as different types

This commit is contained in:
Nikita Lisitsa 2025-12-17 23:12:54 +03:00
parent 04ee8e28e6
commit ddf6d55c54
3 changed files with 41 additions and 32 deletions

View file

@ -7,6 +7,8 @@
namespace pslang::interpreter namespace pslang::interpreter
{ {
type::type resolve_type(context & context, type::type const & type);
value eval(context & context, ast::expression_ptr const & expression); value eval(context & context, ast::expression_ptr const & expression);
value * eval_ref(context & context, ast::expression_ptr const & expression); value * eval_ref(context & context, ast::expression_ptr const & expression);

View file

@ -13,6 +13,39 @@ namespace pslang::interpreter
namespace namespace
{ {
type::type resolve_type_impl(context &, type::unit_type const & type)
{
return type;
}
type::type resolve_type_impl(context &, type::primitive_type const & type)
{
return type;
}
type::type resolve_type_impl(context & context, type::array_type const & type)
{
return type::array_type{std::make_unique<type::type>(resolve_type(context, *type.element_type)), type.size};
}
type::type resolve_type_impl(context & context, type::identifier const & type)
{
for (auto it = context.scope_stack.rbegin(); it != context.scope_stack.rend(); ++it)
{
if (it->structs.count(type.name))
{
return type::identifier{std::string(it.base() - context.scope_stack.begin() - 1, '/') + type.name};
}
}
throw std::runtime_error("Type \"" + type.name + "\" is not defined");
}
type::type resolve_type_impl(context & context, type::type const & type)
{
return std::visit([&](auto const & type){ return resolve_type_impl(context, type); }, type);
}
void print(std::ostream & out, ast::unary_operation_type type) void print(std::ostream & out, ast::unary_operation_type type)
{ {
switch (type) switch (type)
@ -542,7 +575,7 @@ namespace pslang::interpreter
} }
return struct_value{ return struct_value{
.struct_type = std::make_unique<type::type>(type::identifier{function_call.name}), .struct_type = std::make_unique<type::type>(resolve_type(context, type::identifier{function_call.name})),
.fields = std::move(fields), .fields = std::move(fields),
}; };
} }
@ -717,6 +750,11 @@ namespace pslang::interpreter
} }
type::type resolve_type(context & context, type::type const & type)
{
return resolve_type_impl(context, type);
}
value eval(context & context, ast::expression_ptr const & expression) value eval(context & context, ast::expression_ptr const & expression)
{ {
return eval_impl(context, expression); return eval_impl(context, expression);

View file

@ -30,37 +30,6 @@ namespace pslang::interpreter
context & context_; context & context_;
}; };
type::type resolve_type(context & context, type::type const & type);
type::type resolve_type(context &, type::unit_type const & type)
{
return type;
}
type::type resolve_type(context &, type::primitive_type const & type)
{
return type;
}
type::type resolve_type(context & context, type::array_type const & type)
{
return type::array_type{std::make_unique<type::type>(resolve_type(context, *type.element_type)), type.size};
}
type::type resolve_type(context & context, type::identifier const & type)
{
for (auto it = context.scope_stack.rbegin(); it != context.scope_stack.rend(); ++it)
if (it->structs.count(type.name))
return type;
throw std::runtime_error("Type \"" + type.name + "\" is not defined");
}
type::type resolve_type(context & context, type::type const & type)
{
return std::visit([&](auto const & type){ return resolve_type(context, type); }, type);
}
void exec_impl(context & context, ast::expression_ptr const & expression) void exec_impl(context & context, ast::expression_ptr const & expression)
{ {
eval(context, expression); eval(context, expression);