Make a few more things classes.
This commit is contained in:
parent
a5597aeae0
commit
dfe47548cf
12
13/ast.cpp
12
13/ast.cpp
|
@ -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);
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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)));
|
||||||
}
|
}
|
||||||
|
|
47
13/error.hpp
47
13/error.hpp
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user