#include #include namespace pslang::interpreter { namespace { template type::type type_of_impl(primitive_value_base const &) { return type::primitive_type(type::primitive_type_base{}); } type::type type_of_impl(primitive_value const & value) { return std::visit([](auto const & value){ return type_of_impl(value); }, value); } type::type type_of_impl(value const & value) { return std::visit([](auto const & value){ return type_of_impl(value); }, value); } template void print_impl(std::ostream & out, primitive_value_base const & value) { if constexpr (std::is_same_v) { out << (value.value ? "true" : "false"); } else if constexpr (std::is_integral_v && std::is_signed_v) { out << (std::int64_t)value.value; } else if constexpr (std::is_integral_v && std::is_unsigned_v) { out << (std::uint64_t)value.value; } else if constexpr (std::is_same_v) { out << std::setprecision(7) << value.value; } else if constexpr (std::is_same_v) { out << std::setprecision(15) << value.value; } else { out << "(unknown)"; } } 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, value const & value) { std::visit([&](auto const & value){ return print_impl(out, value); }, value); } } type::type type_of(value const & value) { return type_of_impl(value); } void print(std::ostream & out, value const & value) { print_impl(out, value); } }