Commit 7e6dc3ba authored by Laszlo Domoszlai's avatar Laszlo Domoszlai
Browse files

small stuff

parent 7f90e896
TARGET = main
LIBS =
CC = g++
CFLAGS = -g -Wno-write-strings # -fstack-usage
CFLAGS = -O3 -Wno-write-strings # -g -pg -fstack-usage
.PHONY: default all clean
......@@ -17,7 +17,7 @@ HEADERS = $(wildcard *.h)
.PRECIOUS: $(TARGET) $(OBJECTS)
$(TARGET): $(OBJECTS)
$(CC) $(OBJECTS) -static -static-libgcc -static-libstdc++ -Wl,--stack,16777216 -g -Wall $(LIBS) -o $@
$(CC) $(OBJECTS) -static -static-libgcc -static-libstdc++ -Wl,--stack,16777216 -Wall $(LIBS) -o $@ # -pg -g
clean:
-rm -f *.o
......
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <strings.h>
#include "debug.h"
#include "code.h"
......@@ -19,8 +20,8 @@
dst->_forward_ptr = thunk; \
}
#define arg_from_thunk(desc, arg) \
if(((FunEntry*) (desc))->strictness & argmask) \
#define arg_from_thunk(descarg, arg) \
if(((FunEntry*) (descarg))->strictness & argmask && !arg->desc->hnf) \
{ \
push_a(eval(arg)); \
} \
......@@ -36,7 +37,7 @@
Thunk* phl = alloc_b(); \
phl->desc = (Desc*) __STACK_PLACEHOLDER__; \
push_a(phl); \
exec(arg, frame_ptr, stack_top_a, stack_top_b); \
exec(arg, frame_ptr, stack_top_a); \
} \
else \
{ \
......@@ -48,7 +49,7 @@
struct Thunk* create_thunk(Code* expr, int frame_ptr)
{
assert(expr != NULL);
// TODO: check over application
// TODO: enforce strictness in ADT/Record
......@@ -68,7 +69,7 @@ struct Thunk* create_thunk(Code* expr, int frame_ptr)
case CT_APP_DYN:
{
Thunk* basethunk = local(frame_ptr, ((AppEntry*)expr)->var.index);
if(!((AppEntry*)expr)->var.base.strict) basethunk = eval(basethunk);
if(!basethunk->desc->hnf) basethunk = eval(basethunk);
Desc* slice =
get_slice(basethunk->desc->type == FT_SLICE ?
......@@ -78,10 +79,8 @@ struct Thunk* create_thunk(Code* expr, int frame_ptr)
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];
}
memcpy(&thunk->_args, &basethunk->_args, sizeof(Thunk*) * basethunk->desc->arity);
for (int i = 0; i < expr->nr_args; i++) {
thunk->_args[basethunk->desc->arity + i]
= create_thunk(((AppEntry*) expr)->args[i], frame_ptr);
......@@ -113,8 +112,10 @@ struct Thunk* create_thunk(Code* expr, int frame_ptr)
}
}
void exec(Code* expr, int frame_ptr, int root_frame_ptr, int root_frame_ptr_b)
void exec(Code* expr, int frame_ptr, int root_frame_ptr)
{
int root_frame_ptr_b = stack_top_b;
while(1)
{
assert(expr != NULL);
......@@ -133,7 +134,7 @@ void exec(Code* expr, int frame_ptr, int root_frame_ptr, int root_frame_ptr_b)
{
for (int i = 0; i < expr->nr_args; i++) {
push_a(alloc_b());
exec(((AppEntry*) expr)->args[i], frame_ptr, stack_top_a, stack_top_b);
exec(((AppEntry*) expr)->args[i], frame_ptr, stack_top_a);
}
((PrimEntry*) slice)->exec(root_frame_ptr);
......@@ -182,7 +183,7 @@ void exec(Code* expr, int frame_ptr, int root_frame_ptr, int root_frame_ptr_b)
case CT_APP_DYN:
{
Thunk* basethunk = local(frame_ptr, ((AppEntry*)expr)->var.index);
if(!((AppEntry*)expr)->var.base.strict) basethunk = eval(basethunk);
if(!basethunk->desc->hnf) basethunk = eval(basethunk);
Desc* slice =
get_slice(basethunk->desc->type == FT_SLICE ?
......@@ -192,12 +193,19 @@ void exec(Code* expr, int frame_ptr, int root_frame_ptr, int root_frame_ptr_b)
case FT_PRIM:
{
for (int i = 0; i < basethunk->desc->arity; i++) {
push_a(eval(basethunk->_args[i]));
if(basethunk->_args[i]->desc->hnf)
{
push_a(basethunk->_args[i]);
}
else
{
push_a(eval(basethunk->_args[i]));
}
}
for (int i = 0; i < expr->nr_args; i++) {
push_a(alloc_b());
exec(((AppEntry*) expr)->args[i], frame_ptr, stack_top_a, stack_top_b);
exec(((AppEntry*) expr)->args[i], frame_ptr, stack_top_a);
}
((PrimEntry*) slice)->exec(root_frame_ptr);
......@@ -230,9 +238,7 @@ void exec(Code* expr, int frame_ptr, int root_frame_ptr, int root_frame_ptr_b)
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];
}
memcpy(&thunk->_args, &basethunk->_args, sizeof(Thunk*) * basethunk->desc->arity);
for (int i = 0; i < expr->nr_args; i++) {
thunk->_args[basethunk->desc->arity + i]
......@@ -335,7 +341,7 @@ void exec(Code* expr, int frame_ptr, int root_frame_ptr, int root_frame_ptr_b)
case CT_SELECT:
{
push_a(NULL);
exec(((SelectEntry*) expr)->expr, frame_ptr, stack_top_a, stack_top_b);
exec(((SelectEntry*) expr)->expr, frame_ptr, stack_top_a);
Thunk* pattern = pop_a();
assert(is_hnf(pattern));
......@@ -375,7 +381,7 @@ void exec(Code* expr, int frame_ptr, int root_frame_ptr, int root_frame_ptr_b)
case CT_IF:
{
push_a(alloc_b());
exec(((IfEntry*) expr)->cond, frame_ptr, stack_top_a, stack_top_b);
exec(((IfEntry*) expr)->cond, frame_ptr, stack_top_a);
Thunk* cond = pop_a();
if (readB(cond)) {
......@@ -407,7 +413,7 @@ struct Thunk* eval(Thunk* thunk) {
arg_from_thunk(thunk->desc, thunk->_args[i]);
}
exec(((FunEntry*) thunk->desc)->body, frame_ptr, frame_ptr, stack_top_b);
exec(((FunEntry*) thunk->desc)->body, frame_ptr, frame_ptr);
thunk = pop_a();
return thunk;
}
......@@ -417,7 +423,14 @@ struct Thunk* eval(Thunk* thunk) {
int frame_ptr = stack_top_a;
for (int i = 0; i < thunk->desc->arity; i++) {
push_a(eval(thunk->_args[i]));
if(thunk->_args[i]->desc->hnf)
{
push_a(thunk->_args[i]);
}
else
{
push_a(eval(thunk->_args[i]));
}
}
((PrimEntry*) thunk->desc)->exec(frame_ptr);
......
......@@ -60,7 +60,7 @@ struct IfEntry {
struct Code* fexpr;
};
void exec(Code* expr, int frame_ptr, int root_frame_ptr, int root_frame_ptr_b);
void exec(Code* expr, int frame_ptr, int root_frame_ptr);
struct Thunk* eval(Thunk* thunk);
#endif // __CODE_H
\ No newline at end of file
......@@ -46,6 +46,7 @@ FunEntry* alloc_prim(char* name, int unboxable) {
entry->base.arity = 0;
entry->base.thunk_size = sizeof(Thunk);
entry->base.unboxable = unboxable;
entry->base.hnf = 1;
memcpy(entry->name, name, len + 1);
return entry;
}
......@@ -56,6 +57,8 @@ void gen_slices(SliceEntry* dest, Desc* forward_ptr, int arity) {
slice->base.type = FT_SLICE;
slice->base.arity = i;
slice->base.thunk_size = thunk_size_f(i);
slice->base.unboxable = false;
slice->base.hnf = true;
slice->forward_ptr = forward_ptr;
}
}
......@@ -86,27 +89,47 @@ int printDesc(Desc* f) {
void init_desc() {
__INT__ = alloc_prim("INT", 1);
__INT_SHARED__ = alloc_prim("INT", 0);
__BOOL__ = alloc_prim("BOOL", 1);
__BOOL_SHARED__ = alloc_prim("BOOL", 0);
__CHAR__ = alloc_prim("CHAR", 1);
__CHAR_SHARED__ = alloc_prim("CHAR", 0);
__REAL__ = alloc_prim("REAL", 1);
__REAL_SHARED__ = alloc_prim("REAL", 0);
__STRING__ = alloc_prim("STRING", 0);
__ARRAY__ = alloc_prim("ARRAY", 0);
__FORWARD_PTR__ = alloc_prim("FWD", 0);
__FORWARD_PTR__->base.hnf = false;
// Avoid to be overwritten by updateF
__STACK_PLACEHOLDER__ = alloc_prim("PLACEHOLDER", 0);
__STACK_PLACEHOLDER__->base.thunk_size = 0;
__FALSE__ = (Thunk*) alloc_code(sizeof(Thunk));
__FALSE__->desc = (Desc*) __BOOL_SHARED__;
__FALSE__->_bool = false;
__TRUE__ = (Thunk*) alloc_code(sizeof(Thunk));
__TRUE__->desc = (Desc*) __BOOL_SHARED__;
__TRUE__->_bool = true;
}
struct FunEntry* __INT__;
struct FunEntry* __INT_SHARED__;
struct FunEntry* __BOOL__;
struct FunEntry* __BOOL_SHARED__;
struct FunEntry* __CHAR__;
struct FunEntry* __CHAR_SHARED__;
struct FunEntry* __REAL__;
struct FunEntry* __REAL_SHARED__;
struct FunEntry* __STRING__;
struct FunEntry* __ARRAY__;
struct FunEntry* __FORWARD_PTR__;
struct FunEntry* __STACK_PLACEHOLDER__;
struct Thunk* __FALSE__;
struct Thunk* __TRUE__;
......@@ -66,9 +66,13 @@ Desc* get_slice(Desc* f, int nrargs);
int printDesc(Desc* f);
extern struct FunEntry* __INT__;
extern struct FunEntry* __INT_SHARED__;
extern struct FunEntry* __BOOL__;
extern struct FunEntry* __BOOL_SHARED__;
extern struct FunEntry* __CHAR__;
extern struct FunEntry* __CHAR_SHARED__;
extern struct FunEntry* __REAL__;
extern struct FunEntry* __REAL_SHARED__;
extern struct FunEntry* __STRING__;
extern struct FunEntry* __ARRAY__;
......@@ -76,4 +80,7 @@ extern struct FunEntry* __ARRAY__;
extern struct FunEntry* __FORWARD_PTR__;
extern struct FunEntry* __STACK_PLACEHOLDER__;
extern struct Thunk* __FALSE__;
extern struct Thunk* __TRUE__;
#endif // __DESC_H
\ No newline at end of file
......@@ -10,6 +10,7 @@ struct Desc {
unsigned int arity : 8; // LIMITATION: maximum 32 arguments
unsigned int thunk_size : 10; // It gives false result for strings and arrays
unsigned int unboxable : 1;
unsigned int hnf : 1;
};
#endif // __DESC_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, stack_top_b);
exec(expr, stack_top_a, stack_top_a);
Thunk* res = pop_a();
#ifdef BENCHMARK
......
......@@ -47,12 +47,15 @@ void* alloc_code(int size) {
}
void* alloc_heap(int size) {
char* curr = heap_start + heap_alloc;
heap_alloc += size;
nr_heap_alloc++;
#if DEBUG
nr_heap_alloc++;
#endif
assert(heap_alloc < heap_size);
return curr;
......
......@@ -90,7 +90,9 @@ int parseDef1(char** ptr) {
entry->base.type = FT_FUN;
entry->base.arity = arity;
entry->base.thunk_size = thunk_size_f(arity);
entry->base.unboxable = false;
entry->base.hnf = false;
// now the name can be copied into the FunEntry
memcpy(entry->name, namePtr, nameLength);
entry->name[nameLength] = '\0';
......@@ -120,7 +122,9 @@ int parseDef1(char** ptr) {
entry->base.type = FT_CAF;
entry->base.arity = 0;
entry->base.thunk_size = thunk_size_f(0);
entry->base.unboxable = false;
entry->base.hnf = false;
copyStringAndForward(entry->name, ptr, nameLength);
// set the continuation for stage 2
......@@ -159,6 +163,8 @@ int parseDef1(char** ptr) {
entry->base.type = FT_ADT;
entry->base.arity = arity;
entry->base.thunk_size = thunk_size_f(arity);
entry->base.unboxable = false;
entry->base.hnf = true;
// now the name can be copied into the ADTEntry
memcpy(entry->name, namePtr, nameLength);
......@@ -195,6 +201,8 @@ int parseDef1(char** ptr) {
if (!parseInt(ptr, &entry->strictness)) return 0;
entry->base.thunk_size = thunk_size_f(arity);
entry->base.unboxable = false;
entry->base.hnf = true;
entry->fields = (char**) alloc_desc(sizeof (char*) * arity);
for (int i = 0; i < arity; i++) {
......@@ -232,21 +240,21 @@ ThunkEntry* parseLit(char **ptr) {
switch (type) {
case 'I': // Int
{
entry->thunk.desc = (Desc*) __INT__;
entry->thunk.desc = (Desc*) __INT_SHARED__;
if (!parseInt(ptr, &entry->thunk._int)) return 0;
break;
}
case 'C': // Char
{
entry->thunk.desc = (Desc*) __CHAR__;
entry->thunk.desc = (Desc*) __CHAR_SHARED__;
entry->thunk._char = *(*ptr)++;
break;
}
case 'R': // Real
{
entry->thunk.desc = (Desc*) __REAL__;
entry->thunk.desc = (Desc*) __REAL_SHARED__;
if (!parseReal(ptr, &entry->thunk._real)) return 0;
break;
}
......@@ -254,7 +262,7 @@ ThunkEntry* parseLit(char **ptr) {
case '0': // Bool
case '1':
{
entry->thunk.desc = (Desc*) __BOOL__;
entry->thunk.desc = (Desc*) __BOOL_SHARED__;
entry->thunk._bool = type == '1';
break;
}
......
......@@ -53,6 +53,8 @@ void add_prim(int arity, int strictness, char* name, void (*exec)(int)) {
entry->base.type = FT_PRIM;
entry->base.arity = arity;
entry->strictness = strictness;
entry->base.thunk_size = thunk_size_f(arity);
entry->base.hnf = false;
entry->exec = exec;
// TODO: should it be copied at all?
......@@ -72,5 +74,5 @@ void init_prim() {
add_prim(2, 3, "lt", &__lt);
add_prim(2, 3, "eqI", &__eqI);
add_prim(2, 3, "eqB", &__eqB);
add_prim(1, 1, "not", &__not);
add_prim(1, 1, "not", &__not);
}
......@@ -12,7 +12,7 @@
int readI(Thunk* thunk) {
assert(thunk != NULL);
if (thunk->desc != (Desc*) __INT__) {
if (thunk->desc != (Desc*) __INT__ || thunk->desc != (Desc*) __INT_SHARED__) {
printf("readI: not an integer: ");
printDesc(thunk->desc);
exit(-1);
......@@ -24,8 +24,7 @@ int readI(Thunk* thunk) {
int readB(Thunk* thunk) {
assert(thunk != NULL);
if (thunk->desc != (Desc*) __BOOL__) {
if (thunk->desc != (Desc*) __BOOL__ || thunk->desc != (Desc*) __BOOL_SHARED__) {
printf("readB: not a boolean: ");
printDesc(thunk->desc);
exit(-1);
......@@ -45,8 +44,11 @@ struct Thunk* updateI(Thunk* target, int i) {
}
struct Thunk* updateB(Thunk* target, int b) {
if (target == NULL) target = (Thunk*) alloc_heap(sizeof (Thunk));
if (target == NULL)
{
return b ? __TRUE__ : __FALSE__;
}
// always can be overwritten with boxed integer
target->desc = (Desc*) __BOOL__;
target->_bool = b;
......@@ -65,7 +67,7 @@ struct Thunk* updateF(Thunk* target, Desc* f) {
Thunk* thunk = target;
int newsize = f->thunk_size;
if (thunk == NULL) {
thunk = (Thunk*) alloc_heap(newsize);
} else {
......@@ -84,7 +86,7 @@ struct Thunk* updateF(Thunk* target, Desc* f) {
struct Thunk* createF(Desc* f) {
assert(f != NULL);
Thunk* thunk = (Thunk*) alloc_heap(f->thunk_size);
thunk->desc = f;
return thunk;
......@@ -109,15 +111,15 @@ void print(Thunk* thunk, bool force) {
printf("[");
if (thunk->desc->type == FT_BOXED_LIT) {
if ((FunEntry*) thunk->desc == __INT__) {
if ((FunEntry*) thunk->desc == __INT__ || (FunEntry*) thunk->desc == __INT_SHARED__) {
printf("%d", thunk->_int);
} else if ((FunEntry*) thunk->desc == __BOOL__) {
} else if ((FunEntry*) thunk->desc == __BOOL__ || (FunEntry*) thunk->desc == __BOOL_SHARED__) {
if (thunk->_bool) {
printf("True");
} else {
printf("False");
}
} else if ((FunEntry*) thunk->desc == __CHAR__) {
} else if ((FunEntry*) thunk->desc == __CHAR__ || (FunEntry*) thunk->desc == __CHAR_SHARED__) {
printf("%c", thunk->_char);
} else {
printf("print: unhandled BOXED LIT\n");
......
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