2020-05-31 14:37:33 -07:00
|
|
|
#include "global_scope.hpp"
|
|
|
|
#include "ast.hpp"
|
|
|
|
|
2020-06-01 00:23:41 -07:00
|
|
|
void global_function::compile() {
|
2020-05-31 14:37:33 -07:00
|
|
|
env_ptr new_env = env_ptr(new env_offset(0, nullptr));
|
|
|
|
for(auto it = params.rbegin(); it != params.rend(); it++) {
|
|
|
|
new_env = env_ptr(new env_var(*it, new_env));
|
|
|
|
}
|
|
|
|
body->compile(new_env, instructions);
|
|
|
|
instructions.push_back(instruction_ptr(new instruction_update(params.size())));
|
|
|
|
instructions.push_back(instruction_ptr(new instruction_pop(params.size())));
|
|
|
|
}
|
|
|
|
|
2020-06-01 00:23:41 -07:00
|
|
|
void global_function::declare_llvm(llvm_context& ctx) {
|
2020-05-31 14:37:33 -07:00
|
|
|
generated_function = ctx.create_custom_function(name, params.size());
|
|
|
|
}
|
|
|
|
|
2020-06-01 00:23:41 -07:00
|
|
|
void global_function::generate_llvm(llvm_context& ctx) {
|
2020-05-31 14:37:33 -07:00
|
|
|
ctx.builder.SetInsertPoint(&generated_function->getEntryBlock());
|
|
|
|
for(auto& instruction : instructions) {
|
|
|
|
instruction->gen_llvm(ctx, generated_function);
|
|
|
|
}
|
|
|
|
ctx.builder.CreateRetVoid();
|
|
|
|
}
|
|
|
|
|
2020-06-01 00:23:41 -07:00
|
|
|
void global_constructor::generate_llvm(llvm_context& ctx) {
|
|
|
|
auto new_function =
|
|
|
|
ctx.create_custom_function(name, arity);
|
|
|
|
std::vector<instruction_ptr> instructions;
|
|
|
|
instructions.push_back(instruction_ptr(new instruction_pack(tag, arity)));
|
|
|
|
instructions.push_back(instruction_ptr(new instruction_update(0)));
|
|
|
|
ctx.builder.SetInsertPoint(&new_function->getEntryBlock());
|
|
|
|
for (auto& instruction : instructions) {
|
|
|
|
instruction->gen_llvm(ctx, new_function);
|
|
|
|
}
|
|
|
|
ctx.builder.CreateRetVoid();
|
|
|
|
}
|
|
|
|
|
|
|
|
global_function& global_scope::add_function(std::string n, std::vector<std::string> ps, ast_ptr b) {
|
|
|
|
global_function* new_function = new global_function(mangle_name(n), std::move(ps), std::move(b));
|
|
|
|
functions.push_back(global_function_ptr(new_function));
|
|
|
|
return *new_function;
|
|
|
|
}
|
|
|
|
|
|
|
|
global_constructor& global_scope::add_constructor(std::string n, int8_t t, size_t a) {
|
|
|
|
global_constructor* new_constructor = new global_constructor(mangle_name(n), t, a);
|
|
|
|
constructors.push_back(global_constructor_ptr(new_constructor));
|
|
|
|
return *new_constructor;
|
|
|
|
}
|
|
|
|
|
|
|
|
void global_scope::compile() {
|
|
|
|
for(auto& function : functions) {
|
|
|
|
function->compile();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void global_scope::generate_llvm(llvm_context& ctx) {
|
|
|
|
for(auto& constructor : constructors) {
|
|
|
|
constructor->generate_llvm(ctx);
|
|
|
|
}
|
|
|
|
for(auto& function : functions) {
|
|
|
|
function->declare_llvm(ctx);
|
|
|
|
}
|
|
|
|
for(auto& function : functions) {
|
|
|
|
function->generate_llvm(ctx);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string global_scope::mangle_name(const std::string& n) {
|
2020-05-31 14:37:33 -07:00
|
|
|
auto occurence_it = occurence_count.find(n);
|
|
|
|
int occurence = 0;
|
|
|
|
if(occurence_it != occurence_count.end()) {
|
|
|
|
occurence = occurence_it->second + 1;
|
|
|
|
}
|
|
|
|
occurence_count[n] = occurence;
|
|
|
|
|
|
|
|
std::string final_name = n;
|
|
|
|
if (occurence != 0) {
|
|
|
|
final_name += "_";
|
|
|
|
final_name += std::to_string(occurence);
|
|
|
|
}
|
2020-06-01 00:23:41 -07:00
|
|
|
return final_name;
|
2020-05-31 14:37:33 -07:00
|
|
|
}
|