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