pslang/libs/interpreter/source/context.cpp

80 lines
1.9 KiB
C++

#include <pslang/interpreter/context.hpp>
#include <pslang/types/type_visitor.hpp>
#include <pslang/types/print.hpp>
namespace pslang::interpreter
{
namespace
{
struct zero_value_visitor
{
interpreter::context & context;
value operator()(types::unit_type const &)
{
return unit_value{};
}
template <typename T>
value operator()(types::primitive_type_base<T> const &)
{
return primitive_value{primitive_value_base<T>{.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<value>(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<types::type>(named_type)};
for (auto const & field : struct_data.fields)
result.fields[field.name] = std::make_unique<value>(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);
}
}