prim.c 2.31 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"

9
void __add(Thunk* target)
10
{
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
11
12
13
	Thunk* arg1 = stack[stack_top - 2];
	Thunk* arg2 = stack[stack_top - 1];
	
14
15
	arg1 = eval(arg1);
	arg2 = eval(arg2);
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
16
17
	
	updateI(target, readI(arg1) + readI(arg2));
18
19
}

20
21
22
23
24
void __sub(Thunk* target)
{
	Thunk* arg1 = stack[stack_top - 2];
	Thunk* arg2 = stack[stack_top - 1];
	
25
26
	arg1 = eval(arg1);
	arg2 = eval(arg2);
27
28
29
30
31
32
33
34
35
	
	updateI(target, readI(arg1) - readI(arg2));
}

void __gt(Thunk* target)
{
	Thunk* arg1 = stack[stack_top - 2];
	Thunk* arg2 = stack[stack_top - 1];
	
36
37
	arg1 = eval(arg1);
	arg2 = eval(arg2);
38
39
40
41
42
43
44
45
46
	
	updateB(target, readI(arg1) > readI(arg2));
}

void __lt(Thunk* target)
{
	Thunk* arg1 = stack[stack_top - 2];
	Thunk* arg2 = stack[stack_top - 1];
	
47
48
	arg1 = eval(arg1);
	arg2 = eval(arg2);
49
50
51
52
	
	updateB(target, readI(arg1) < readI(arg2));
}

53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
void __eqI(Thunk* target)
{
	Thunk* arg1 = stack[stack_top - 2];
	Thunk* arg2 = stack[stack_top - 1];
	
	arg1 = eval(arg1);
	arg2 = eval(arg2);
	
	updateB(target, readI(arg1) == readI(arg2));
}

void __eqB(Thunk* target)
{
	Thunk* arg1 = stack[stack_top - 2];
	Thunk* arg2 = stack[stack_top - 1];
	
	arg1 = eval(arg1);
	arg2 = eval(arg2);
	
	updateB(target, readB(arg1) == readB(arg2));
}

void __not(Thunk* target)
{
	Thunk* arg1 = stack[stack_top - 1];
	
	arg1 = eval(arg1);
	
	updateB(target, !readB(arg1));
}

84
PrimEntry* add_prim(int arity, int strictness, char* name, void (*exec)(Thunk*))
85
86
87
88
{
	int nameLength = strlen(name);
	
	// before the PrimEntry there are "arity" number of SliceEntries
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
89
	SliceEntry* entry_base = (SliceEntry*) alloc_desc(sizeof(SliceEntry) * arity + sizeof(PrimEntry) + nameLength + 1);
90
		
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
91
	PrimEntry* entry = (PrimEntry*) (entry_base + arity);
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
92
93
	entry->base.type = FT_PRIM;
	entry->base.arity = arity;
94
95
96
97
98
99
100
101
	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
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
102
	if(arity>0) gen_slices(entry_base, (Desc*) entry, arity);
103
	
Laszlo Domoszlai's avatar
Laszlo Domoszlai committed
104
	add_desc(entry->name, (Desc*) entry);
105
106
107
108
109
}

void init_prim()
{
	add_prim(2, 3, "add", &__add);
110
111
112
	add_prim(2, 3, "sub", &__sub);
	add_prim(2, 3, "gt", &__gt);
	add_prim(2, 3, "lt", &__lt);
113
114
115
	add_prim(2, 3, "eqI", &__eqI);
	add_prim(2, 3, "eqB", &__eqB);
	add_prim(1, 1, "not", &__not);
116
}