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);
|
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/interpreter/context.hpp>
|
||||||
|
#include <pslang/types/type_visitor.hpp>
|
||||||
#include <pslang/types/print.hpp>
|
#include <pslang/types/print.hpp>
|
||||||
|
|
||||||
namespace pslang::interpreter
|
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 empty_context()
|
||||||
{
|
{
|
||||||
context result;
|
context result;
|
||||||
|
|
@ -27,4 +72,9 @@ namespace pslang::interpreter
|
||||||
std::cout << std::flush;
|
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 (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())
|
if (jt->second.fields.size() != function_call.arguments.size())
|
||||||
{
|
{
|
||||||
std::ostringstream os;
|
std::ostringstream os;
|
||||||
|
|
|
||||||
|
|
@ -14,19 +14,19 @@ namespace pslang::types
|
||||||
Visitor & visitor;
|
Visitor & visitor;
|
||||||
|
|
||||||
template <typename Type>
|
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;
|
Visitor & visitor;
|
||||||
|
|
||||||
template <typename Type>
|
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>
|
template <typename Visitor>
|
||||||
void apply(Visitor && visitor, type const & type)
|
auto apply(Visitor && visitor, type const & type)
|
||||||
{
|
{
|
||||||
detail::const_visitor_helper<Visitor> helper{visitor};
|
detail::const_visitor_helper<Visitor> helper{visitor};
|
||||||
helper(type);
|
return helper(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Visitor>
|
template <typename Visitor>
|
||||||
void apply(Visitor && visitor, type & type)
|
auto apply(Visitor && visitor, type & type)
|
||||||
{
|
{
|
||||||
detail::visitor_helper<Visitor> helper{visitor};
|
detail::visitor_helper<Visitor> helper{visitor};
|
||||||
helper(type);
|
return helper(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue