#pragma once #include <memory> #include <vector> #include <map> #include <set> #include "instruction.hpp" #include "llvm_context.hpp" #include "parsed_type.hpp" #include "type_env.hpp" #include "global_scope.hpp" struct ast; using ast_ptr = std::unique_ptr<ast>; struct constructor { std::string name; std::vector<parsed_type_ptr> types; int8_t tag; constructor(std::string n, std::vector<parsed_type_ptr> ts) : name(std::move(n)), types(std::move(ts)) {} }; using constructor_ptr = std::unique_ptr<constructor>; struct definition_defn { std::string name; std::vector<std::string> params; ast_ptr body; type_env_ptr env; type_env_ptr var_env; std::set<std::string> free_variables; std::set<std::string> nearby_variables; type_ptr full_type; type_ptr return_type; definition_defn(std::string n, std::vector<std::string> p, ast_ptr b) : name(std::move(n)), params(std::move(p)), body(std::move(b)) { } void find_free(); void insert_types(type_mgr& mgr, type_env_ptr& env, visibility v); void typecheck(type_mgr& mgr); global_function& into_global(global_scope& scope); }; using definition_defn_ptr = std::unique_ptr<definition_defn>; struct definition_data { std::string name; std::vector<std::string> vars; std::vector<constructor_ptr> constructors; type_env_ptr env; definition_data( std::string n, std::vector<std::string> vs, std::vector<constructor_ptr> cs) : name(std::move(n)), vars(std::move(vs)), constructors(std::move(cs)) {} void insert_types(type_env_ptr& env); void insert_constructors() const; void into_globals(global_scope& scope); }; using definition_data_ptr = std::unique_ptr<definition_data>; struct definition_group { std::map<std::string, definition_data_ptr> defs_data; std::map<std::string, definition_defn_ptr> defs_defn; visibility vis; type_env_ptr env; definition_group(visibility v = visibility::local) : vis(v) {} void find_free(std::set<std::string>& into); void typecheck(type_mgr& mgr, type_env_ptr& env); };