#include #include "prim.h" #include "desc.h" #include "thunk.h" #include "mem.h" #define arg(idx) stack_a[stack_top_a - idx] void __add(int dst_idx) { Thunk* target = get_dst(dst_idx); target->desc = (Desc*) __INT__; target->_int = readI(arg(2)) + readI(arg(1)); } void __sub(int dst_idx) { Thunk* target = get_dst(dst_idx); target->desc = (Desc*) __INT__; target->_int = readI(arg(2)) - readI(arg(1)); } void __mult(int dst_idx) { Thunk* target = get_dst(dst_idx); target->desc = (Desc*) __INT__; target->_int = readI(arg(2)) * readI(arg(1)); } void __div(int dst_idx) { Thunk* target = get_dst(dst_idx); target->desc = (Desc*) __INT__; target->_int = readI(arg(2)) / readI(arg(1)); } void __gt(int dst_idx) { Thunk* target = get_dst(dst_idx); target->desc = (Desc*) __BOOL__; target->_bool = readI(arg(2)) > readI(arg(1)); } void __lt(int dst_idx) { Thunk* target = get_dst(dst_idx); target->desc = (Desc*) __BOOL__; target->_bool = readI(arg(2)) < readI(arg(1)); } void __geC(int dst_idx) { Thunk* target = get_dst(dst_idx); target->desc = (Desc*) __BOOL__; target->_bool = readC(arg(2)) >= readC(arg(1)); } void __eqI(int dst_idx) { Thunk* target = get_dst(dst_idx); target->desc = (Desc*) __BOOL__; target->_bool = readI(arg(2)) == readI(arg(1)); } void __neqI(int dst_idx) { Thunk* target = get_dst(dst_idx); target->desc = (Desc*) __BOOL__; target->_bool = readI(arg(2)) != readI(arg(1)); } void __eqB(int dst_idx) { Thunk* target = get_dst(dst_idx); target->desc = (Desc*) __BOOL__; target->_bool = readB(arg(2)) == readB(arg(1)); } void __eqC(int dst_idx) { Thunk* target = get_dst(dst_idx); target->desc = (Desc*) __CHAR__; target->_bool = readC(arg(2)) == readC(arg(1)); } void __not(int dst_idx) { Thunk* target = get_dst(dst_idx); target->desc = (Desc*) __BOOL__; target->_bool = !readB(arg(1)); } void __and(int dst_idx) { Thunk* target = get_dst(dst_idx); target->desc = (Desc*) __BOOL__; target->_bool = readB(arg(2)) && readB(arg(1)); } void __or(int dst_idx) { Thunk* target = get_dst(dst_idx); target->desc = (Desc*) __BOOL__; target->_bool = readB(arg(2)) || readB(arg(1)); } void __mod(int dst_idx) { Thunk* target = get_dst(dst_idx); target->desc = (Desc*) __INT__; target->_int = readB(arg(2)) % readB(arg(1)); } void __C2I(int dst_idx) { Thunk* target = get_dst(dst_idx); target->desc = (Desc*) __INT__; target->_int = readC(arg(1)); } void add_prim(int arity, char* name, void (*exec)(int)) { int nameLength = strlen(name); // before the PrimEntry there are "arity" number of SliceEntries SliceEntry* entry_base = (SliceEntry*) alloc_desc(sizeof (SliceEntry) * arity + sizeof (PrimEntry) + nameLength + 1); PrimEntry* entry = (PrimEntry*) (entry_base + arity); entry->base.type = arity == 1 ? FT_PRIM1 : FT_PRIM2; entry->base.arity = arity; entry->base.thunk_size = thunk_size_f(arity); entry->base.hnf = false; entry->exec = exec; // TODO: should it be copied at all? memcpy(entry->name, name, nameLength); entry->name[nameLength] = '\0'; // generate slices. avoid function call if arity is zero if (arity > 0) gen_slices(entry_base, (Desc*) entry, arity); add_desc(entry->name, (Desc*) entry); } void init_prim() { add_prim(2, "add", &__add); add_prim(2, "sub", &__sub); add_prim(2, "mult", &__mult); add_prim(2, "div", &__div); add_prim(2, "gt", &__gt); add_prim(2, "geC", &__geC); add_prim(2, "lt", &__lt); add_prim(2, "eqI", &__eqI); add_prim(2, "neqI", &__neqI); add_prim(2, "eqB", &__eqB); add_prim(2, "eqC", &__eqC); add_prim(1, "not", &__not); add_prim(2, "and", &__and); add_prim(2, "or", &__or); add_prim(2, "mod", &__mod); add_prim(1, "C2I", &__C2I); }