From e6f31f8c5b272668f8df246e284bb8dae8038bc8 Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Wed, 12 Jun 2019 03:33:35 -0700 Subject: [PATCH] Fix unwind bug and add eval. --- runtime.c | 29 ++++++++++------------------- src/gmachine.cpp | 5 ++++- src/llvm.cpp | 9 ++++++++- src/llvm.hpp | 2 ++ src/main.cpp | 3 ++- src/parser.cpp | 7 ++----- 6 files changed, 28 insertions(+), 27 deletions(-) diff --git a/runtime.c b/runtime.c index 0b1c412..e80c626 100644 --- a/runtime.c +++ b/runtime.c @@ -46,10 +46,8 @@ void stack_free(struct stack* stack) { } void stack_push(struct stack* stack, struct node_parent* node) { - printf("pushing\n"); assert(stack->count < stack->size); stack->data[stack->count++] = node; - printf("new size: %d\n", stack->count); } 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) { - printf("popping\nnew size: %d\n", stack->count - 1); assert(stack->count > 0); 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) { assert(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) { assert(stack->count >= offset + 2); - struct node_parent* to_replace = stack->data[stack->count - 1 - 1 - offset]; - struct node_parent* to_use = stack->data[stack->count - 1]; - memcpy(to_replace, to_use, sizeof(struct node_app)); + struct node_ind* to_replace = (struct node_ind*) stack->data[stack->count - 1 - 1 - offset]; + to_replace->tag = 3; + to_replace->next = stack->data[stack->count - 1]; stack->count--; - printf("updating\nnew size: %d\n", stack->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) { - printf("alloced num %d\n", value); struct node_num* node = malloc(sizeof(struct node_app)); node->tag = 0; 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) { - printf("allocated application\n"); struct node_app* node = malloc(sizeof(struct node_app)); node->tag = 1; 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; } 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)); node->tag = 2; 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; } struct node_parent* malloc_node_indirect(struct node_parent* target) { - printf("allocated indirection node\n"); struct node_ind* node = malloc(sizeof(struct node_app)); node->tag = 3; node->next = target; @@ -139,14 +130,17 @@ void unwind(struct stack* stack) { if(node->tag == 0) { return; } else if(node->tag == 1) { - printf("unwinding an application\n"); stack_push(stack, ((struct node_app*) node)->left); } else if(node->tag == 2) { struct node_global* global = (struct node_global*) node; if(stack->size > global->arity) { - for(int i = 0; i < global->arity; i++) { - struct node_app* app = (struct node_app*) stack_peek(stack, i + 1); - stack_set(stack, i + 1, app->right); + struct node_parent* root = stack_peek(stack, global->arity); + stack_popn(stack, global->arity + 1); + 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); } else { @@ -175,7 +169,4 @@ extern void main_supercomb(struct stack* stack); int main(int argc, char** argv) { 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); - } } diff --git a/src/gmachine.cpp b/src/gmachine.cpp index c6a2094..f61e643 100644 --- a/src/gmachine.cpp +++ b/src/gmachine.cpp @@ -140,7 +140,10 @@ namespace lily { } 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) { diff --git a/src/llvm.cpp b/src/llvm.cpp index e26620b..c672d80 100644 --- a/src/llvm.cpp +++ b/src/llvm.cpp @@ -37,6 +37,8 @@ namespace lily { llvm::Function* malloc_node_global_func; llvm::Function* malloc_node_ind_func; + llvm::Function* eval_func; + llvm::IntegerType* tag_type; llvm::PointerType* node_pointer_type; llvm::StructType* node_parent_type; @@ -131,10 +133,15 @@ namespace lily { "malloc_node_global", &module); 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, "malloc_node_indirect", &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() { diff --git a/src/llvm.hpp b/src/llvm.hpp index 8816b91..50bb06c 100644 --- a/src/llvm.hpp +++ b/src/llvm.hpp @@ -32,6 +32,8 @@ namespace lily { extern llvm::Function* malloc_node_app_func; extern llvm::Function* malloc_node_global_func; extern llvm::Function* malloc_node_ind_func; + + extern llvm::Function* eval_func; extern llvm::IntegerType* tag_type; extern llvm::PointerType* node_pointer_type; diff --git a/src/main.cpp b/src/main.cpp index 2a4b19a..cf95faa 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -8,7 +8,8 @@ int main() { try { 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(); } catch(lily::error& e) { diff --git a/src/parser.cpp b/src/parser.cpp index 819c3f3..968af03 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -296,9 +296,9 @@ namespace lily { template static void generate_binop(instruction_manager& mgr, std::map>& into) { std::vector dest; - dest.push_back(mgr.add_instruction(2)); + dest.push_back(mgr.add_instruction(1)); dest.push_back(mgr.add_instruction()); - dest.push_back(mgr.add_instruction(2)); + dest.push_back(mgr.add_instruction(1)); dest.push_back(mgr.add_instruction()); dest.push_back(mgr.add_instruction(o)); dest.push_back(mgr.add_instruction(2)); @@ -323,9 +323,6 @@ namespace lily { new_env->set_parent(fresh_env); fresh_env = new_env; } - auto new_env = std::make_shared(1); - new_env->set_parent(fresh_env); - fresh_env = new_env; std::vector destination; pair.second.body->compile(mgr, destination, fresh_env);