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 = { | defn not b = { | ||||||
|     case b of { |     case b of { | ||||||
|         False -> { True } |         False -> { True } | ||||||
|  | |||||||
| @ -62,6 +62,11 @@ namespace lily { | |||||||
|         return os; |         return os; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     std::ostream& instruction_eq::to_stream(std::ostream& os) { | ||||||
|  |         os << "eq"; | ||||||
|  |         return os; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     std::ostream& instruction_cond::to_stream(std::ostream& os) { |     std::ostream& instruction_cond::to_stream(std::ostream& os) { | ||||||
|         os << "cond"; |         os << "cond"; | ||||||
|         return os; |         return os; | ||||||
| @ -166,6 +171,39 @@ namespace lily { | |||||||
|         builder.CreateCall(stack_push_func, { stack, new_node }); |         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) { |     void instruction_cond::gen_llvm(llvm_context& ctx) { | ||||||
|          |          | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -94,6 +94,11 @@ namespace lily { | |||||||
|         void gen_llvm(llvm_context& ctx); |         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 { |     struct instruction_cond : instruction { | ||||||
|         std::vector<instruction*> true_branch; |         std::vector<instruction*> true_branch; | ||||||
|         std::vector<instruction*> false_branch; |         std::vector<instruction*> false_branch; | ||||||
|  | |||||||
| @ -246,6 +246,13 @@ namespace lily { | |||||||
|         return prog; |         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() { |     void program::check() { | ||||||
|         // Each function has an environment, which will be used
 |         // Each function has an environment, which will be used
 | ||||||
|         // as base for type checking.
 |         // as base for type checking.
 | ||||||
| @ -281,6 +288,13 @@ namespace lily { | |||||||
|             base_env->set_type(pair.first, current_type); |             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.
 |         // We also want to gather all the constructor calls.
 | ||||||
|         type_mgr.register_constructors(base_env); |         type_mgr.register_constructors(base_env); | ||||||
| 
 | 
 | ||||||
| @ -311,6 +325,16 @@ namespace lily { | |||||||
|         generate_binop<binop::subtract>(mgr, into); |         generate_binop<binop::subtract>(mgr, into); | ||||||
|         generate_binop<binop::times>(mgr, into); |         generate_binop<binop::times>(mgr, into); | ||||||
|         generate_binop<binop::divide>(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) { |     void program::compile(instruction_manager& mgr, std::map<std::string, std::vector<instruction*>>& into) { | ||||||
|  | |||||||
| @ -13,6 +13,8 @@ namespace lily { | |||||||
|         type_manager type_mgr; |         type_manager type_mgr; | ||||||
|         std::map<std::string, function> functions; |         std::map<std::string, function> functions; | ||||||
| 
 | 
 | ||||||
|  |         program(); | ||||||
|  | 
 | ||||||
|         void check(); |         void check(); | ||||||
|         void compile(instruction_manager& mgr, std::map<std::string, std::vector<instruction*>>& into); |         void compile(instruction_manager& mgr, std::map<std::string, std::vector<instruction*>>& into); | ||||||
|         void gen_llvm(); |         void gen_llvm(); | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user