Refactor type visitor
This commit is contained in:
parent
d37c5b8754
commit
1f8c73614c
3 changed files with 64 additions and 83 deletions
|
|
@ -9,40 +9,43 @@ namespace pslang::interpreter
|
||||||
{
|
{
|
||||||
|
|
||||||
struct zero_value_visitor
|
struct zero_value_visitor
|
||||||
|
: types::const_visitor<zero_value_visitor>
|
||||||
{
|
{
|
||||||
interpreter::context & context;
|
interpreter::context & context;
|
||||||
|
|
||||||
value operator()(types::unit_type const &)
|
using const_visitor::apply;
|
||||||
|
|
||||||
|
value apply(types::unit_type const &)
|
||||||
{
|
{
|
||||||
return unit_value{};
|
return unit_value{};
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
value operator()(types::primitive_type_base<T> const &)
|
value apply(types::primitive_type_base<T> const &)
|
||||||
{
|
{
|
||||||
return primitive_value{primitive_value_base<T>{.value = {}}};
|
return primitive_value{primitive_value_base<T>{.value = {}}};
|
||||||
}
|
}
|
||||||
|
|
||||||
value operator()(types::array_type const & array_type)
|
value apply(types::array_type const & array_type)
|
||||||
{
|
{
|
||||||
array_value result{.element_type = array_type.element_type};
|
array_value result{.element_type = array_type.element_type};
|
||||||
for (std::uint64_t i = 0; i < array_type.size; ++i)
|
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)));
|
result.elements.push_back(std::make_unique<value>(apply(*array_type.element_type)));
|
||||||
return std::move(result);
|
return std::move(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
value operator()(types::function_type const &)
|
value apply(types::function_type const &)
|
||||||
{
|
{
|
||||||
throw std::runtime_error("Cannot zero-initialize a function type");
|
throw std::runtime_error("Cannot zero-initialize a function type");
|
||||||
}
|
}
|
||||||
|
|
||||||
value operator()(types::named_type const & named_type)
|
value apply(types::named_type const & named_type)
|
||||||
{
|
{
|
||||||
auto const & struct_data = context.scope_stack.at(named_type.level).structs.at(named_type.name);
|
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)};
|
struct_value result{.struct_type = std::make_unique<types::type>(named_type)};
|
||||||
for (auto const & field : struct_data.fields)
|
for (auto const & field : struct_data.fields)
|
||||||
result.fields[field.name] = std::make_unique<value>(types::apply(*this, *field.type));
|
result.fields[field.name] = std::make_unique<value>(apply(*field.type));
|
||||||
return std::move(result);
|
return std::move(result);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -74,7 +77,7 @@ namespace pslang::interpreter
|
||||||
|
|
||||||
value zero_value(context & context, types::type const & type)
|
value zero_value(context & context, types::type const & type)
|
||||||
{
|
{
|
||||||
return types::apply(zero_value_visitor{context}, type);
|
return zero_value_visitor{{}, context}.apply(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,67 +5,42 @@
|
||||||
namespace pslang::types
|
namespace pslang::types
|
||||||
{
|
{
|
||||||
|
|
||||||
namespace detail
|
template <typename Derived>
|
||||||
|
struct const_visitor
|
||||||
{
|
{
|
||||||
|
Derived & derived()
|
||||||
template <typename Visitor>
|
|
||||||
struct const_visitor_helper
|
|
||||||
{
|
{
|
||||||
Visitor & visitor;
|
return static_cast<Derived &>(*this);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename Type>
|
auto apply(types::primitive_type const & type)
|
||||||
auto operator()(Type const & type)
|
|
||||||
{
|
|
||||||
return visitor(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto operator()(types::primitive_type const & type)
|
|
||||||
{
|
|
||||||
return std::visit(*this, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto operator()(types::type const & type)
|
|
||||||
{
|
|
||||||
return std::visit(*this, type);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename Visitor>
|
|
||||||
struct visitor_helper
|
|
||||||
{
|
{
|
||||||
Visitor & visitor;
|
return std::visit([this](auto const & type){ return derived().apply(type); }, type);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename Type>
|
auto apply(types::type const & type)
|
||||||
auto operator()(Type & type)
|
{
|
||||||
{
|
return std::visit([this](auto const & type){ return derived().apply(type); }, type);
|
||||||
return visitor(type);
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
auto operator()(types::primitive_type & type)
|
template <typename Derived>
|
||||||
{
|
struct visitor
|
||||||
return std::visit(*this, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto operator()(types::type & type)
|
|
||||||
{
|
|
||||||
return std::visit(*this, type);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Visitor>
|
|
||||||
auto apply(Visitor && visitor, type const & type)
|
|
||||||
{
|
{
|
||||||
detail::const_visitor_helper<Visitor> helper{visitor};
|
Derived & derived()
|
||||||
return helper(type);
|
{
|
||||||
}
|
return static_cast<Derived &>(*this);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename Visitor>
|
auto apply(types::primitive_type & type)
|
||||||
auto apply(Visitor && visitor, type & type)
|
{
|
||||||
{
|
return std::visit([this](auto & type){ return derived().apply(type); }, type);
|
||||||
detail::visitor_helper<Visitor> helper{visitor};
|
}
|
||||||
return helper(type);
|
|
||||||
}
|
auto apply(types::type & type)
|
||||||
|
{
|
||||||
|
return std::visit([this](auto & type){ return derived().apply(type); }, type);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,82 +8,85 @@ namespace pslang::types
|
||||||
{
|
{
|
||||||
|
|
||||||
struct print_visitor
|
struct print_visitor
|
||||||
|
: const_visitor<print_visitor>
|
||||||
{
|
{
|
||||||
std::ostream & out;
|
std::ostream & out;
|
||||||
|
|
||||||
void operator()(unit_type const & type)
|
using const_visitor::apply;
|
||||||
|
|
||||||
|
void apply(unit_type const & type)
|
||||||
{
|
{
|
||||||
out << "unit";
|
out << "unit";
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator()(bool_type const &)
|
void apply(bool_type const &)
|
||||||
{
|
{
|
||||||
out << "bool";
|
out << "bool";
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator()(i8_type const &)
|
void apply(i8_type const &)
|
||||||
{
|
{
|
||||||
out << "i8";
|
out << "i8";
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator()(u8_type const &)
|
void apply(u8_type const &)
|
||||||
{
|
{
|
||||||
out << "u8";
|
out << "u8";
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator()(i16_type const &)
|
void apply(i16_type const &)
|
||||||
{
|
{
|
||||||
out << "i16";
|
out << "i16";
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator()(u16_type const &)
|
void apply(u16_type const &)
|
||||||
{
|
{
|
||||||
out << "u16";
|
out << "u16";
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator()(i32_type const &)
|
void apply(i32_type const &)
|
||||||
{
|
{
|
||||||
out << "i32";
|
out << "i32";
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator()(u32_type const &)
|
void apply(u32_type const &)
|
||||||
{
|
{
|
||||||
out << "u32";
|
out << "u32";
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator()(i64_type const &)
|
void apply(i64_type const &)
|
||||||
{
|
{
|
||||||
out << "i64";
|
out << "i64";
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator()(u64_type const &)
|
void apply(u64_type const &)
|
||||||
{
|
{
|
||||||
out << "u64";
|
out << "u64";
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator()(f32_type const &)
|
void apply(f32_type const &)
|
||||||
{
|
{
|
||||||
out << "f32";
|
out << "f32";
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator()(f64_type const &)
|
void apply(f64_type const &)
|
||||||
{
|
{
|
||||||
out << "f64";
|
out << "f64";
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator()(array_type const & type)
|
void apply(array_type const & type)
|
||||||
{
|
{
|
||||||
apply(*this, *type.element_type);
|
apply(*type.element_type);
|
||||||
out << "[" << type.size << "]";
|
out << "[" << type.size << "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator()(function_type const & type)
|
void apply(function_type const & type)
|
||||||
{
|
{
|
||||||
if (type.arguments.size() == 1)
|
if (type.arguments.size() == 1)
|
||||||
{
|
{
|
||||||
apply(*this, *type.arguments.front());
|
apply(*type.arguments.front());
|
||||||
out << " -> ";
|
out << " -> ";
|
||||||
apply(*this, *type.result);
|
apply(*type.result);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -93,13 +96,13 @@ namespace pslang::types
|
||||||
{
|
{
|
||||||
if (!first) out << ", ";
|
if (!first) out << ", ";
|
||||||
first = false;
|
first = false;
|
||||||
apply(*this, *argument);
|
apply(*argument);
|
||||||
}
|
}
|
||||||
out << ") -> ";
|
out << ") -> ";
|
||||||
apply(*this, *type.result);
|
apply(*type.result);
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator()(named_type const & type)
|
void apply(named_type const & type)
|
||||||
{
|
{
|
||||||
out << type.name;
|
out << type.name;
|
||||||
}
|
}
|
||||||
|
|
@ -109,7 +112,7 @@ namespace pslang::types
|
||||||
|
|
||||||
void print(std::ostream & out, type const & type)
|
void print(std::ostream & out, type const & type)
|
||||||
{
|
{
|
||||||
apply(print_visitor{out}, type);
|
print_visitor{{}, out}.apply(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue