prim.c 2.55 KB
Newer Older
1
2
3
4
5

#include <string.h>

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

Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
9
struct Thunk* __add(Thunk* target) {
10
11
    Thunk* arg1 = arg(stack_top_a, 2);
    Thunk* arg2 = arg(stack_top_a, 1);
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
12
13
14
15
16

    arg1 = eval(arg1);
    arg2 = eval(arg2);

    return updateI(target, readI(arg1) + readI(arg2));
17
18
}

Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
19
struct Thunk* __sub(Thunk* target) {
20
21
    Thunk* arg1 = arg(stack_top_a, 2);
    Thunk* arg2 = arg(stack_top_a, 1);
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
22
23
24
25
26

    arg1 = eval(arg1);
    arg2 = eval(arg2);

    return updateI(target, readI(arg1) - readI(arg2));
27
28
}

Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
29
struct Thunk* __gt(Thunk* target) {
30
31
    Thunk* arg1 = arg(stack_top_a, 2);
    Thunk* arg2 = arg(stack_top_a, 1);
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
32
33
34
35
36

    arg1 = eval(arg1);
    arg2 = eval(arg2);

    return updateB(target, readI(arg1) > readI(arg2));
37
38
}

Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
39
struct Thunk* __lt(Thunk* target) {
40
41
    Thunk* arg1 = arg(stack_top_a, 2);
    Thunk* arg2 = arg(stack_top_a, 1);
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
42
43
44
45
46

    arg1 = eval(arg1);
    arg2 = eval(arg2);

    return updateB(target, readI(arg1) < readI(arg2));
47
48
}

Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
49
struct Thunk* __eqI(Thunk* target) {
50
51
    Thunk* arg1 = arg(stack_top_a, 2);
    Thunk* arg2 = arg(stack_top_a, 1);
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
52
53
54
55
56

    arg1 = eval(arg1);
    arg2 = eval(arg2);

    return updateB(target, readI(arg1) == readI(arg2));
57
58
}

Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
59
struct Thunk* __eqB(Thunk* target) {
60
61
    Thunk* arg1 = arg(stack_top_a, 2);
    Thunk* arg2 = arg(stack_top_a, 1);
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
62
63
64
65
66

    arg1 = eval(arg1);
    arg2 = eval(arg2);

    return updateB(target, readB(arg1) == readB(arg2));
67
68
}

Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
69
struct Thunk* __not(Thunk* target) {
70
    Thunk* arg1 = arg(stack_top_a, 1);
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
71
72
73
74

    arg1 = eval(arg1);

    return updateB(target, !readB(arg1));
75
76
}

Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
77
void add_prim(int arity, int strictness, char* name, Thunk* (*exec)(Thunk*)) {
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
    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);
97
98
}

Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
99
100
101
102
103
104
105
106
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);
107
}