-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathoperators.c
307 lines (249 loc) · 7.94 KB
/
operators.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
/*
Operators.
*/
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "alisp.h"
// ----------------------------------------------------------------------
// Output
/* Print. */
atom_t* op_print() {
operator_t* o = malloc(sizeof(operator_t));
o->type = PRINT;
atom_t* obj = malloc(sizeof(atom_t));
obj->val.oper = o;
obj->type = STD_OP;
obj->bindings = 0;
return obj;
}
/* Print line. */
atom_t* op_println() {
operator_t* o = malloc(sizeof(operator_t));
o->type = PRINTLN;
atom_t* obj = malloc(sizeof(atom_t));
obj->val.oper = o;
obj->type = STD_OP;
obj->bindings = 0;
return obj;
}
// ----------------------------------------------------------------------
// Math and relation
/* Math unary. */
atom_t* op_math1(double (*op)(double)) {
operator_t* o = malloc(sizeof(operator_t));
o->val.math1 = op;
o->type = MATH1;
atom_t* obj = malloc(sizeof(atom_t));
obj->val.oper = o;
obj->type = STD_OP;
obj->bindings = 0;
return obj;
}
/* Math unary, mutates argument. */
atom_t* op_math1m(double (*op)(double)) {
operator_t* o = malloc(sizeof(operator_t));
o->val.math1 = op;
o->type = MATH1_M;
atom_t* obj = malloc(sizeof(atom_t));
obj->val.oper = o;
obj->type = STD_OP;
obj->bindings = 0;
return obj;
}
/* Math binary. */
atom_t* op_math2(double (*op)(double, double)) {
operator_t* o = malloc(sizeof(operator_t));
o->val.math2 = op;
o->type = MATH2;
atom_t* obj = malloc(sizeof(atom_t));
obj->val.oper = o;
obj->type = STD_OP;
obj->bindings = 0;
return obj;
}
/* Math binary, reduces operator over arguments. */
atom_t* op_math2r(double (*op)(double, double)) {
operator_t* o = malloc(sizeof(operator_t));
o->val.math2 = op;
o->type = MATH2_R;
atom_t* obj = malloc(sizeof(atom_t));
obj->val.oper = o;
obj->type = STD_OP;
obj->bindings = 0;
return obj;
}
/* Relation. */
atom_t* op_rel(double (*op)(char, void*, void*)) {
operator_t* o = malloc(sizeof(operator_t));
o->val.rel = op;
o->type = REL;
atom_t* obj = malloc(sizeof(atom_t));
obj->val.oper = o;
obj->type = STD_OP;
obj->bindings = 0;
return obj;
}
// ----------------------------------------------------------------------
// Utility
/* Return a copy of an object. */
atom_t* op_copy() {
operator_t* o = malloc(sizeof(operator_t));
o->type = COPY;
atom_t* obj = malloc(sizeof(atom_t));
obj->val.oper = o;
obj->type = STD_OP;
obj->bindings = 0;
return obj;
}
/* Return type of an object. */
atom_t* op_type() {
operator_t* o = malloc(sizeof(operator_t));
o->type = TYPE;
atom_t* obj = malloc(sizeof(atom_t));
obj->val.oper = o;
obj->type = STD_OP;
obj->bindings = 0;
return obj;
}
// ----------------------------------------------------------------------
// List
/* Create list. */
atom_t* op_list() {
operator_t* o = malloc(sizeof(operator_t));
o->type = LIST_NEW;
atom_t* obj = malloc(sizeof(atom_t));
obj->val.oper = o;
obj->type = STD_OP;
obj->bindings = 0;
return obj;
}
/* Get list element/sublist. */
atom_t* op_list_get() {
operator_t* o = malloc(sizeof(operator_t));
o->type = LIST_GET;
atom_t* obj = malloc(sizeof(atom_t));
obj->val.oper = o;
obj->type = STD_OP;
obj->bindings = 0;
return obj;
}
/* Assign a value to list element. */
atom_t* op_list_set() {
operator_t* o = malloc(sizeof(operator_t));
o->type = LIST_SET;
atom_t* obj = malloc(sizeof(atom_t));
obj->val.oper = o;
obj->type = STD_OP;
obj->bindings = 0;
return obj;
}
/* Return list length. */
atom_t* op_list_len() {
operator_t* o = malloc(sizeof(operator_t));
o->type = LIST_LEN;
atom_t* obj = malloc(sizeof(atom_t));
obj->val.oper = o;
obj->type = STD_OP;
obj->bindings = 0;
return obj;
}
/* Add element to list. */
atom_t* op_list_add() {
operator_t* o = malloc(sizeof(operator_t));
o->type = LIST_ADD;
atom_t* obj = malloc(sizeof(atom_t));
obj->val.oper = o;
obj->type = STD_OP;
obj->bindings = 0;
return obj;
}
/* Insert element to list. */
atom_t* op_list_ins() {
operator_t* o = malloc(sizeof(operator_t));
o->type = LIST_INS;
atom_t* obj = malloc(sizeof(atom_t));
obj->val.oper = o;
obj->type = STD_OP;
obj->bindings = 0;
return obj;
}
/* Delete element from list. */
atom_t* op_list_rem() {
operator_t* o = malloc(sizeof(operator_t));
o->type = LIST_REM;
atom_t* obj = malloc(sizeof(atom_t));
obj->val.oper = o;
obj->type = STD_OP;
obj->bindings = 0;
return obj;
}
/* Merge lists. */
atom_t* op_list_merge() {
operator_t* o = malloc(sizeof(operator_t));
o->type = LIST_MERGE;
atom_t* obj = malloc(sizeof(atom_t));
obj->val.oper = o;
obj->type = STD_OP;
obj->bindings = 0;
return obj;
}
// ----------------------------------------------------------------------
// TODO: dictionary
// TODO: "for" loop -- iterable/generator based
// TODO: "while" loop -- condition based
// ----------------------------------------------------------------------
// Operator functions
/* Arithmetic */
double op_add(double a, double b) { return a + b; }
double op_sub(double a, double b) { return a - b; }
double op_mul(double a, double b) { return a * b; }
double op_div(double a, double b) { return a / b; }
double op_inc(double a) { return a + 1.0; }
double op_dec(double a) { return a - 1.0; }
/* Relational */
double op_eq(char type, void* a, void* b) {
return type == NUMBER ? *(double*)a == *(double*)b : strcmp((char*)a, (char*)b) == 0; }
double op_ne(char type, void* a, void* b) {
return type == NUMBER ? *(double*)a != *(double*)b : strcmp((char*)a, (char*)b) != 0; }
double op_lt(char type, void* a, void* b) {
return type == NUMBER ? *(double*)a < *(double*)b : strcmp((char*)a, (char*)b) < 0; }
double op_gt(char type, void* a, void* b) {
return type == NUMBER ? *(double*)a > *(double*)b : strcmp((char*)a, (char*)b) > 0; }
double op_le(char type, void* a, void* b) {
return type == NUMBER ? *(double*)a <= *(double*)b : strcmp((char*)a, (char*)b) <= 0; }
double op_ge(char type, void* a, void* b) {
return type == NUMBER ? *(double*)a >= *(double*)b : strcmp((char*)a, (char*)b) >= 0; }
/* Logical */
double op_and(double a, double b) { return a && b; }
double op_or (double a, double b) { return a || b; }
double op_not(double a) { return !a; }
/* Bitwise */
double op_band(double a, double b) { return (double)((long)a & (long)b); }
double op_bor (double a, double b) { return (double)((long)a | (long)b); }
double op_bxor(double a, double b) { return (double)((long)a ^ (long)b); }
double op_bnot(double a) { return (double)(~(long)a); }
double op_blsh(double a, double b) { return (double)((long)a << (long)b); }
double op_brsh(double a, double b) { return (double)((long)a >> (long)b); }
/* Math */
double op_acos (double x) { return acos(x); }
double op_asin (double x) { return asin(x); }
double op_atan (double x) { return atan(x); }
double op_atan2(double y, double x) { return atan2(y, x); }
double op_cos (double x) { return cos(x); }
double op_cosh (double x) { return cosh(x); }
double op_sin (double x) { return sin(x); }
double op_sinh (double x) { return sinh(x); }
double op_tanh (double x) { return tanh(x); }
double op_exp (double x) { return exp(x); }
double op_frexp(double x) { int tmp; return frexp(x, &tmp); }
double op_ldexp(double x, double y) { return ldexp(x, (int)y); }
double op_log (double x) { return log(x); }
double op_log10(double x) { return log10(x); }
double op_modf (double x) { double tmp; return modf(x, &tmp); }
double op_pow (double x, double y) { return pow(x, y); }
double op_sqrt (double x) { return sqrt(x); }
double op_ceil (double x) { return ceil(x); }
double op_fabs (double x) { return fabs(x); }
double op_floor(double x) { return floor(x); }
double op_fmod (double x, double y) { return fmod(x, y); }