Commit 016c82fe authored by Laszlo Domoszlai's avatar Laszlo Domoszlai
Browse files

remove force variable from exec, split it into exec and create_thunk

parent d745f3d0
......@@ -7,12 +7,87 @@
#include "mem.h"
#include "desc.h"
void exec(Code* expr, int frame_ptr, int root_frame_ptr, bool force)
void create_thunk(Code* expr, int frame_ptr, int root_frame_ptr)
{
assert(expr != NULL);
switch (expr->type) {
case CT_LIT:
set_return(root_frame_ptr, updateT(get_dst(root_frame_ptr), &((LitEntry*) expr)->thunk));
destroy_stack_frame(root_frame_ptr);
return;
case CT_VAR:
if (expr->local_type == VAR_LOCAL) {
Thunk* thunk = forward_to(get_dst(root_frame_ptr), local(frame_ptr, ((VarEntry*) expr)->index));
destroy_stack_frame(root_frame_ptr);
set_return(root_frame_ptr, thunk);
return;
}else{
destroy_stack_frame(root_frame_ptr);
set_return(root_frame_ptr, updateF(get_dst(root_frame_ptr), get_slice(((VarEntry*) expr)->f, 0)));
return;
}
case CT_APP:
{
// TODO: check over application
// TODO: enforce strictness in ADT/Record
VarEntry* var = &((AppEntry*) expr)->var;
if (var->base.local_type == VAR_LOCAL)
{
// TODO: force
Thunk* basethunk = eval(local(frame_ptr, var->index));
Desc* slice =
get_slice(basethunk->desc->type == FT_SLICE ?
((SliceEntry*) basethunk->desc)->forward_ptr : basethunk->desc, basethunk->desc->arity + expr->nr_args);
Thunk* thunk = updateF(get_dst(root_frame_ptr), slice);
assert(thunk->desc->arity == basethunk->desc->arity + expr->nr_args);
for (int i = 0; i < basethunk->desc->arity; i++) {
thunk->_args[i] = basethunk->_args[i];
}
for (int i = 0; i < expr->nr_args; i++) {
push_a(NULL);
create_thunk(((AppEntry*) expr)->args[i], frame_ptr, stack_top_a);
thunk->_args[basethunk->desc->arity + i] = pop_a();
}
set_return(root_frame_ptr, thunk);
destroy_stack_frame(root_frame_ptr);
return;
}
else
{
Thunk* thunk = updateF(get_dst(root_frame_ptr), get_slice(var->f, expr->nr_args));
assert(thunk->desc->arity == expr->nr_args);
for (int i = 0; i < expr->nr_args; i++) {
push_a(NULL);
create_thunk(((AppEntry*) expr)->args[i], frame_ptr, stack_top_a);
thunk->_args[i] = pop_a();
}
set_return(root_frame_ptr, thunk);
destroy_stack_frame(root_frame_ptr);
return;
}
break;
}
}
}
void exec(Code* expr, int frame_ptr, int root_frame_ptr)
{
while(1)
{
assert(expr != NULL);
assert(stack_top_a < STACK_SIZE_A);
switch (expr->type) {
......@@ -26,12 +101,8 @@ void exec(Code* expr, int frame_ptr, int root_frame_ptr, bool force)
// Destroy stack frame before eval, it is not needed any more
// Greatly reduces stack usage
destroy_stack_frame(root_frame_ptr);
// TODO: inline eval
if(force) thunk = eval(thunk);
set_return(root_frame_ptr, thunk);
destroy_stack_frame(root_frame_ptr);
set_return(root_frame_ptr, eval(thunk));
return;
}else{
// Safe to destroy, the next call has no arguments
......@@ -39,7 +110,7 @@ void exec(Code* expr, int frame_ptr, int root_frame_ptr, bool force)
Desc* slice = get_slice(((VarEntry*) expr)->f, 0);
if(force && slice->type == FT_FUN)
if(slice->type == FT_FUN)
{
expr = ((FunEntry*)slice)->body;
continue;
......@@ -77,7 +148,7 @@ void exec(Code* expr, int frame_ptr, int root_frame_ptr, bool force)
for (int i = 0; i < expr->nr_args; i++) {
push_a(NULL);
exec(((AppEntry*) expr)->args[i], frame_ptr, stack_top_a, false);
create_thunk(((AppEntry*) expr)->args[i], frame_ptr, stack_top_a);
thunk->_args[basethunk->desc->arity + i] = pop_a();
}
......@@ -89,25 +160,32 @@ void exec(Code* expr, int frame_ptr, int root_frame_ptr, bool force)
{
Desc* slice = get_slice(var->f, expr->nr_args);
if (force && slice->type == FT_PRIM) {
if (slice->type == FT_PRIM) {
Thunk args[expr->nr_args];
for (int i = 0; i < expr->nr_args; i++) {
push_a(&args[i]);
exec(((AppEntry*) expr)->args[i], frame_ptr, stack_top_a, true);
exec(((AppEntry*) expr)->args[i], frame_ptr, stack_top_a);
}
((PrimEntry*) slice)->exec(root_frame_ptr);
destroy_stack_frame(root_frame_ptr);
return;
}
else if (force && slice->type == FT_FUN) {
else if (slice->type == FT_FUN) {
int new_frame_ptr = stack_top_a;
for (int i = 0; i < expr->nr_args; i++) {
push_a(NULL);
exec(((AppEntry*) expr)->args[i], frame_ptr, stack_top_a, is_strict_fun_arg((FunEntry*) slice, i));
if(is_strict_fun_arg((FunEntry*) slice, i))
{
exec(((AppEntry*) expr)->args[i], frame_ptr, stack_top_a);
}
else
{
create_thunk(((AppEntry*) expr)->args[i], frame_ptr, stack_top_a);
}
}
expr = ((FunEntry*) slice)->body;
......@@ -121,7 +199,7 @@ void exec(Code* expr, int frame_ptr, int root_frame_ptr, bool force)
for (int i = 0; i < expr->nr_args; i++) {
push_a(NULL);
exec(((AppEntry*) expr)->args[i], frame_ptr, stack_top_a, false);
create_thunk(((AppEntry*) expr)->args[i], frame_ptr, stack_top_a);
thunk->_args[i] = pop_a();
}
......@@ -135,7 +213,7 @@ void exec(Code* expr, int frame_ptr, int root_frame_ptr, bool force)
case CT_SELECT:
{
push_a(NULL);
exec(((SelectEntry*) expr)->expr, frame_ptr, stack_top_a, true);
exec(((SelectEntry*) expr)->expr, frame_ptr, stack_top_a);
Thunk* pattern = eval(pop_a());
bool handled = false;
......@@ -177,7 +255,7 @@ void exec(Code* expr, int frame_ptr, int root_frame_ptr, bool force)
tmp.desc = (Desc*) __BOOL__;
push_a(&tmp);
exec(((IfEntry*) expr)->cond, frame_ptr, stack_top_a, true);
exec(((IfEntry*) expr)->cond, frame_ptr, stack_top_a);
Thunk* cond = eval(pop_a());
if (readB(cond)) {
......
......@@ -72,6 +72,6 @@ struct IfEntry {
struct Code* fexpr;
};
void exec(Code* expr, int frame_ptr, int root_frame_ptr, bool force);
void exec(Code* expr, int frame_ptr, int root_frame_ptr);
#endif // __CODE_H
\ No newline at end of file
......@@ -85,7 +85,7 @@ int main ( int argc, char *argv[] )
#endif
push_a(NULL);
exec(expr, stack_top_a, stack_top_a, true);
exec(expr, stack_top_a, stack_top_a);
Thunk* res = eval(pop_a());
#ifdef DEBUG
......
......@@ -129,7 +129,7 @@ struct Thunk* eval(Thunk* thunk) {
// TODO: handle strictness
push_a(thunk->_args[i]);
}
exec(((FunEntry*) thunk->desc)->body, frame_ptr, frame_ptr, true);
exec(((FunEntry*) thunk->desc)->body, frame_ptr, frame_ptr);
thunk = pop_a();
}
else if(thunk->desc->type == FT_PRIM) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment