#include #include #include namespace pslang::interpreter { namespace { struct zero_value_visitor : types::const_visitor { interpreter::context & context; using const_visitor::apply; value apply(types::unit_type const &) { return unit_value{}; } template value apply(types::primitive_type_base const &) { return primitive_value{primitive_value_base{.value = {}}}; } 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(apply(*array_type.element_type))); return std::move(result); } value apply(types::function_type const &) { throw std::runtime_error("Cannot zero-initialize a function type"); } value apply(types::pointer_type const &) { throw std::runtime_error("Not implemented"); } value apply(types::struct_type const & struct_type) { struct_value result{.struct_type = std::make_unique(struct_type)}; for (auto const & field : struct_type.node->fields) result.fields[field.name] = std::make_unique(apply(*field.inferred_type)); return std::move(result); } }; } context empty_context() { context result; result.frame_stack.emplace_back(); return result; } void dump(std::ostream & out, context const & context) { for (auto const & scope : context.frame_stack) { for (auto const & variable : scope.variables) { out << variable.first << " = "; print(out, variable.second.value); out << " ("; ast::print(out, type_of(variable.second.value)); out << ")\n"; } } std::cout << std::flush; } value zero_value(context & context, types::type const & type) { return zero_value_visitor{{}, context}.apply(type); } }