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
|
||||
: types::const_visitor<zero_value_visitor>
|
||||
{
|
||||
interpreter::context & context;
|
||||
|
||||
value operator()(types::unit_type const &)
|
||||
using const_visitor::apply;
|
||||
|
||||
value apply(types::unit_type const &)
|
||||
{
|
||||
return unit_value{};
|
||||
}
|
||||
|
||||
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 = {}}};
|
||||
}
|
||||
|
||||
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};
|
||||
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);
|
||||
}
|
||||
|
||||
value operator()(types::function_type const &)
|
||||
value apply(types::function_type const &)
|
||||
{
|
||||
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);
|
||||
|
||||
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));
|
||||
result.fields[field.name] = std::make_unique<value>(apply(*field.type));
|
||||
return std::move(result);
|
||||
}
|
||||
};
|
||||
|
|
@ -74,7 +77,7 @@ namespace pslang::interpreter
|
|||
|
||||
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 detail
|
||||
template <typename Derived>
|
||||
struct const_visitor
|
||||
{
|
||||
|
||||
template <typename Visitor>
|
||||
struct const_visitor_helper
|
||||
Derived & derived()
|
||||
{
|
||||
Visitor & visitor;
|
||||
return static_cast<Derived &>(*this);
|
||||
}
|
||||
|
||||
template <typename 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
|
||||
auto apply(types::primitive_type const & type)
|
||||
{
|
||||
Visitor & visitor;
|
||||
return std::visit([this](auto const & type){ return derived().apply(type); }, type);
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
auto operator()(Type & type)
|
||||
{
|
||||
return visitor(type);
|
||||
}
|
||||
auto apply(types::type const & type)
|
||||
{
|
||||
return std::visit([this](auto const & type){ return derived().apply(type); }, type);
|
||||
}
|
||||
};
|
||||
|
||||
auto operator()(types::primitive_type & type)
|
||||
{
|
||||
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)
|
||||
template <typename Derived>
|
||||
struct visitor
|
||||
{
|
||||
detail::const_visitor_helper<Visitor> helper{visitor};
|
||||
return helper(type);
|
||||
}
|
||||
Derived & derived()
|
||||
{
|
||||
return static_cast<Derived &>(*this);
|
||||
}
|
||||
|
||||
template <typename Visitor>
|
||||
auto apply(Visitor && visitor, type & type)
|
||||
{
|
||||
detail::visitor_helper<Visitor> helper{visitor};
|
||||
return helper(type);
|
||||
}
|
||||
auto apply(types::primitive_type & type)
|
||||
{
|
||||
return std::visit([this](auto & type){ return derived().apply(type); }, 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
|
||||
: const_visitor<print_visitor>
|
||||
{
|
||||
std::ostream & out;
|
||||
|
||||
void operator()(unit_type const & type)
|
||||
using const_visitor::apply;
|
||||
|
||||
void apply(unit_type const & type)
|
||||
{
|
||||
out << "unit";
|
||||
}
|
||||
|
||||
void operator()(bool_type const &)
|
||||
void apply(bool_type const &)
|
||||
{
|
||||
out << "bool";
|
||||
}
|
||||
|
||||
void operator()(i8_type const &)
|
||||
void apply(i8_type const &)
|
||||
{
|
||||
out << "i8";
|
||||
}
|
||||
|
||||
void operator()(u8_type const &)
|
||||
void apply(u8_type const &)
|
||||
{
|
||||
out << "u8";
|
||||
}
|
||||
|
||||
void operator()(i16_type const &)
|
||||
void apply(i16_type const &)
|
||||
{
|
||||
out << "i16";
|
||||
}
|
||||
|
||||
void operator()(u16_type const &)
|
||||
void apply(u16_type const &)
|
||||
{
|
||||
out << "u16";
|
||||
}
|
||||
|
||||
void operator()(i32_type const &)
|
||||
void apply(i32_type const &)
|
||||
{
|
||||
out << "i32";
|
||||
}
|
||||
|
||||
void operator()(u32_type const &)
|
||||
void apply(u32_type const &)
|
||||
{
|
||||
out << "u32";
|
||||
}
|
||||
|
||||
void operator()(i64_type const &)
|
||||
void apply(i64_type const &)
|
||||
{
|
||||
out << "i64";
|
||||
}
|
||||
|
||||
void operator()(u64_type const &)
|
||||
void apply(u64_type const &)
|
||||
{
|
||||
out << "u64";
|
||||
}
|
||||
|
||||
void operator()(f32_type const &)
|
||||
void apply(f32_type const &)
|
||||
{
|
||||
out << "f32";
|
||||
}
|
||||
|
||||
void operator()(f64_type const &)
|
||||
void apply(f64_type const &)
|
||||
{
|
||||
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 << "]";
|
||||
}
|
||||
|
||||
void operator()(function_type const & type)
|
||||
void apply(function_type const & type)
|
||||
{
|
||||
if (type.arguments.size() == 1)
|
||||
{
|
||||
apply(*this, *type.arguments.front());
|
||||
apply(*type.arguments.front());
|
||||
out << " -> ";
|
||||
apply(*this, *type.result);
|
||||
apply(*type.result);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -93,13 +96,13 @@ namespace pslang::types
|
|||
{
|
||||
if (!first) out << ", ";
|
||||
first = false;
|
||||
apply(*this, *argument);
|
||||
apply(*argument);
|
||||
}
|
||||
out << ") -> ";
|
||||
apply(*this, *type.result);
|
||||
apply(*type.result);
|
||||
}
|
||||
|
||||
void operator()(named_type const & type)
|
||||
void apply(named_type const & type)
|
||||
{
|
||||
out << type.name;
|
||||
}
|
||||
|
|
@ -109,7 +112,7 @@ namespace pslang::types
|
|||
|
||||
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