#include "global_scope.hpp" #include "ast.hpp" void global_function::compile() { 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()))); } void global_function::declare_llvm(llvm_context& ctx) { generated_function = ctx.create_custom_function(name, params.size()); } void global_function::generate_llvm(llvm_context& ctx) { ctx.builder.SetInsertPoint(&generated_function->getEntryBlock()); for(auto& instruction : instructions) { instruction->gen_llvm(ctx, generated_function); } ctx.builder.CreateRetVoid(); } void global_constructor::generate_llvm(llvm_context& ctx) { auto new_function = ctx.create_custom_function(name, arity); std::vector 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 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) { 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); } return final_name; }