Fix unwind bug and add eval.
This commit is contained in:
		
							parent
							
								
									37f5e53a59
								
							
						
					
					
						commit
						e6f31f8c5b
					
				
							
								
								
									
										29
									
								
								runtime.c
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								runtime.c
									
									
									
									
									
								
							| @ -46,10 +46,8 @@ void stack_free(struct stack* stack) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void stack_push(struct stack* stack, struct node_parent* node) { | void stack_push(struct stack* stack, struct node_parent* node) { | ||||||
|     printf("pushing\n"); |  | ||||||
|     assert(stack->count < stack->size); |     assert(stack->count < stack->size); | ||||||
|     stack->data[stack->count++] = node; |     stack->data[stack->count++] = node; | ||||||
|     printf("new size: %d\n", stack->count); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| struct node_parent* stack_peek(struct stack* stack, int32_t offset) { | struct node_parent* stack_peek(struct stack* stack, int32_t offset) { | ||||||
| @ -58,7 +56,6 @@ struct node_parent* stack_peek(struct stack* stack, int32_t offset) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| struct node_parent* stack_pop(struct stack* stack) { | struct node_parent* stack_pop(struct stack* stack) { | ||||||
|     printf("popping\nnew size: %d\n", stack->count - 1); |  | ||||||
|     assert(stack->count > 0); |     assert(stack->count > 0); | ||||||
|     return stack->data[--stack->count]; |     return stack->data[--stack->count]; | ||||||
| } | } | ||||||
| @ -66,16 +63,14 @@ struct node_parent* stack_pop(struct stack* stack) { | |||||||
| void stack_popn(struct stack* stack, int32_t count) { | void stack_popn(struct stack* stack, int32_t count) { | ||||||
|     assert(stack->count >= count); |     assert(stack->count >= count); | ||||||
|     stack->count -= count; |     stack->count -= count; | ||||||
|     printf("popping %d\nnew size: %d\n", count, stack->count); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void stack_update(struct stack* stack, int32_t offset) { | void stack_update(struct stack* stack, int32_t offset) { | ||||||
|     assert(stack->count >= offset + 2); |     assert(stack->count >= offset + 2); | ||||||
|     struct node_parent* to_replace = stack->data[stack->count - 1 - 1 - offset]; |     struct node_ind* to_replace = (struct node_ind*) stack->data[stack->count - 1 - 1 - offset]; | ||||||
|     struct node_parent* to_use = stack->data[stack->count - 1]; |     to_replace->tag = 3; | ||||||
|     memcpy(to_replace, to_use, sizeof(struct node_app)); |     to_replace->next = stack->data[stack->count - 1]; | ||||||
|     stack->count--; |     stack->count--; | ||||||
|     printf("updating\nnew size: %d\n", stack->count); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void stack_alloc(struct stack* stack, int32_t count) { | void stack_alloc(struct stack* stack, int32_t count) { | ||||||
| @ -101,7 +96,6 @@ int32_t stack_size(struct stack* stack) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| struct node_parent* malloc_node_num(int32_t value) { | struct node_parent* malloc_node_num(int32_t value) { | ||||||
|     printf("alloced num %d\n", value); |  | ||||||
|     struct node_num* node = malloc(sizeof(struct node_app)); |     struct node_num* node = malloc(sizeof(struct node_app)); | ||||||
|     node->tag = 0; |     node->tag = 0; | ||||||
|     node->value = value; |     node->value = value; | ||||||
| @ -109,7 +103,6 @@ struct node_parent* malloc_node_num(int32_t value) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| struct node_parent* malloc_node_app(struct node_parent* left, struct node_parent* right) { | struct node_parent* malloc_node_app(struct node_parent* left, struct node_parent* right) { | ||||||
|     printf("allocated application\n"); |  | ||||||
|     struct node_app* node = malloc(sizeof(struct node_app)); |     struct node_app* node = malloc(sizeof(struct node_app)); | ||||||
|     node->tag = 1; |     node->tag = 1; | ||||||
|     node->left = left; |     node->left = left; | ||||||
| @ -117,7 +110,6 @@ struct node_parent* malloc_node_app(struct node_parent* left, struct node_parent | |||||||
|     return (struct node_parent*) node; |     return (struct node_parent*) node; | ||||||
| } | } | ||||||
| struct node_parent* malloc_node_global(int32_t arity, void (*function)(struct stack*)) { | struct node_parent* malloc_node_global(int32_t arity, void (*function)(struct stack*)) { | ||||||
|     printf("allocated global with arity %d\n", arity); |  | ||||||
|     struct node_global* node = malloc(sizeof(struct node_app)); |     struct node_global* node = malloc(sizeof(struct node_app)); | ||||||
|     node->tag = 2; |     node->tag = 2; | ||||||
|     node->arity = arity; |     node->arity = arity; | ||||||
| @ -125,7 +117,6 @@ struct node_parent* malloc_node_global(int32_t arity, void (*function)(struct st | |||||||
|     return (struct node_parent*) node; |     return (struct node_parent*) node; | ||||||
| } | } | ||||||
| struct node_parent* malloc_node_indirect(struct node_parent* target) { | struct node_parent* malloc_node_indirect(struct node_parent* target) { | ||||||
|     printf("allocated indirection node\n"); |  | ||||||
|     struct node_ind* node = malloc(sizeof(struct node_app)); |     struct node_ind* node = malloc(sizeof(struct node_app)); | ||||||
|     node->tag = 3; |     node->tag = 3; | ||||||
|     node->next = target; |     node->next = target; | ||||||
| @ -139,14 +130,17 @@ void unwind(struct stack* stack) { | |||||||
|         if(node->tag == 0) { |         if(node->tag == 0) { | ||||||
|             return; |             return; | ||||||
|         } else if(node->tag == 1) { |         } else if(node->tag == 1) { | ||||||
|             printf("unwinding an application\n"); |  | ||||||
|             stack_push(stack, ((struct node_app*) node)->left); |             stack_push(stack, ((struct node_app*) node)->left); | ||||||
|         } else if(node->tag == 2) { |         } else if(node->tag == 2) { | ||||||
|             struct node_global* global = (struct node_global*) node; |             struct node_global* global = (struct node_global*) node; | ||||||
|             if(stack->size > global->arity) { |             if(stack->size > global->arity) { | ||||||
|                 for(int i = 0; i < global->arity; i++) { |                 struct node_parent* root = stack_peek(stack, global->arity); | ||||||
|                     struct node_app* app = (struct node_app*) stack_peek(stack, i + 1); |                 stack_popn(stack, global->arity + 1); | ||||||
|                     stack_set(stack, i + 1, app->right); |                 stack_push(stack, root); | ||||||
|  |                 while(root->tag == 1) { | ||||||
|  |                     struct node_app* app = (struct node_app*) root; | ||||||
|  |                     stack_push(stack, app->right); | ||||||
|  |                     root = app->left; | ||||||
|                 } |                 } | ||||||
|                 global->function(stack); |                 global->function(stack); | ||||||
|             } else { |             } else { | ||||||
| @ -175,7 +169,4 @@ extern void main_supercomb(struct stack* stack); | |||||||
| 
 | 
 | ||||||
| int main(int argc, char** argv) { | int main(int argc, char** argv) { | ||||||
|     struct node_parent* result = eval(malloc_node_global(0, main_supercomb)); |     struct node_parent* result = eval(malloc_node_global(0, main_supercomb)); | ||||||
|     if(result->tag == 0) { |  | ||||||
|         printf("resulting number: %d\n", ((struct node_num*) result)->value); |  | ||||||
|     } |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -140,7 +140,10 @@ namespace lily { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     void instruction_eval::gen_llvm(llvm_context& ctx) { |     void instruction_eval::gen_llvm(llvm_context& ctx) { | ||||||
|         // ??
 |         llvm::Value* stack = ctx.get_current_function()->arg_begin(); | ||||||
|  |         llvm::Value* top = builder.CreateCall(stack_pop_func, { stack }, "temp"); | ||||||
|  |         llvm::Value* evaluated = builder.CreateCall(eval_func, { top }, "temp"); | ||||||
|  |         builder.CreateCall(stack_push_func, { stack, evaluated }); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     void instruction_op::gen_llvm(llvm_context& ctx) { |     void instruction_op::gen_llvm(llvm_context& ctx) { | ||||||
|  | |||||||
| @ -37,6 +37,8 @@ namespace lily { | |||||||
|     llvm::Function* malloc_node_global_func; |     llvm::Function* malloc_node_global_func; | ||||||
|     llvm::Function* malloc_node_ind_func; |     llvm::Function* malloc_node_ind_func; | ||||||
| 
 | 
 | ||||||
|  |     llvm::Function* eval_func; | ||||||
|  | 
 | ||||||
|     llvm::IntegerType* tag_type; |     llvm::IntegerType* tag_type; | ||||||
|     llvm::PointerType* node_pointer_type; |     llvm::PointerType* node_pointer_type; | ||||||
|     llvm::StructType* node_parent_type; |     llvm::StructType* node_parent_type; | ||||||
| @ -131,10 +133,15 @@ namespace lily { | |||||||
|                 "malloc_node_global", |                 "malloc_node_global", | ||||||
|                 &module); |                 &module); | ||||||
|         malloc_node_ind_func = llvm::Function::Create( |         malloc_node_ind_func = llvm::Function::Create( | ||||||
|                 llvm::FunctionType::get(llvm::PointerType::getUnqual(node_parent_type), { node_pointer_type }, false), |                 llvm::FunctionType::get(node_pointer_type, { node_pointer_type }, false), | ||||||
|                 llvm::Function::LinkageTypes::ExternalLinkage, |                 llvm::Function::LinkageTypes::ExternalLinkage, | ||||||
|                 "malloc_node_indirect", |                 "malloc_node_indirect", | ||||||
|                 &module); |                 &module); | ||||||
|  |         eval_func = llvm::Function::Create( | ||||||
|  |                 llvm::FunctionType::get(node_pointer_type, { node_pointer_type }, false), | ||||||
|  |                 llvm::Function::LinkageTypes::ExternalLinkage, | ||||||
|  |                 "eval", | ||||||
|  |                 &module); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     static void initialize_types() { |     static void initialize_types() { | ||||||
|  | |||||||
| @ -32,6 +32,8 @@ namespace lily { | |||||||
|     extern llvm::Function* malloc_node_app_func; |     extern llvm::Function* malloc_node_app_func; | ||||||
|     extern llvm::Function* malloc_node_global_func; |     extern llvm::Function* malloc_node_global_func; | ||||||
|     extern llvm::Function* malloc_node_ind_func; |     extern llvm::Function* malloc_node_ind_func; | ||||||
|  |      | ||||||
|  |     extern llvm::Function* eval_func; | ||||||
| 
 | 
 | ||||||
|     extern llvm::IntegerType* tag_type; |     extern llvm::IntegerType* tag_type; | ||||||
|     extern llvm::PointerType* node_pointer_type; |     extern llvm::PointerType* node_pointer_type; | ||||||
|  | |||||||
| @ -8,7 +8,8 @@ int main() { | |||||||
|     try { |     try { | ||||||
| 
 | 
 | ||||||
|         lily::program_ptr prog = lily::parse( |         lily::program_ptr prog = lily::parse( | ||||||
|                 "defn main = { 163 * 2 }" |                 "defn magic x y = { let z = { x + y } in  { 326 + z + z } }\n" | ||||||
|  |                 "defn main = { magic 1 2 }" | ||||||
|                 ); |                 ); | ||||||
|         prog->gen_llvm(); |         prog->gen_llvm(); | ||||||
|     } catch(lily::error& e) { |     } catch(lily::error& e) { | ||||||
|  | |||||||
| @ -296,9 +296,9 @@ namespace lily { | |||||||
|     template <binop o> |     template <binop o> | ||||||
|     static void generate_binop(instruction_manager& mgr, std::map<std::string, std::vector<instruction*>>& into) { |     static void generate_binop(instruction_manager& mgr, std::map<std::string, std::vector<instruction*>>& into) { | ||||||
|         std::vector<instruction*> dest; |         std::vector<instruction*> dest; | ||||||
|         dest.push_back(mgr.add_instruction<instruction_push>(2)); |         dest.push_back(mgr.add_instruction<instruction_push>(1)); | ||||||
|         dest.push_back(mgr.add_instruction<instruction_eval>()); |         dest.push_back(mgr.add_instruction<instruction_eval>()); | ||||||
|         dest.push_back(mgr.add_instruction<instruction_push>(2)); |         dest.push_back(mgr.add_instruction<instruction_push>(1)); | ||||||
|         dest.push_back(mgr.add_instruction<instruction_eval>()); |         dest.push_back(mgr.add_instruction<instruction_eval>()); | ||||||
|         dest.push_back(mgr.add_instruction<instruction_op>(o)); |         dest.push_back(mgr.add_instruction<instruction_op>(o)); | ||||||
|         dest.push_back(mgr.add_instruction<instruction_update>(2)); |         dest.push_back(mgr.add_instruction<instruction_update>(2)); | ||||||
| @ -323,9 +323,6 @@ namespace lily { | |||||||
|                 new_env->set_parent(fresh_env); |                 new_env->set_parent(fresh_env); | ||||||
|                 fresh_env = new_env; |                 fresh_env = new_env; | ||||||
|             } |             } | ||||||
|             auto new_env = std::make_shared<compile_env_offset>(1); |  | ||||||
|             new_env->set_parent(fresh_env); |  | ||||||
|             fresh_env = new_env; |  | ||||||
| 
 | 
 | ||||||
|             std::vector<instruction*> destination; |             std::vector<instruction*> destination; | ||||||
|             pair.second.body->compile(mgr, destination, fresh_env); |             pair.second.body->compile(mgr, destination, fresh_env); | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user