Implement new ordered typing in compiler series

This commit is contained in:
Danila Fedorin 2020-03-24 22:00:09 -07:00
parent c286c9edcc
commit e07da0c9b1
3 changed files with 54 additions and 31 deletions

View File

@ -46,6 +46,7 @@ class function_graph {
std::map<group_id, data_ptr>&);
public:
std::set<function>& add_function(const function& f);
void add_edge(const function& from, const function& to);
std::vector<group_ptr> compute_order();
};
@ -139,13 +140,17 @@ std::vector<group_ptr> function_graph::generate_order(
return output;
}
void function_graph::add_edge(const function& from, const function& to) {
auto adjacency_list_it = adjacency_lists.find(from);
std::set<function>& function_graph::add_function(const function& f) {
auto adjacency_list_it = adjacency_lists.find(f);
if(adjacency_list_it != adjacency_lists.end()) {
adjacency_list_it->second.insert(to);
return adjacency_list_it->second;
} else {
adjacency_lists[from] = { to };
return adjacency_lists[f] = { };
}
}
void function_graph::add_edge(const function& from, const function& to) {
add_function(from).insert(to);
edges.insert({ from, to });
}

View File

@ -2,6 +2,7 @@
#include <iostream>
#include "binop.hpp"
#include "definition.hpp"
#include "graph.hpp"
#include "instruction.hpp"
#include "llvm_context.hpp"
#include "parser.hpp"
@ -20,12 +21,12 @@ void yy::parser::error(const std::string& msg) {
std::cout << "An error occured: " << msg << std::endl;
}
extern std::vector<definition_data_ptr> defs_data;
extern std::vector<definition_defn_ptr> defs_defn;
extern std::map<std::string, definition_data_ptr> defs_data;
extern std::map<std::string, definition_defn_ptr> defs_defn;
void typecheck_program(
const std::vector<definition_data_ptr>& defs_data,
const std::vector<definition_defn_ptr>& defs_defn,
const std::map<std::string, definition_data_ptr>& defs_data,
const std::map<std::string, definition_defn_ptr>& defs_defn,
type_mgr& mgr, type_env_ptr& env) {
type_ptr int_type = type_ptr(new type_base("Int"));
type_ptr binop_type = type_ptr(new type_arr(
@ -38,20 +39,36 @@ void typecheck_program(
env->bind("/", binop_type);
for(auto& def_data : defs_data) {
def_data->insert_types(mgr, env);
def_data.second->insert_types(mgr, env);
}
for(auto& def_data : defs_data) {
def_data->insert_constructors();
def_data.second->insert_constructors();
}
function_graph dependency_graph;
for(auto& def_defn : defs_defn) {
def_defn->find_free(mgr, env);
def_defn.second->find_free(mgr, env);
dependency_graph.add_function(def_defn.second->name);
for(auto& dependency : def_defn.second->free_variables) {
if(defs_defn.find(dependency) == defs_defn.end())
throw 0;
dependency_graph.add_edge(def_defn.second->name, dependency);
}
}
for(auto& def_defn : defs_defn) {
def_defn->insert_types(mgr);
}
for(auto& def_defn : defs_defn) {
def_defn->typecheck(mgr);
std::vector<group_ptr> groups = dependency_graph.compute_order();
for(auto it = groups.rbegin(); it != groups.rend(); it++) {
auto& group = *it;
for(auto& def_defnn_name : group->members) {
auto& def_defn = defs_defn.find(def_defnn_name)->second;
def_defn->insert_types(mgr);
}
for(auto& def_defnn_name : group->members) {
auto& def_defn = defs_defn.find(def_defnn_name)->second;
def_defn->typecheck(mgr);
}
}
for(auto& pair : env->names) {
@ -61,11 +78,11 @@ void typecheck_program(
}
}
void compile_program(const std::vector<definition_defn_ptr>& defs_defn) {
void compile_program(const std::map<std::string, definition_defn_ptr>& defs_defn) {
for(auto& def_defn : defs_defn) {
def_defn->compile();
def_defn.second->compile();
for(auto& instruction : def_defn->instructions) {
for(auto& instruction : def_defn.second->instructions) {
instruction->print(0, std::cout);
}
std::cout << std::endl;
@ -130,8 +147,8 @@ void output_llvm(llvm_context& ctx, const std::string& filename) {
}
void gen_llvm(
const std::vector<definition_data_ptr>& defs_data,
const std::vector<definition_defn_ptr>& defs_defn) {
const std::map<std::string, definition_data_ptr>& defs_data,
const std::map<std::string, definition_defn_ptr>& defs_defn) {
llvm_context ctx;
gen_llvm_internal_op(ctx, PLUS);
gen_llvm_internal_op(ctx, MINUS);
@ -139,13 +156,13 @@ void gen_llvm(
gen_llvm_internal_op(ctx, DIVIDE);
for(auto& def_data : defs_data) {
def_data->generate_llvm(ctx);
def_data.second->generate_llvm(ctx);
}
for(auto& def_defn : defs_defn) {
def_defn->declare_llvm(ctx);
def_defn.second->declare_llvm(ctx);
}
for(auto& def_defn : defs_defn) {
def_defn->generate_llvm(ctx);
def_defn.second->generate_llvm(ctx);
}
ctx.module.print(llvm::outs(), nullptr);
@ -159,11 +176,11 @@ int main() {
parser.parse();
for(auto& def_defn : defs_defn) {
std::cout << def_defn->name;
for(auto& param : def_defn->params) std::cout << " " << param;
std::cout << def_defn.second->name;
for(auto& param : def_defn.second->params) std::cout << " " << param;
std::cout << ":" << std::endl;
def_defn->body->print(1, std::cout);
def_defn.second->body->print(1, std::cout);
}
try {
typecheck_program(defs_data, defs_defn, mgr, env);

View File

@ -1,12 +1,13 @@
%{
#include <string>
#include <iostream>
#include <map>
#include "ast.hpp"
#include "definition.hpp"
#include "parser.hpp"
std::vector<definition_data_ptr> defs_data;
std::vector<definition_defn_ptr> defs_defn;
std::map<std::string, definition_data_ptr> defs_data;
std::map<std::string, definition_defn_ptr> defs_defn;
extern yy::parser::symbol_type yylex();
@ -59,8 +60,8 @@ definitions
;
definition
: defn { defs_defn.push_back(std::move($1)); }
| data { defs_data.push_back(std::move($1)); }
: defn { auto name = $1->name; defs_defn[name] = std::move($1); }
| data { auto name = $1->name; defs_data[name] = std::move($1); }
;
defn