77 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			77 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
#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<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(
 | 
						|
        const std::string& n,
 | 
						|
        std::vector<std::string> 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);
 | 
						|
    }
 | 
						|
}
 |