Implement new ordered typing in compiler series
This commit is contained in:
parent
0efa05142f
commit
ae3e661d7a
|
@ -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 });
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue
Block a user