#include "type_manager.hpp" #include #include "error.hpp" #include "type.hpp" #include "type_checker.hpp" namespace lily { type_manager::type_manager() { create_int_type(); create_str_type(); } type_internal* type_manager::create_int_type() { auto new_type = std::make_unique(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::make_unique(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::make_unique(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 env) { for(auto& type_ref : types) { type_data* data_type = dynamic_cast(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(param, current_type); } env->set_type(pair.first, current_type); } } } }