Make a few more things classes.

This commit is contained in:
Danila Fedorin 2020-09-17 18:30:41 -07:00
parent 5e13047846
commit 7a631b3557
7 changed files with 54 additions and 49 deletions

View File

@ -415,7 +415,7 @@ void compile_case(const ast_case& node, const env_ptr& env, const type* type, st
void ast_case::compile(const env_ptr& env, std::vector<instruction_ptr>& into) const { void ast_case::compile(const env_ptr& env, std::vector<instruction_ptr>& into) const {
type_app* app_type = dynamic_cast<type_app*>(input_type.get()); type_app* app_type = dynamic_cast<type_app*>(input_type.get());
type_data* data; type_data* data;
type_internal* internal; type_base *base;
of->compile(env, into); of->compile(env, into);
into.push_back(instruction_ptr(new instruction_eval())); into.push_back(instruction_ptr(new instruction_eval()));
@ -423,11 +423,11 @@ void ast_case::compile(const env_ptr& env, std::vector<instruction_ptr>& into) c
if(app_type && (data = dynamic_cast<type_data*>(app_type->constructor.get()))) { if(app_type && (data = dynamic_cast<type_data*>(app_type->constructor.get()))) {
compile_case<case_strategy_data>(*this, env, data, into); compile_case<case_strategy_data>(*this, env, data, into);
return; return;
} else if(app_type && (internal = dynamic_cast<type_internal*>(app_type->constructor.get()))) { } else if (app_type && (base = dynamic_cast<type_base *>(app_type->constructor.get()))) {
if(internal->name == "Bool") { if (base->name == "Bool") {
compile_case<case_strategy_bool>(*this, env, data, into); compile_case<case_strategy_bool>(*this, env, data, into);
return; return;
} }
} }
throw type_error("attempting unsupported case analysis", of->loc); throw type_error("attempting unsupported case analysis", of->loc);

View File

@ -16,13 +16,12 @@
#include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetMachine.h"
void compiler::add_default_types() { void compiler::add_default_types() {
global_env->bind_type("Int", type_ptr(new type_internal("Int"))); global_env->bind_type("Int", type_ptr(new type_base("Int")));
global_env->bind_type("Bool", type_ptr(new type_internal("Bool"))); global_env->bind_type("Bool", type_ptr(new type_base("Bool")));
} }
void compiler::add_binop_type(binop op, type_ptr type) { void compiler::add_binop_type(binop op, type_ptr type) {
auto name = mng.new_mangled_name(op_action(op)); auto name = mng.new_mangled_name(op_action(op));
binop_names[op] = name;
global_env->bind(op_name(op), std::move(type), visibility::global); global_env->bind(op_name(op), std::move(type), visibility::global);
global_env->set_mangled_name(op_name(op), name); global_env->set_mangled_name(op_name(op), name);
} }
@ -53,7 +52,7 @@ void compiler::add_default_function_types() {
} }
void compiler::parse() { void compiler::parse() {
if(!driver.run_parse()) if(!driver())
throw compiler_error("failed to open file"); throw compiler_error("failed to open file");
} }
@ -78,7 +77,8 @@ void compiler::compile() {
} }
void compiler::create_llvm_binop(binop op) { void compiler::create_llvm_binop(binop op) {
auto new_function = ctx.create_custom_function(binop_names.at(op), 2); auto new_function =
ctx.create_custom_function(global_env->get_mangled_name(op_name(op)), 2);
std::vector<instruction_ptr> instructions; std::vector<instruction_ptr> instructions;
instructions.push_back(instruction_ptr(new instruction_push(1))); instructions.push_back(instruction_ptr(new instruction_push(1)));
instructions.push_back(instruction_ptr(new instruction_eval())); instructions.push_back(instruction_ptr(new instruction_eval()));
@ -95,7 +95,8 @@ void compiler::create_llvm_binop(binop op) {
} }
void compiler::create_llvm_bool(bool b) { void compiler::create_llvm_bool(bool b) {
auto new_function = ctx.create_custom_function(b ? "True" : "False", 0); auto new_function = ctx.create_custom_function(
global_env->get_mangled_name(b ? "True" : "False"), 0);
std::vector<instruction_ptr> instructions; std::vector<instruction_ptr> instructions;
instructions.push_back(instruction_ptr(new instruction_pushint(b))); instructions.push_back(instruction_ptr(new instruction_pushint(b)));
instructions.push_back(instruction_ptr(new instruction_update(0))); instructions.push_back(instruction_ptr(new instruction_update(0)));
@ -158,7 +159,7 @@ void compiler::output_llvm(const std::string& into) {
compiler::compiler(const std::string& filename) compiler::compiler(const std::string& filename)
: file_m(), global_defs(), driver(file_m, global_defs, filename), : file_m(), global_defs(), driver(file_m, global_defs, filename),
mng(), global_scp(mng), global_env(new type_env), type_m(), ctx() { global_env(new type_env), type_m(), mng(), global_scp(mng), ctx() {
add_default_types(); add_default_types();
add_default_function_types(); add_default_function_types();
} }

View File

@ -10,14 +10,13 @@
class compiler { class compiler {
private: private:
std::map<binop, std::string> binop_names;
file_mgr file_m; file_mgr file_m;
definition_group global_defs; definition_group global_defs;
parse_driver driver; parse_driver driver;
mangler mng;
global_scope global_scp;
type_env_ptr global_env; type_env_ptr global_env;
type_mgr type_m; type_mgr type_m;
mangler mng;
global_scope global_scp;
llvm_context ctx; llvm_context ctx;
void add_default_types(); void add_default_types();

View File

@ -65,8 +65,8 @@ void definition_data::insert_constructors() const {
for(auto& var : vars) { for(auto& var : vars) {
if(var_set.find(var) != var_set.end()) if(var_set.find(var) != var_set.end())
throw compiler_error( throw compiler_error(
std::string("type variable ") + "type variable " + var +
var + std::string(" used twice in data type definition."), loc); " used twice in data type definition.", loc);
var_set.insert(var); var_set.insert(var);
return_app->arguments.push_back(type_ptr(new type_var(var))); return_app->arguments.push_back(type_ptr(new type_var(var)));
} }

View File

@ -7,38 +7,43 @@
using maybe_location = std::optional<yy::location>; using maybe_location = std::optional<yy::location>;
struct compiler_error : std::exception { class compiler_error : std::exception {
std::string description; private:
maybe_location loc; std::string description;
maybe_location loc;
compiler_error(std::string d, maybe_location l = std::nullopt) public:
: description(std::move(d)), loc(std::move(l)) {} compiler_error(std::string d, maybe_location l = std::nullopt)
: description(std::move(d)), loc(std::move(l)) {}
const char* what() const noexcept override; const char* what() const noexcept override;
void print_about(std::ostream& to); void print_about(std::ostream& to);
void print_location(std::ostream& to, file_mgr& fm, bool highlight = false); void print_location(std::ostream& to, file_mgr& fm, bool highlight = false);
void pretty_print(std::ostream& to, file_mgr& fm); void pretty_print(std::ostream& to, file_mgr& fm);
}; };
struct type_error : compiler_error { class type_error : compiler_error {
std::optional<yy::location> loc; private:
type_error(std::string d, maybe_location l = std::nullopt) public:
: compiler_error(std::move(d), std::move(l)) {} type_error(std::string d, maybe_location l = std::nullopt)
: compiler_error(std::move(d), std::move(l)) {}
const char* what() const noexcept override; const char* what() const noexcept override;
void pretty_print(std::ostream& to, file_mgr& fm); void pretty_print(std::ostream& to, file_mgr& fm);
}; };
struct unification_error : public type_error { class unification_error : public type_error {
type_ptr left; private:
type_ptr right; type_ptr left;
type_ptr right;
unification_error(type_ptr l, type_ptr r, maybe_location loc = std::nullopt) public:
: left(std::move(l)), right(std::move(r)), unification_error(type_ptr l, type_ptr r, maybe_location loc = std::nullopt)
: left(std::move(l)), right(std::move(r)),
type_error("failed to unify types", std::move(loc)) {} type_error("failed to unify types", std::move(loc)) {}
void pretty_print(std::ostream& to, file_mgr& fm, type_mgr& mgr); void pretty_print(std::ostream& to, file_mgr& fm, type_mgr& mgr);
}; };

View File

@ -45,7 +45,7 @@ void file_mgr::print_location(
stream.write(content + highlight_end, print_end - highlight_end); stream.write(content + highlight_end, print_end - highlight_end);
} }
bool parse_driver::run_parse() { bool parse_driver::operator()() {
FILE* stream = fopen(file_name.c_str(), "r"); FILE* stream = fopen(file_name.c_str(), "r");
if(!stream) return false; if(!stream) return false;
yyscan_t scanner; yyscan_t scanner;

View File

@ -41,16 +41,16 @@ class parse_driver {
file_mgr* file_m; file_mgr* file_m;
public: public:
parse_driver( parse_driver(
file_mgr& mgr, file_mgr& mgr,
definition_group& defs, definition_group& defs,
const std::string& file) const std::string& file)
: file_name(file), file_m(&mgr), global_defs(&defs) {} : file_name(file), file_m(&mgr), global_defs(&defs) {}
bool run_parse(); bool operator()();
yy::location& get_current_location(); yy::location& get_current_location();
file_mgr& get_file_manager() const; file_mgr& get_file_manager() const;
definition_group& get_global_defs() const; definition_group& get_global_defs() const;
}; };
#define YY_DECL yy::parser::symbol_type yylex(yyscan_t yyscanner, parse_driver& drv) #define YY_DECL yy::parser::symbol_type yylex(yyscan_t yyscanner, parse_driver& drv)