prim.c 2.06 KB
Newer Older
1
2
3
4
#include <string.h>

#include "prim.h"
#include "desc.h"
5
#include "thunk.h"
6
7
#include "mem.h"

Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
8
9
#define arg(idx) stack_a[stack_top_a - idx]

10
11
void __add(int frame_ptr) {
    set_return(frame_ptr, updateI(get_dst(frame_ptr), readI(arg(2)) + readI(arg(1))));
12
13
}

14
15
void __sub(int frame_ptr) {
    set_return(frame_ptr, updateI(get_dst(frame_ptr), readI(arg(2)) - readI(arg(1))));
16
17
}

18
19
void __gt(int frame_ptr) {
    set_return(frame_ptr, updateB(get_dst(frame_ptr), readI(arg(2)) > readI(arg(1))));
20
21
}

22
23
void __lt(int frame_ptr) {
    set_return(frame_ptr, updateB(get_dst(frame_ptr), readI(arg(2)) < readI(arg(1))));
24
25
}

26
void __eqI(int frame_ptr) {
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
27
28
    Thunk* arg1 = arg(2);
    Thunk* arg2 = arg(1);
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
29

30
    set_return(frame_ptr, updateB(get_dst(frame_ptr), readI(arg1) == readI(arg2)));
31
32
}

33
void __eqB(int frame_ptr) {
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
34
35
    Thunk* arg1 = arg(2);
    Thunk* arg2 = arg(1);
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
36

37
    set_return(frame_ptr, updateB(get_dst(frame_ptr), readB(arg1) == readB(arg2)));
38
39
}

40
void __not(int frame_ptr) {
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
41
    Thunk* arg1 = arg(1);
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
42

43
    set_return(frame_ptr, updateB(get_dst(frame_ptr), !readB(arg1)));
44
45
}

46
void add_prim(int arity, int strictness, char* name, void (*exec)(int)) {
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
    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 = FT_PRIM;
    entry->base.arity = arity;
    entry->strictness = strictness;
    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);
66
67
}

Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
68
69
70
71
72
73
74
75
void init_prim() {
    add_prim(2, 3, "add", &__add);
    add_prim(2, 3, "sub", &__sub);
    add_prim(2, 3, "gt", &__gt);
    add_prim(2, 3, "lt", &__lt);
    add_prim(2, 3, "eqI", &__eqI);
    add_prim(2, 3, "eqB", &__eqB);
    add_prim(1, 1, "not", &__not);
76
}