Fix unwind bug and add eval.

This commit is contained in:
Danila Fedorin 2019-06-12 03:33:35 -07:00
parent 37f5e53a59
commit e6f31f8c5b
6 changed files with 28 additions and 27 deletions

View File

@ -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);
}
} }

View File

@ -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) {

View File

@ -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() {

View File

@ -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;

View File

@ -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) {

View File

@ -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);