89 lines
3.2 KiB
C++
89 lines
3.2 KiB
C++
#include "type_manager.hpp"
|
|
#include <memory>
|
|
#include "error.hpp"
|
|
#include "type.hpp"
|
|
#include "type_checker.hpp"
|
|
#include <vector>
|
|
|
|
namespace lily {
|
|
type_manager::type_manager() {
|
|
create_int_type();
|
|
create_str_type();
|
|
}
|
|
|
|
type_internal* type_manager::create_int_type() {
|
|
auto new_type = std::unique_ptr<type_internal>(new type_internal(next_id++));
|
|
type_internal* raw_ptr = new_type.get();
|
|
types.push_back(std::move(new_type));
|
|
type_names["Int"] = raw_ptr;
|
|
return raw_ptr;
|
|
}
|
|
|
|
type_internal* type_manager::create_str_type() {
|
|
auto new_type = std::unique_ptr<type_internal>(new type_internal(next_id++));
|
|
type_internal* raw_ptr = new_type.get();
|
|
types.push_back(std::move(new_type));
|
|
type_names["Str"] = raw_ptr;
|
|
return raw_ptr;
|
|
}
|
|
|
|
type_data* type_manager::create_data_type(const std::string& name) {
|
|
if(type_names.count(name)) throw error("redefinition of type");
|
|
auto new_type = std::unique_ptr<type_data>(new type_data(next_id++));
|
|
type_data* raw_ptr = new_type.get();
|
|
types.push_back(std::move(new_type));
|
|
type_names[name] = raw_ptr;
|
|
return raw_ptr;
|
|
}
|
|
|
|
type* type_manager::require_type(const std::string& name) const {
|
|
if(!type_names.count(name)) throw error("invalid type name");
|
|
return type_names.find(name)->second;
|
|
}
|
|
|
|
void type_manager::register_constructors(std::shared_ptr<type_env> env) {
|
|
for(int i = 0; i < types.size(); i++) {
|
|
std::unique_ptr<type>& type_ref = types[i];
|
|
type_data* data_type = dynamic_cast<type_data*>(type_ref.get());
|
|
if(!data_type) continue;
|
|
|
|
for(auto& pair : data_type->constructors) {
|
|
size_t param_count = pair.second->params.size();
|
|
type* current_type = data_type;
|
|
for(int i = 0; i < param_count; i++) {
|
|
type* param = pair.second->params[param_count - i - 1];
|
|
current_type = create_type<type_func>(param, current_type);
|
|
}
|
|
env->set_type(pair.first, current_type);
|
|
}
|
|
}
|
|
}
|
|
|
|
void type_manager::register_constructor_supercombs(instruction_manager& mgr, std::map<std::string, std::vector<instruction*>>& into) {
|
|
for(auto& type_ref : types) {
|
|
type_data* data_type = dynamic_cast<type_data*>(type_ref.get());
|
|
if(!data_type) continue;
|
|
|
|
for(auto& pair : data_type->constructors) {
|
|
std::vector<instruction*> is;
|
|
is.push_back(mgr.add_instruction<instruction_pack>(pair.second->id, pair.second->params.size()));
|
|
is.push_back(mgr.add_instruction<instruction_update>(0));
|
|
into[pair.first] = std::move(is);
|
|
}
|
|
}
|
|
}
|
|
|
|
int type_manager::constructor_arity(const std::string& name) {
|
|
for(auto& type_ref : types) {
|
|
type_data* data_type = dynamic_cast<type_data*>(type_ref.get());
|
|
if(!data_type) continue;
|
|
|
|
for(auto& pair : data_type->constructors) {
|
|
if(pair.first == name) return pair.second->params.size();
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
}
|