diff --git a/libs/interpreter/source/context.cpp b/libs/interpreter/source/context.cpp index c2caac4..0036ea1 100644 --- a/libs/interpreter/source/context.cpp +++ b/libs/interpreter/source/context.cpp @@ -9,40 +9,43 @@ namespace pslang::interpreter { struct zero_value_visitor + : types::const_visitor { interpreter::context & context; - value operator()(types::unit_type const &) + using const_visitor::apply; + + value apply(types::unit_type const &) { return unit_value{}; } template - value operator()(types::primitive_type_base const &) + value apply(types::primitive_type_base const &) { return primitive_value{primitive_value_base{.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(types::apply(*this, *array_type.element_type))); + result.elements.push_back(std::make_unique(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(named_type)}; for (auto const & field : struct_data.fields) - result.fields[field.name] = std::make_unique(types::apply(*this, *field.type)); + result.fields[field.name] = std::make_unique(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); } } diff --git a/libs/types/include/pslang/types/type_visitor.hpp b/libs/types/include/pslang/types/type_visitor.hpp index 1a9bdea..8dfaa1d 100644 --- a/libs/types/include/pslang/types/type_visitor.hpp +++ b/libs/types/include/pslang/types/type_visitor.hpp @@ -5,67 +5,42 @@ namespace pslang::types { - namespace detail + template + struct const_visitor { - - template - struct const_visitor_helper + Derived & derived() { - Visitor & visitor; + return static_cast(*this); + } - template - 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 - 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 - 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 - auto apply(Visitor && visitor, type const & type) + template + struct visitor { - detail::const_visitor_helper helper{visitor}; - return helper(type); - } + Derived & derived() + { + return static_cast(*this); + } - template - auto apply(Visitor && visitor, type & type) - { - detail::visitor_helper 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); + } + }; } diff --git a/libs/types/source/print.cpp b/libs/types/source/print.cpp index 3ff44fa..a54bf26 100644 --- a/libs/types/source/print.cpp +++ b/libs/types/source/print.cpp @@ -8,82 +8,85 @@ namespace pslang::types { struct print_visitor + : const_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); } }