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

View File

@ -2,6 +2,7 @@
#include <iostream> #include <iostream>
#include "binop.hpp" #include "binop.hpp"
#include "definition.hpp" #include "definition.hpp"
#include "graph.hpp"
#include "instruction.hpp" #include "instruction.hpp"
#include "llvm_context.hpp" #include "llvm_context.hpp"
#include "parser.hpp" #include "parser.hpp"
@ -20,12 +21,12 @@ void yy::parser::error(const std::string& msg) {
std::cout << "An error occured: " << msg << std::endl; std::cout << "An error occured: " << msg << std::endl;
} }
extern std::vector<definition_data_ptr> defs_data; extern std::map<std::string, definition_data_ptr> defs_data;
extern std::vector<definition_defn_ptr> defs_defn; extern std::map<std::string, definition_defn_ptr> defs_defn;
void typecheck_program( void typecheck_program(
const std::vector<definition_data_ptr>& defs_data, const std::map<std::string, definition_data_ptr>& defs_data,
const std::vector<definition_defn_ptr>& defs_defn, const std::map<std::string, definition_defn_ptr>& defs_defn,
type_mgr& mgr, type_env_ptr& env) { type_mgr& mgr, type_env_ptr& env) {
type_ptr int_type = type_ptr(new type_base("Int")); type_ptr int_type = type_ptr(new type_base("Int"));
type_ptr binop_type = type_ptr(new type_arr( type_ptr binop_type = type_ptr(new type_arr(
@ -38,21 +39,37 @@ void typecheck_program(
env->bind("/", binop_type); env->bind("/", binop_type);
for(auto& def_data : defs_data) { 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) { 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) { 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) { }
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); def_defn->insert_types(mgr);
} }
for(auto& def_defn : defs_defn) { for(auto& def_defnn_name : group->members) {
auto& def_defn = defs_defn.find(def_defnn_name)->second;
def_defn->typecheck(mgr); def_defn->typecheck(mgr);
} }
}
for(auto& pair : env->names) { for(auto& pair : env->names) {
std::cout << pair.first << ": "; std::cout << pair.first << ": ";
@ -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) { 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); instruction->print(0, std::cout);
} }
std::cout << std::endl; std::cout << std::endl;
@ -130,8 +147,8 @@ void output_llvm(llvm_context& ctx, const std::string& filename) {
} }
void gen_llvm( void gen_llvm(
const std::vector<definition_data_ptr>& defs_data, const std::map<std::string, definition_data_ptr>& defs_data,
const std::vector<definition_defn_ptr>& defs_defn) { const std::map<std::string, definition_defn_ptr>& defs_defn) {
llvm_context ctx; llvm_context ctx;
gen_llvm_internal_op(ctx, PLUS); gen_llvm_internal_op(ctx, PLUS);
gen_llvm_internal_op(ctx, MINUS); gen_llvm_internal_op(ctx, MINUS);
@ -139,13 +156,13 @@ void gen_llvm(
gen_llvm_internal_op(ctx, DIVIDE); gen_llvm_internal_op(ctx, DIVIDE);
for(auto& def_data : defs_data) { for(auto& def_data : defs_data) {
def_data->generate_llvm(ctx); def_data.second->generate_llvm(ctx);
} }
for(auto& def_defn : defs_defn) { for(auto& def_defn : defs_defn) {
def_defn->declare_llvm(ctx); def_defn.second->declare_llvm(ctx);
} }
for(auto& def_defn : defs_defn) { for(auto& def_defn : defs_defn) {
def_defn->generate_llvm(ctx); def_defn.second->generate_llvm(ctx);
} }
ctx.module.print(llvm::outs(), nullptr); ctx.module.print(llvm::outs(), nullptr);
@ -159,11 +176,11 @@ int main() {
parser.parse(); parser.parse();
for(auto& def_defn : defs_defn) { for(auto& def_defn : defs_defn) {
std::cout << def_defn->name; std::cout << def_defn.second->name;
for(auto& param : def_defn->params) std::cout << " " << param; for(auto& param : def_defn.second->params) std::cout << " " << param;
std::cout << ":" << std::endl; std::cout << ":" << std::endl;
def_defn->body->print(1, std::cout); def_defn.second->body->print(1, std::cout);
} }
try { try {
typecheck_program(defs_data, defs_defn, mgr, env); typecheck_program(defs_data, defs_defn, mgr, env);

View File

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