-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathmc.h
114 lines (106 loc) · 3.55 KB
/
mc.h
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
#ifndef MC_H
#define MC_H
#include "k.h"
/* math function constructors
* F: function
* F1: function to compute type 1
* F2: function to compute type 2
* T1: result type for type 1
* T2: result type for type 2
* A1: access macro for result of type -1
* A2: access macro for result of type -2
*/
#define MC1D(F,F1,F2,T1,T2,A1,A2) \
K* F(K *a) { \
K *r=0; \
switch(at) { \
case 1: r=k##T1(F1(I2F(a1))); break; \
case 2: r=k##T2(F2(a2)); break; \
case 0: r=kv0(ac); DO(ac, v0(r)[i]=F((v0(a)[i])); EC(v0(r)[i])) break; \
case -1: r=kv##T1(ac); DO(ac, A1(r)[i]=F1(I2F(v1(a)[i]))) break; \
case -2: r=kv##T2(ac); DO(ac, A2(r)[i]=F2(v2(a)[i])) break; \
default: return kerror("type"); \
} \
return r->t ? r : knorm(r); \
}
#define MC1(F,F1,F2,T1,T2,A1,A2) \
K* F(K *a) { \
K *r=0; \
switch(at) { \
case 1: r=k##T1(F1(a1)); break; \
case 2: r=k##T2(F2(a2)); break; \
case 0: r=kv0(ac); DO(ac, v0(r)[i]=F((v0(a)[i])); EC(v0(r)[i])) break; \
case -1: r=kv##T1(ac); DO(ac, A1(r)[i]=F1(v1(a)[i])) break; \
case -2: r=kv##T2(ac); DO(ac, A2(r)[i]=F2(v2(a)[i])) break; \
default: return kerror("type"); \
} \
return r->t ? r : knorm(r); \
}
#define MC2D(F,F1,F2,T1,T2,A1,A2) \
K* F(K *a, K *b) { \
K *r=0; \
if(at <= 0 && bt <= 0 && ac != bc) return kerror("length"); \
if(at==0 || bt==0) r=eache(F,a,b); \
else { \
switch(at) { \
case 1: \
switch(bt) { \
case 1: r=k##T1(F1(I2F(a1),I2F(b1))); break; \
case 2: r=k##T2(F2(I2F(a1),b2)); break; \
case -1: r=kv##T1(bc); DO(bc, A1(r)[i]=F1(I2F(a1),I2F(v1(b)[i]))) break; \
case -2: r=kv##T2(bc); DO(bc, A2(r)[i]=F2(I2F(a1),v2(b)[i])) break; \
} break; \
case 2: \
switch(bt) { \
case 1: r=k##T1(F1(a2,I2F(b1))); break; \
case 2: r=k##T2(F2(a2,b2)); break; \
case -1: r=kv##T1(bc); DO(bc, A1(r)[i]=F1(a2,I2F(v1(b)[i]))) break; \
case -2: r=kv##T2(bc); DO(bc, A2(r)[i]=F2(a2,v2(b)[i])) break; \
} break; \
case -1: \
switch(bt) { \
case 1: r=kv##T1(ac); DO(ac, A1(r)[i]=F1(I2F(v1(a)[i]),I2F(b1))) break; \
case 2: r=kv##T2(ac); DO(ac, A2(r)[i]=F2(I2F(v1(a)[i]),b2)) break; \
case -1: r=kv##T1(ac); DO(ac, A1(r)[i]=F1(I2F(v1(a)[i]),I2F(v1(b)[i]))) break; \
case -2: r=kv##T2(ac); DO(ac, A2(r)[i]=F2(I2F(v1(a)[i]),v2(b)[i])) break; \
} break; \
case -2: \
switch(bt) { \
case 1: r=kv##T1(ac); DO(ac, A1(r)[i]=F1(v2(a)[i],I2F(b1))) break; \
case 2: r=kv##T2(ac); DO(ac, A2(r)[i]=F2(v2(a)[i],b2)) break; \
case -1: r=kv##T1(ac); DO(ac, A1(r)[i]=F1(v2(a)[i],I2F(v1(b)[i]))) break; \
case -2: r=kv##T2(ac); DO(ac, A2(r)[i]=F2(v2(a)[i],v2(b)[i])) break; \
} break; \
default: return kerror("type"); \
} \
} \
return r->t ? r : knorm(r); \
}
/* integer ops */
#define MC2IO(F,O,N) \
K* F(K *a, K *b) { \
K *r=0; \
if((N) && !b1) return kerror("nonce"); \
if(at <= 0 && bt <= 0 && ac != bc) return kerror("length"); \
if(at==0 || bt==0) r=eache(F,a,b); \
else { \
switch(at) { \
case 1: \
switch(bt) { \
case 1: r=k1(a1 O b1); break; \
case -1: r=kv1(bc); DO(bc, v1(r)[i] = a1 O v1(b)[i]) break; \
} break; \
case -1: \
switch(bt) { \
case 1: r=kv1(ac); DO(ac, v1(r)[i] = v1(a)[i] O b1) break; \
case -1: r=kv1(ac); DO(ac, v1(r)[i] = v1(a)[i] O v1(b)[i]) break; \
} break; \
default: return kerror("type"); \
} \
} \
return r->t ? r : knorm(r); \
}
/* optimized adverb stubs */
#define MC1A(F) K* F##avopt(K *a, char *av) { (void)a; (void)av; return 0; }
#define MC2A(F) K* F##avopt2(K *a, K *b, char *av) { (void)a; (void)b; (void)av; return 0; }
#endif /* MC_H */