#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.get_builder().SetInsertPoint(&generated_function->getEntryBlock()); for(auto& instruction : instructions) { instruction->gen_llvm(ctx, generated_function); } ctx.get_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.get_builder().SetInsertPoint(&new_function->getEntryBlock()); for (auto& instruction : instructions) { instruction->gen_llvm(ctx, new_function); } ctx.get_builder().CreateRetVoid(); } global_function& global_scope::add_function( const std::string& n, std::vector ps, ast_ptr b) { auto name = mng->new_mangled_name(n); global_function* new_function = new global_function(std::move(name), std::move(ps), std::move(b)); functions.push_back(global_function_ptr(new_function)); return *new_function; } global_constructor& global_scope::add_constructor( const std::string& n, int8_t t, size_t a) { auto name = mng->new_mangled_name(n); global_constructor* new_constructor = new global_constructor(name, 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); } }