From ae3e661d7a6c03de3693cf97db0e9fbc6cf56bb0 Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Tue, 24 Mar 2020 22:00:09 -0700 Subject: [PATCH] Implement new ordered typing in compiler series --- code/compiler/10/graph.hpp | 13 +++++--- code/compiler/10/main.cpp | 63 ++++++++++++++++++++++++-------------- code/compiler/10/parser.y | 9 +++--- 3 files changed, 54 insertions(+), 31 deletions(-) diff --git a/code/compiler/10/graph.hpp b/code/compiler/10/graph.hpp index 66dc392..d1b0a86 100644 --- a/code/compiler/10/graph.hpp +++ b/code/compiler/10/graph.hpp @@ -46,6 +46,7 @@ class function_graph { std::map&); public: + std::set& add_function(const function& f); void add_edge(const function& from, const function& to); std::vector compute_order(); }; @@ -139,13 +140,17 @@ std::vector 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_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 }); } diff --git a/code/compiler/10/main.cpp b/code/compiler/10/main.cpp index dd59316..89d32d6 100644 --- a/code/compiler/10/main.cpp +++ b/code/compiler/10/main.cpp @@ -2,6 +2,7 @@ #include #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 defs_data; -extern std::vector defs_defn; +extern std::map defs_data; +extern std::map defs_defn; void typecheck_program( - const std::vector& defs_data, - const std::vector& defs_defn, + const std::map& defs_data, + const std::map& 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 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& defs_defn) { +void compile_program(const std::map& 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& defs_data, - const std::vector& defs_defn) { + const std::map& defs_data, + const std::map& 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); diff --git a/code/compiler/10/parser.y b/code/compiler/10/parser.y index 9614126..57f4be9 100644 --- a/code/compiler/10/parser.y +++ b/code/compiler/10/parser.y @@ -1,12 +1,13 @@ %{ #include #include +#include #include "ast.hpp" #include "definition.hpp" #include "parser.hpp" -std::vector defs_data; -std::vector defs_defn; +std::map defs_data; +std::map 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