#include #include #include namespace pslang::interpreter { namespace { struct zero_value_visitor { interpreter::context & context; value operator()(types::unit_type const &) { return unit_value{}; } template value operator()(types::primitive_type_base const &) { return primitive_value{primitive_value_base{.value = {}}}; } value operator()(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))); return std::move(result); } value operator()(types::function_type const &) { throw std::runtime_error("Cannot zero-initialize a function type"); } value operator()(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)); return std::move(result); } }; } context empty_context() { context result; result.scope_stack.emplace_back(); return result; } void dump(std::ostream & out, context const & context) { for (auto const & scope : context.scope_stack) { for (auto const & variable : scope.variables) { out << variable.first << " = "; print(out, variable.second.value); out << " ("; types::print(out, type_of(variable.second.value)); out << ")\n"; } } std::cout << std::flush; } value zero_value(context & context, types::type const & type) { return types::apply(zero_value_visitor{context}, type); } }