Store arity of functions in llvm context to generate correct calls.

This commit is contained in:
Danila Fedorin 2019-06-12 04:11:28 -07:00
parent e6f31f8c5b
commit dbe7572eb5
5 changed files with 19 additions and 9 deletions

View File

@ -109,7 +109,7 @@ namespace lily {
void instruction_push_global::gen_llvm(llvm_context& ctx) { void instruction_push_global::gen_llvm(llvm_context& ctx) {
llvm::Value* stack = ctx.get_current_function()->arg_begin(); llvm::Value* stack = ctx.get_current_function()->arg_begin();
llvm::Value* new_node = builder.CreateCall(malloc_node_global_func, llvm::Value* new_node = builder.CreateCall(malloc_node_global_func,
{ get_int8_constant(2), ctx.get_supercombinator(name) }, "temp"); { get_int8_constant(ctx.get_supercombinator_arity(name)), ctx.get_supercombinator_function(name) }, "temp");
// TODO get arity // TODO get arity
builder.CreateCall(stack_push_func, { stack, new_node }); builder.CreateCall(stack_push_func, { stack, new_node });
} }

View File

@ -217,12 +217,17 @@ namespace lily {
} }
} }
llvm::Function* llvm_context::get_supercombinator(const std::string& name) { llvm::Function* llvm_context::get_supercombinator_function(const std::string& name) {
if(!supercombinators.count(name)) throw error("unknown supercombinator"); if(!supercombinators.count(name)) throw error("unknown supercombinator");
return supercombinators.find(name)->second; return supercombinators.find(name)->second;
} }
void llvm_context::add_supercombinator(const std::string& name) { int llvm_context::get_supercombinator_arity(const std::string& name) {
if(!arities.count(name)) throw error("unknown supercombinator");
return arities.find(name)->second;
}
void llvm_context::add_supercombinator(const std::string& name, int arity) {
if(supercombinators.count(name)) throw error("re-creating supercombinator"); if(supercombinators.count(name)) throw error("re-creating supercombinator");
llvm::Function* new_function = llvm::Function::Create( llvm::Function* new_function = llvm::Function::Create(
supercomb_function_type, supercomb_function_type,
@ -231,6 +236,7 @@ namespace lily {
&module); &module);
new_function->arg_begin()->setName("stack"); new_function->arg_begin()->setName("stack");
supercombinators[name] = new_function; supercombinators[name] = new_function;
arities[name] = arity;
} }
llvm::Function* llvm_context::get_current_function() { llvm::Function* llvm_context::get_current_function() {

View File

@ -53,10 +53,13 @@ namespace lily {
class llvm_context { class llvm_context {
private: private:
std::map<std::string, llvm::Function*> supercombinators; std::map<std::string, llvm::Function*> supercombinators;
std::map<std::string, int> arities;
llvm::Function* current_function; llvm::Function* current_function;
public: public:
llvm::Function* get_supercombinator(const std::string& name); void add_supercombinator(const std::string& name, int arity);
void add_supercombinator(const std::string& name); llvm::Function* get_supercombinator_function(const std::string& name);
int get_supercombinator_arity(const std::string& name);
llvm::Function* get_current_function(); llvm::Function* get_current_function();
void set_current_function(llvm::Function* f); void set_current_function(llvm::Function* f);
}; };

View File

@ -8,8 +8,8 @@ int main() {
try { try {
lily::program_ptr prog = lily::parse( lily::program_ptr prog = lily::parse(
"defn magic x y = { let z = { x + y } in { 326 + z + z } }\n" "defn magic x = { let z = { x * 2 } in { 326 + z + z } }\n"
"defn main = { magic 1 2 }" "defn main = { magic 1 + magic 0 }"
); );
prog->gen_llvm(); prog->gen_llvm();
} catch(lily::error& e) { } catch(lily::error& e) {

View File

@ -342,12 +342,13 @@ namespace lily {
compile(mgr, gcode); compile(mgr, gcode);
for(auto& pair : gcode) { for(auto& pair : gcode) {
ctx.add_supercombinator(pair.first); int arity = functions.count(pair.first) ? functions[pair.first].params.size() : 2;
ctx.add_supercombinator(pair.first, arity);
} }
for(auto& pair : gcode) { for(auto& pair : gcode) {
std::vector<instruction*>& comb_gcode = pair.second; std::vector<instruction*>& comb_gcode = pair.second;
llvm::Function* current_function = ctx.get_supercombinator(pair.first); llvm::Function* current_function = ctx.get_supercombinator_function(pair.first);
ctx.set_current_function(current_function); ctx.set_current_function(current_function);
llvm::BasicBlock* new_block = llvm::BasicBlock* new_block =
llvm::BasicBlock::Create(context, "entry", current_function); llvm::BasicBlock::Create(context, "entry", current_function);