86 lines
2 KiB
C++
86 lines
2 KiB
C++
#include <pslang/interpreter/context.hpp>
|
|
#include <pslang/types/type_visitor.hpp>
|
|
#include <pslang/ast/print.hpp>
|
|
|
|
namespace pslang::interpreter
|
|
{
|
|
|
|
namespace
|
|
{
|
|
|
|
struct zero_value_visitor
|
|
: types::const_visitor<zero_value_visitor>
|
|
{
|
|
interpreter::context & context;
|
|
|
|
using const_visitor::apply;
|
|
|
|
value apply(types::unit_type const &)
|
|
{
|
|
return unit_value{};
|
|
}
|
|
|
|
template <typename T>
|
|
value apply(types::primitive_type_base<T> const &)
|
|
{
|
|
return primitive_value{primitive_value_base<T>{.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<value>(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<types::type>(struct_type)};
|
|
for (auto const & field : struct_type.node->fields)
|
|
result.fields[field.name] = std::make_unique<value>(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);
|
|
}
|
|
|
|
}
|