@@ -17,6 +17,18 @@ void global_dict_add_ffi1(str n, const ffi1_table& ffi) {
17
17
global_dict_add_new ({string (n), array::create (T_FFI, ffi.size (), ffi.begin ())});
18
18
}
19
19
20
+ template <template <typename > class Word , typename ... Types>
21
+ struct ffi1_registrar {
22
+ ttX struct reg {
23
+ reg (ffi1_table& table) { table[X::e] = Word<X>::call; }
24
+ };
25
+
26
+ ffi1_registrar (str name, ffi1_table& table) {
27
+ call_each_arg<reg, ffi1_table&, Types...> _ (table);
28
+ global_dict_add_ffi1 (name, table);
29
+ }
30
+ };
31
+
20
32
void global_dict_add_ffi2 (str n, const ffi2_table& ffi) {
21
33
global_dict_add_new ({string (n), array::create (T_FFI, ffi.size () * ffi.size (), ffi.begin ())});
22
34
}
@@ -103,15 +115,15 @@ DEF_WORD("2over", _2over) {
103
115
104
116
#pragma endregion stack
105
117
106
- void thread1 (inter_t & inter, stack& stack, ffi ffi_table[T_MAX] ) {
118
+ void thread1 (inter_t & inter, stack& stack, const ffi1_table& table ) {
107
119
POP (x);
108
120
assert (x->t == T_ARR);
109
121
array_p out = x->alloc_as ();
110
122
array_p const * src = x->data <arr_t >();
111
123
array_p* dst = out->mut_data <arr_t >();
112
124
DO (i, x->n ) {
113
125
PUSH (src[i]);
114
- ffi f = ffi_table [src[i]->t ];
126
+ ffi f = table [src[i]->t ];
115
127
assert (f);
116
128
f (inter, stack);
117
129
dst[i] = stack.pop ();
@@ -122,46 +134,45 @@ void thread1(inter_t& inter, stack& stack, ffi ffi_table[T_MAX]) {
122
134
#define GEN_THREAD1 (name, ffi_table ) \
123
135
DEF_WORD_HANDLER (name##_arr_t ) { thread1 (inter, stack, ffi_table); }
124
136
137
+ #define GEN_THREAD_SPEC1 (name, ffi_table ) \
138
+ template <> \
139
+ struct name <arr_t > { \
140
+ static void call (inter_t & inter, stack& stack) { thread1 (inter, stack, ffi_table); } \
141
+ };
142
+
125
143
#pragma region bool
126
144
127
- ffi1_table not_table{};
128
- GEN_THREAD1 (not , not_table.begin());
145
+ ttX struct w_not {
146
+ static void call (inter_t & inter, stack& stack) {
147
+ POP (x);
148
+ array_p y = x->alloc_as <i64_t >();
149
+ DO (i, x->n ) { y->mut_data <i64_t >()[i] = !(x->data <X>()[i]); }
150
+ PUSH (y);
151
+ }
152
+ };
129
153
130
- ttT void w_not (inter_t & inter, stack& stack) {
131
- POP (x);
132
- array_p y = x->alloc_as <i64_t >();
133
- DO (i, x->n ) { y->mut_data <i64_t >()[i] = !(x->data <T>()[i]); }
134
- PUSH (y);
135
- }
154
+ ffi1_table not_table{};
155
+ GEN_THREAD_SPEC1 (w_not, not_table);
156
+ ffi1_registrar<w_not, c8_t , i64_t , f64_t , arr_t > _not_registrar (" not" , not_table);
136
157
137
- CONSTRUCTOR void reg_not () {
138
- not_table[T_I64] = w_not<i64_t >;
139
- not_table[T_F64] = w_not<f64_t >;
140
- not_table[T_ARR] = not_arr_t ;
141
- global_dict_add_ffi1 (" not" , not_table);
142
- }
143
158
#pragma endregion bool
144
159
145
160
#pragma region math
146
161
147
162
// neg
148
163
149
- ffi1_table neg_table{};
150
-
151
- ttT void w_neg (inter_t & inter, stack& stack) {
152
- POP (x);
153
- array_p y = x->alloc_as ();
154
- DO (i, x->n ) { y->mut_data <T>()[i] = -x->data <T>()[i]; }
155
- PUSH (y);
156
- }
157
- GEN_THREAD1 (neg, neg_table.begin())
164
+ ttX struct w_neg {
165
+ static void call (inter_t & inter, stack& stack) {
166
+ POP (x);
167
+ array_p y = x->alloc_as ();
168
+ DO (i, x->n ) { y->mut_data <X>()[i] = -x->data <X>()[i]; }
169
+ PUSH (y);
170
+ }
171
+ };
158
172
159
- CONSTRUCTOR void reg_neg() {
160
- neg_table[T_I64] = w_neg<i64_t >;
161
- neg_table[T_F64] = w_neg<f64_t >;
162
- neg_table[T_ARR] = neg_arr_t ;
163
- global_dict_add_ffi1 (" neg" , neg_table);
164
- }
173
+ ffi1_table neg_table{};
174
+ GEN_THREAD_SPEC1 (w_neg, neg_table);
175
+ ffi1_registrar<w_neg, c8_t , i64_t , f64_t , arr_t > _neg_registrar (" neg" , neg_table);
165
176
166
177
// abs
167
178
@@ -176,7 +187,7 @@ ffi1_table abs_table{};
176
187
177
188
GEN_ABS (i64_t , labs);
178
189
GEN_ABS (f64_t , fabs);
179
- GEN_THREAD1 (abs, abs_table.begin() )
190
+ GEN_THREAD1 (abs, abs_table)
180
191
181
192
CONSTRUCTOR void reg_abs() {
182
193
abs_table[T_I64] = abs_i64_t ;
@@ -196,7 +207,7 @@ void w_math(struct inter_t& inter, class stack& stack) {
196
207
197
208
#define GEN_FLOAT (name, fn ) \
198
209
ffi1_table name##_table; \
199
- GEN_THREAD1 (name, name##_table.begin()) \
210
+ GEN_THREAD1 (name, name##_table) \
200
211
CONSTRUCTOR void reg_##name() { \
201
212
struct op { \
202
213
static f64 call (f64 x) { return fn (x); } \
@@ -235,7 +246,7 @@ GEN_FLOAT(tanh, tanh)
235
246
236
247
#define GEN_ROUND (name, fn ) \
237
248
ffi1_table name##_table{}; \
238
- GEN_THREAD1 (name, name##_table.begin()) \
249
+ GEN_THREAD1 (name, name##_table) \
239
250
CONSTRUCTOR void reg_##name() { \
240
251
struct op { \
241
252
static i64 call (f64 x) { return fn (x); } \
@@ -457,19 +468,17 @@ DEF_WORD_1_1("index", index) {
457
468
458
469
DEF_WORD_1_1 (" len" , len) { return array::atom<i64_t >(x->n ); }
459
470
460
- ttX void reverse (inter_t & inter, stack& stack) {
461
- POP (x);
462
- array_p y = x->alloc_as ();
463
- DO (i, x->n ) { y->mut_data <X>()[i] = x->data <X>()[x->n - i - 1 ]; }
464
- PUSH (y);
465
- }
471
+ ttX struct w_reverse {
472
+ static void call (inter_t & inter, stack& stack) {
473
+ POP (x);
474
+ array_p y = x->alloc_as ();
475
+ DO (i, x->n ) { y->mut_data <X>()[i] = x->data <X>()[x->n - i - 1 ]; }
476
+ PUSH (y);
477
+ }
478
+ };
466
479
467
- #define REGISTER_REVERSE (t ) reverse_table[t::e] = reverse<t>;
468
- CONSTRUCTOR void register_reverse () {
469
- ffi1_table reverse_table{};
470
- TYPE_FOREACH (REGISTER_REVERSE);
471
- global_dict_add_ffi1 (" reverse" , reverse_table);
472
- }
480
+ ffi1_table reverse_table{};
481
+ ffi1_registrar<w_reverse, c8_t , i64_t , f64_t , arr_t > _reverse_registrar (" reverse" , reverse_table);
473
482
474
483
ttX void take (inter_t & inter, stack& stack) {
475
484
POP (y);
0 commit comments