Add interpreter::value_visitor
This commit is contained in:
parent
8c07e1950b
commit
83b4d23ab2
2 changed files with 165 additions and 105 deletions
|
|
@ -0,0 +1,71 @@
|
|||
#pragma once
|
||||
|
||||
#include <pslang/interpreter/value.hpp>
|
||||
|
||||
namespace pslang::interpreter
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template <typename Visitor>
|
||||
struct const_value_visitor_helper
|
||||
{
|
||||
Visitor & visitor;
|
||||
|
||||
template <typename Value>
|
||||
auto operator()(Value const & value)
|
||||
{
|
||||
return visitor(value);
|
||||
}
|
||||
|
||||
auto operator()(value const & value)
|
||||
{
|
||||
return std::visit(*this, value);
|
||||
}
|
||||
|
||||
auto operator()(primitive_value const & value)
|
||||
{
|
||||
return std::visit(*this, value);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Visitor>
|
||||
struct value_visitor_helper
|
||||
{
|
||||
Visitor & visitor;
|
||||
|
||||
template <typename Value>
|
||||
auto operator()(Value & value)
|
||||
{
|
||||
return visitor(value);
|
||||
}
|
||||
|
||||
auto operator()(value & value)
|
||||
{
|
||||
return std::visit(*this, value);
|
||||
}
|
||||
|
||||
auto operator()(primitive_value & value)
|
||||
{
|
||||
return std::visit(*this, value);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template <typename Visitor>
|
||||
auto apply(Visitor && visitor, value const & value)
|
||||
{
|
||||
detail::const_value_visitor_helper<Visitor> helper{visitor};
|
||||
return helper(value);
|
||||
}
|
||||
|
||||
template <typename Visitor>
|
||||
auto apply(Visitor && visitor, value & value)
|
||||
{
|
||||
detail::value_visitor_helper<Visitor> helper{visitor};
|
||||
return helper(value);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
#include <pslang/interpreter/value.hpp>
|
||||
#include <pslang/interpreter/value_visitor.hpp>
|
||||
#include <pslang/types/print.hpp>
|
||||
|
||||
#include <iomanip>
|
||||
|
|
@ -9,33 +10,30 @@ namespace pslang::interpreter
|
|||
namespace
|
||||
{
|
||||
|
||||
types::type type_of_impl(unit_value const &)
|
||||
struct type_of_visitor
|
||||
{
|
||||
types::type operator()(unit_value const &)
|
||||
{
|
||||
return types::unit_type{};
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
types::type type_of_impl(primitive_value_base<T> const &)
|
||||
types::type operator()(primitive_value_base<T> const &)
|
||||
{
|
||||
return types::primitive_type(types::primitive_type_base<T>{});
|
||||
}
|
||||
|
||||
types::type type_of_impl(primitive_value const & value)
|
||||
{
|
||||
return std::visit([](auto const & value){ return type_of_impl(value); }, value);
|
||||
}
|
||||
|
||||
types::type type_of_impl(array_value const & value)
|
||||
types::type operator()(array_value const & value)
|
||||
{
|
||||
return types::array_type{.element_type = value.element_type, .size = value.elements.size()};
|
||||
}
|
||||
|
||||
types::type type_of_impl(struct_value const & value)
|
||||
types::type operator()(struct_value const & value)
|
||||
{
|
||||
return *value.struct_type;
|
||||
}
|
||||
|
||||
types::type type_of_impl(function_value const & value)
|
||||
types::type operator()(function_value const & value)
|
||||
{
|
||||
types::function_type result;
|
||||
for (auto const & argument : value.arguments)
|
||||
|
|
@ -43,19 +41,19 @@ namespace pslang::interpreter
|
|||
result.result = value.return_type;
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
types::type type_of_impl(value const & value)
|
||||
struct print_visitor
|
||||
{
|
||||
return std::visit([](auto const & value){ return type_of_impl(value); }, value);
|
||||
}
|
||||
std::ostream & out;
|
||||
|
||||
void print_impl(std::ostream & out, unit_value const &)
|
||||
void operator()(unit_value const &)
|
||||
{
|
||||
out << "unit";
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void print_impl(std::ostream & out, primitive_value_base<T> const & value)
|
||||
void operator()(primitive_value_base<T> const & value)
|
||||
{
|
||||
if constexpr (std::is_same_v<T, bool>)
|
||||
{
|
||||
|
|
@ -83,24 +81,19 @@ namespace pslang::interpreter
|
|||
}
|
||||
}
|
||||
|
||||
void print_impl(std::ostream & out, primitive_value const & value)
|
||||
{
|
||||
std::visit([&](auto const & value){ return print_impl(out, value); }, value);
|
||||
}
|
||||
|
||||
void print_impl(std::ostream & out, array_value const & value)
|
||||
void operator()(array_value const & value)
|
||||
{
|
||||
out << "[";
|
||||
for (std::size_t i = 0; i < value.elements.size(); ++i)
|
||||
{
|
||||
if (i > 0)
|
||||
out << ", ";
|
||||
print(out, *value.elements[i]);
|
||||
apply(*this, *value.elements[i]);
|
||||
}
|
||||
out << "]";
|
||||
}
|
||||
|
||||
void print_impl(std::ostream & out, struct_value const & value)
|
||||
void operator()(struct_value const & value)
|
||||
{
|
||||
out << "{";
|
||||
bool first = true;
|
||||
|
|
@ -110,31 +103,27 @@ namespace pslang::interpreter
|
|||
out << ", ";
|
||||
first = false;
|
||||
out << field.first << " = ";
|
||||
print(out, *field.second);
|
||||
apply(*this, *field.second);
|
||||
}
|
||||
out << "}";
|
||||
}
|
||||
|
||||
void print_impl(std::ostream & out, function_value const & value)
|
||||
void operator()(function_value const & value)
|
||||
{
|
||||
out << "func";
|
||||
}
|
||||
|
||||
void print_impl(std::ostream & out, value const & value)
|
||||
{
|
||||
std::visit([&](auto const & value){ return print_impl(out, value); }, value);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
types::type type_of(value const & value)
|
||||
{
|
||||
return type_of_impl(value);
|
||||
return apply(type_of_visitor{}, value);
|
||||
}
|
||||
|
||||
void print(std::ostream & out, value const & value)
|
||||
{
|
||||
print_impl(out, value);
|
||||
apply(print_visitor{out}, value);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue