Implement new ordered typing in compiler series
This commit is contained in:
parent
c286c9edcc
commit
e07da0c9b1
13
10/graph.hpp
13
10/graph.hpp
|
@ -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 });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
57
10/main.cpp
57
10/main.cpp
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue
Block a user