Support zero (default) initialization for struct types
This commit is contained in:
parent
83b4d23ab2
commit
d37c5b8754
4 changed files with 71 additions and 16 deletions
|
|
@ -54,4 +54,6 @@ namespace pslang::interpreter
|
|||
|
||||
void dump(std::ostream & out, context const & context);
|
||||
|
||||
value zero_value(context & context, types::type const & type);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,54 @@
|
|||
#include <pslang/interpreter/context.hpp>
|
||||
#include <pslang/types/type_visitor.hpp>
|
||||
#include <pslang/types/print.hpp>
|
||||
|
||||
namespace pslang::interpreter
|
||||
{
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
struct zero_value_visitor
|
||||
{
|
||||
interpreter::context & context;
|
||||
|
||||
value operator()(types::unit_type const &)
|
||||
{
|
||||
return unit_value{};
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
value operator()(types::primitive_type_base<T> const &)
|
||||
{
|
||||
return primitive_value{primitive_value_base<T>{.value = {}}};
|
||||
}
|
||||
|
||||
value operator()(types::array_type const & array_type)
|
||||
{
|
||||
array_value result{.element_type = array_type.element_type};
|
||||
for (std::uint64_t i = 0; i < array_type.size; ++i)
|
||||
result.elements.push_back(std::make_unique<value>(types::apply(*this, *array_type.element_type)));
|
||||
return std::move(result);
|
||||
}
|
||||
|
||||
value operator()(types::function_type const &)
|
||||
{
|
||||
throw std::runtime_error("Cannot zero-initialize a function type");
|
||||
}
|
||||
|
||||
value operator()(types::named_type const & named_type)
|
||||
{
|
||||
auto const & struct_data = context.scope_stack.at(named_type.level).structs.at(named_type.name);
|
||||
|
||||
struct_value result{.struct_type = std::make_unique<types::type>(named_type)};
|
||||
for (auto const & field : struct_data.fields)
|
||||
result.fields[field.name] = std::make_unique<value>(types::apply(*this, *field.type));
|
||||
return std::move(result);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
context empty_context()
|
||||
{
|
||||
context result;
|
||||
|
|
@ -27,4 +72,9 @@ namespace pslang::interpreter
|
|||
std::cout << std::flush;
|
||||
}
|
||||
|
||||
value zero_value(context & context, types::type const & type)
|
||||
{
|
||||
return types::apply(zero_value_visitor{context}, type);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -514,6 +514,9 @@ namespace pslang::interpreter
|
|||
{
|
||||
if (auto jt = it->structs.find(identifier->name); jt != it->structs.end())
|
||||
{
|
||||
if (function_call.arguments.empty())
|
||||
return zero_value(context, types::named_type{.name = identifier->name, .level = identifier->level});
|
||||
|
||||
if (jt->second.fields.size() != function_call.arguments.size())
|
||||
{
|
||||
std::ostringstream os;
|
||||
|
|
|
|||
|
|
@ -14,19 +14,19 @@ namespace pslang::types
|
|||
Visitor & visitor;
|
||||
|
||||
template <typename Type>
|
||||
void operator()(Type const & type)
|
||||
auto operator()(Type const & type)
|
||||
{
|
||||
visitor(type);
|
||||
return visitor(type);
|
||||
}
|
||||
|
||||
void operator()(types::primitive_type const & type)
|
||||
auto operator()(types::primitive_type const & type)
|
||||
{
|
||||
std::visit(*this, type);
|
||||
return std::visit(*this, type);
|
||||
}
|
||||
|
||||
void operator()(types::type const & type)
|
||||
auto operator()(types::type const & type)
|
||||
{
|
||||
std::visit(*this, type);
|
||||
return std::visit(*this, type);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -36,36 +36,36 @@ namespace pslang::types
|
|||
Visitor & visitor;
|
||||
|
||||
template <typename Type>
|
||||
void operator()(Type & type)
|
||||
auto operator()(Type & type)
|
||||
{
|
||||
visitor(type);
|
||||
return visitor(type);
|
||||
}
|
||||
|
||||
void operator()(types::primitive_type & type)
|
||||
auto operator()(types::primitive_type & type)
|
||||
{
|
||||
std::visit(*this, type);
|
||||
return std::visit(*this, type);
|
||||
}
|
||||
|
||||
void operator()(types::type & type)
|
||||
auto operator()(types::type & type)
|
||||
{
|
||||
std::visit(*this, type);
|
||||
return std::visit(*this, type);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template <typename Visitor>
|
||||
void apply(Visitor && visitor, type const & type)
|
||||
auto apply(Visitor && visitor, type const & type)
|
||||
{
|
||||
detail::const_visitor_helper<Visitor> helper{visitor};
|
||||
helper(type);
|
||||
return helper(type);
|
||||
}
|
||||
|
||||
template <typename Visitor>
|
||||
void apply(Visitor && visitor, type & type)
|
||||
auto apply(Visitor && visitor, type & type)
|
||||
{
|
||||
detail::visitor_helper<Visitor> helper{visitor};
|
||||
helper(type);
|
||||
return helper(type);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue