Compare commits
	
		
			2 Commits
		
	
	
		
			9855dda31a
			...
			17c5486551
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 17c5486551 | |||
| df33263fcd | 
							
								
								
									
										6
									
								
								programs/eq.lily
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								programs/eq.lily
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,6 @@ | ||||
| defn main = { | ||||
|     case eq 1 1 of { | ||||
|         True -> { 326 } | ||||
|         False -> { 404 } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										12
									
								
								programs/factorial.lily
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								programs/factorial.lily
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,12 @@ | ||||
| defn if c t e = { | ||||
|     case c of { | ||||
|         True -> { t } | ||||
|         False -> { e } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| defn fact n = { | ||||
|     if (eq n 0) 1 (n * fact (n - 1)) | ||||
| } | ||||
| 
 | ||||
| defn main = { fact 6 } | ||||
| @ -1,4 +1,3 @@ | ||||
| data Bool = { True, False } | ||||
| defn not b = { | ||||
|     case b of { | ||||
|         False -> { True } | ||||
|  | ||||
| @ -62,6 +62,11 @@ namespace lily { | ||||
|         return os; | ||||
|     } | ||||
| 
 | ||||
|     std::ostream& instruction_eq::to_stream(std::ostream& os) { | ||||
|         os << "eq"; | ||||
|         return os; | ||||
|     } | ||||
| 
 | ||||
|     std::ostream& instruction_cond::to_stream(std::ostream& os) { | ||||
|         os << "cond"; | ||||
|         return os; | ||||
| @ -166,6 +171,39 @@ namespace lily { | ||||
|         builder.CreateCall(stack_push_func, { stack, new_node }); | ||||
|     } | ||||
| 
 | ||||
|     void instruction_eq::gen_llvm(llvm_context& ctx) { | ||||
|         llvm::Value* stack = ctx.get_current_function()->arg_begin(); | ||||
|         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"); | ||||
|         llvm::Value* param2_intptr = builder.CreateGEP(param2_node_num, { get_int32_constant(0), get_int32_constant(1) }, "temp"); | ||||
|         llvm::Value* param1_int = builder.CreateLoad(llvm::IntegerType::get(context, 32), param1_intptr, "temp"); | ||||
|         llvm::Value* param2_int = builder.CreateLoad(llvm::IntegerType::get(context, 32), param2_intptr, "temp"); | ||||
|         llvm::Value* compare_result = builder.CreateICmpEQ(param1_int, param2_int, "temp"); | ||||
| 
 | ||||
|         llvm::BasicBlock* false_block = llvm::BasicBlock::Create(context, "false", ctx.get_current_function()); | ||||
|         llvm::BasicBlock* true_block = llvm::BasicBlock::Create(context, "true", ctx.get_current_function()); | ||||
|         builder.CreateCondBr(compare_result, true_block, false_block); | ||||
| 
 | ||||
|         llvm::BasicBlock* after = llvm::BasicBlock::Create(context, "after", ctx.get_current_function()); | ||||
| 
 | ||||
|         builder.SetInsertPoint(false_block); | ||||
|         llvm::Value* false_node = builder.CreateCall(malloc_node_global_func, | ||||
|                 { get_int8_constant(0), ctx.get_supercombinator_function("False") }, "temp"); | ||||
|         builder.CreateCall(stack_push_func, { stack, false_node }); | ||||
|         builder.CreateBr(after); | ||||
| 
 | ||||
|         builder.SetInsertPoint(true_block); | ||||
|         llvm::Value* true_node = builder.CreateCall(malloc_node_global_func, | ||||
|                 { get_int8_constant(0), ctx.get_supercombinator_function("True") }, "temp"); | ||||
|         builder.CreateCall(stack_push_func, { stack, true_node }); | ||||
|         builder.CreateBr(after); | ||||
| 
 | ||||
|         builder.SetInsertPoint(after); | ||||
|     } | ||||
| 
 | ||||
|     void instruction_cond::gen_llvm(llvm_context& ctx) { | ||||
|          | ||||
|     } | ||||
|  | ||||
| @ -94,6 +94,11 @@ namespace lily { | ||||
|         void gen_llvm(llvm_context& ctx); | ||||
|     }; | ||||
| 
 | ||||
|     struct instruction_eq : instruction { | ||||
|         std::ostream& to_stream(std::ostream& os); | ||||
|         void gen_llvm(llvm_context& ctx); | ||||
|     }; | ||||
| 
 | ||||
|     struct instruction_cond : instruction { | ||||
|         std::vector<instruction*> true_branch; | ||||
|         std::vector<instruction*> false_branch; | ||||
|  | ||||
| @ -246,6 +246,13 @@ namespace lily { | ||||
|         return prog; | ||||
|     } | ||||
| 
 | ||||
|     program::program() { | ||||
|         type_data* data = type_mgr.create_data_type("Bool"); | ||||
|         std::vector<type*> params; | ||||
|         data->create_constructor("True", std::move(params)); | ||||
|         data->create_constructor("False", std::move(params)); | ||||
|     } | ||||
| 
 | ||||
|     void program::check() { | ||||
|         // Each function has an environment, which will be used
 | ||||
|         // as base for type checking.
 | ||||
| @ -281,6 +288,13 @@ namespace lily { | ||||
|             base_env->set_type(pair.first, current_type); | ||||
|         } | ||||
| 
 | ||||
|         // Also add internal functions
 | ||||
|         type* eq_return_type = type_mgr.require_type("Bool"); | ||||
|         type* eq_param_type = type_mgr.require_type("Int"); | ||||
|         type* eq_app_1 = type_mgr.create_type<type_func>(eq_param_type, eq_return_type); | ||||
|         type* eq_app_2 = type_mgr.create_type<type_func>(eq_param_type, eq_app_1); | ||||
|         base_env->set_type("eq", eq_app_2); | ||||
| 
 | ||||
|         // We also want to gather all the constructor calls.
 | ||||
|         type_mgr.register_constructors(base_env); | ||||
| 
 | ||||
| @ -311,6 +325,16 @@ namespace lily { | ||||
|         generate_binop<binop::subtract>(mgr, into); | ||||
|         generate_binop<binop::times>(mgr, into); | ||||
|         generate_binop<binop::divide>(mgr, into); | ||||
| 
 | ||||
|         std::vector<instruction*> dest; | ||||
|         dest.push_back(mgr.add_instruction<instruction_push>(1)); | ||||
|         dest.push_back(mgr.add_instruction<instruction_eval>()); | ||||
|         dest.push_back(mgr.add_instruction<instruction_push>(1)); | ||||
|         dest.push_back(mgr.add_instruction<instruction_eval>()); | ||||
|         dest.push_back(mgr.add_instruction<instruction_eq>()); | ||||
|         dest.push_back(mgr.add_instruction<instruction_update>(2)); | ||||
|         dest.push_back(mgr.add_instruction<instruction_pop>(2)); | ||||
|         into["eq"] = std::move(dest); | ||||
|     } | ||||
| 
 | ||||
|     void program::compile(instruction_manager& mgr, std::map<std::string, std::vector<instruction*>>& into) { | ||||
|  | ||||
| @ -13,6 +13,8 @@ namespace lily { | ||||
|         type_manager type_mgr; | ||||
|         std::map<std::string, function> functions; | ||||
| 
 | ||||
|         program(); | ||||
| 
 | ||||
|         void check(); | ||||
|         void compile(instruction_manager& mgr, std::map<std::string, std::vector<instruction*>>& into); | ||||
|         void gen_llvm(); | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user