prim.c 4.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]

Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
10
void __addI(int dst_idx) {
11
    Thunk* target = get_dst(dst_idx);
12
13
    target->desc = (Desc*) __INT__;
    target->_int = readI(arg(2)) + readI(arg(1));
14
15
}

Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
16
void __subI(int dst_idx) {
17
    Thunk* target = get_dst(dst_idx);
18
19
    target->desc = (Desc*) __INT__;
    target->_int = readI(arg(2)) - readI(arg(1));
20
21
}

Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
22
void __multI(int dst_idx) {
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
23
24
25
26
27
    Thunk* target = get_dst(dst_idx);
    target->desc = (Desc*) __INT__;
    target->_int = readI(arg(2)) * readI(arg(1));
}

Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
28
void __divI(int dst_idx) {
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
29
30
31
32
33
    Thunk* target = get_dst(dst_idx);
    target->desc = (Desc*) __INT__;
    target->_int = readI(arg(2)) / readI(arg(1));
}

Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
34
void __gtI(int dst_idx) {
35
    Thunk* target = get_dst(dst_idx);
36
37
    target->desc = (Desc*) __BOOL__;
    target->_bool = readI(arg(2)) > readI(arg(1));
38
39
}

40
41
42
43
44
45
void __geI(int dst_idx) {
    Thunk* target = get_dst(dst_idx);
    target->desc = (Desc*) __BOOL__;
    target->_bool = readI(arg(2)) >= readI(arg(1));
}

Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
46
void __ltI(int dst_idx) {
47
    Thunk* target = get_dst(dst_idx);
48
49
    target->desc = (Desc*) __BOOL__;
    target->_bool = readI(arg(2)) < readI(arg(1));
50
51
}

Laszlo Domoszlai's avatar
add gc    
Laszlo Domoszlai committed
52
53
54
55
56
57
void __geC(int dst_idx) {
    Thunk* target = get_dst(dst_idx);
    target->desc = (Desc*) __BOOL__;
    target->_bool = readC(arg(2)) >= readC(arg(1));
}

58
59
void __eqI(int dst_idx) {
    Thunk* target = get_dst(dst_idx);
60
61
    target->desc = (Desc*) __BOOL__;
    target->_bool = readI(arg(2)) == readI(arg(1));
62
63
}

Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
64
65
66
67
68
69
void __neqI(int dst_idx) {
    Thunk* target = get_dst(dst_idx);
    target->desc = (Desc*) __BOOL__;
    target->_bool = readI(arg(2)) != readI(arg(1));
}

70
71
void __eqB(int dst_idx) {
    Thunk* target = get_dst(dst_idx);
72
73
    target->desc = (Desc*) __BOOL__;
    target->_bool = readB(arg(2)) == readB(arg(1));
74
75
}

Laszlo Domoszlai's avatar
add gc    
Laszlo Domoszlai committed
76
77
78
79
80
81
void __eqC(int dst_idx) {
    Thunk* target = get_dst(dst_idx);
    target->desc = (Desc*) __CHAR__;
    target->_bool = readC(arg(2)) == readC(arg(1));
}

82
83
void __not(int dst_idx) {
    Thunk* target = get_dst(dst_idx);
84
85
    target->desc = (Desc*) __BOOL__;
    target->_bool = !readB(arg(1));
86
87
}

Laszlo Domoszlai's avatar
add gc    
Laszlo Domoszlai committed
88
89
90
91
92
93
94
95
96
97
98
99
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));
}

Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
100
101
102
103
104
105
void __mod(int dst_idx) {
    Thunk* target = get_dst(dst_idx);
    target->desc = (Desc*) __INT__;
    target->_int = readB(arg(2)) % readB(arg(1));
}

Laszlo Domoszlai's avatar
add gc    
Laszlo Domoszlai committed
106
107
108
109
110
111
void __C2I(int dst_idx) {
    Thunk* target = get_dst(dst_idx);
    target->desc = (Desc*) __INT__;
    target->_int = readC(arg(1));
}

112
void add_prim(int arity, char* name, void (*exec)(int)) {
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
113
114
115
116
117
118
    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);
119
    entry->base.type = arity == 1 ? FT_PRIM1 : FT_PRIM2;
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
120
    entry->base.arity = arity;
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
121
122
    entry->base.thunk_size = thunk_size_f(arity);    
    entry->base.hnf = false;
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
123
124
125
126
127
128
129
130
131
132
    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);
133
134
}

Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
135
void init_prim() {
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
136
137
138
139
140
    add_prim(2, "addI", &__addI);
    add_prim(2, "subI", &__subI);
    add_prim(2, "multI", &__multI);
    add_prim(2, "divI", &__divI);
    add_prim(2, "gtI", &__gtI);
141
    add_prim(2, "geI", &__geI);
142
    add_prim(2, "geC", &__geC);    
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
143
    add_prim(2, "ltI", &__ltI);
144
145
146
147
148
149
150
151
152
    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);    
153
}