diff --git a/src/ast.cpp b/src/ast.cpp index 96cf25f..2306b52 100644 --- a/src/ast.cpp +++ b/src/ast.cpp @@ -171,6 +171,7 @@ namespace lily { new_env->set_parent(env); std::vector new_branch; branch.expr->compile(mgr, new_branch, new_env); + new_branch.push_back(mgr.add_instruction(1)); ijump->instructions.push_back(std::move(new_branch)); for(int i = 0; i < ccount; i++) { @@ -179,7 +180,10 @@ namespace lily { } } else { pattern_cons* cons_pattern = dynamic_cast(pattern.get()); - int constructor = std::distance(data->constructors.begin(), data->constructors.find(cons_pattern->name)); + int constructor; + for(auto& pair : data->constructors) { + if(pair.first == cons_pattern->name) constructor = pair.second->id; + } if(branched[constructor]) throw error("cannot branch on the same constructor twice"); branched[constructor] = true; @@ -193,6 +197,7 @@ namespace lily { std::vector into; into.push_back(mgr.add_instruction(vcount)); branch.expr->compile(mgr, into, env); + into.push_back(mgr.add_instruction(vcount)); ijump->instructions.push_back(std::move(into)); ijump->const_instructions[constructor] = ijump->instructions.size() - 1; } diff --git a/src/gmachine.cpp b/src/gmachine.cpp index 336776d..4becc62 100644 --- a/src/gmachine.cpp +++ b/src/gmachine.cpp @@ -147,8 +147,8 @@ namespace lily { void instruction_op::gen_llvm(llvm_context& ctx) { llvm::Value* stack = ctx.get_current_function()->arg_begin(); - llvm::Value* param1 = builder.CreateCall(stack_pop_func, { stack }, "temp"); llvm::Value* param2 = builder.CreateCall(stack_pop_func, { stack }, "temp"); + llvm::Value* param1 = builder.CreateCall(stack_pop_func, { stack }, "temp"); llvm::Value* param1_node_num = builder.CreatePointerCast(param1, llvm::PointerType::getUnqual(node_num_type), "temp"); llvm::Value* param2_node_num = builder.CreatePointerCast(param2, llvm::PointerType::getUnqual(node_num_type), "temp"); llvm::Value* param1_intptr = builder.CreateGEP(param1_node_num, { get_int32_constant(0), get_int32_constant(1) }, "temp"); diff --git a/src/main.cpp b/src/main.cpp index abdbc4b..3056dfa 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -8,10 +8,12 @@ int main() { try { lily::program_ptr prog = lily::parse( - "data Bool = { False, True }\n" - "defn if c t e = { case not c of { True -> { t } False -> { e } } }\n" - "defn not b = { case b of { True -> { False } False -> { True } } }\n" - "defn main = { if True 3 2 }" + "data IntPair = { MkPair(Int, Int) }\n" + "data IntList = { Nil, Cons(Int, IntList) }" + "defn fst p = { case p of { MkPair(a, b) -> { a } } }\n" + "defn snd p = { case p of { MkPair(a, b) -> { b } } }\n" + "defn sum l = { case l of { Nil -> { 0 } Cons(x, xs) -> { x + sum xs } } }\n" + "defn main = { let tl1 = { Cons 1 Nil } in { let tl2 = { Cons 2 tl1 } in { let tl3 = { Cons 3 tl2 } in { sum tl3 } } } }" ); prog->gen_llvm(); } catch(lily::error& e) { diff --git a/src/type_manager.cpp b/src/type_manager.cpp index 0d962e2..7cc7f2d 100644 --- a/src/type_manager.cpp +++ b/src/type_manager.cpp @@ -29,7 +29,6 @@ namespace lily { type_data* type_manager::create_data_type(const std::string& name) { if(type_names.count(name)) throw error("redefinition of type"); - auto new_type = std::make_unique(next_id++); type_data* raw_ptr = new_type.get(); types.push_back(std::move(new_type)); @@ -43,7 +42,8 @@ namespace lily { } void type_manager::register_constructors(std::shared_ptr env) { - for(auto& type_ref : types) { + for(int i = 0; i < types.size(); i++) { + std::unique_ptr& type_ref = types[i]; type_data* data_type = dynamic_cast(type_ref.get()); if(!data_type) continue;