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

View File

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

View File

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

View File

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

View File

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

View File

@ -296,9 +296,9 @@ namespace lily {
template <binop o>
static void generate_binop(instruction_manager& mgr, std::map<std::string, std::vector<instruction*>>& into) {
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_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_op>(o));
dest.push_back(mgr.add_instruction<instruction_update>(2));
@ -323,9 +323,6 @@ namespace lily {
new_env->set_parent(fresh_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;
pair.second.body->compile(mgr, destination, fresh_env);