Skip to content

Commit c8f541e

Browse files
committed
more templates
1 parent 0120768 commit c8f541e

File tree

3 files changed

+74
-47
lines changed

3 files changed

+74
-47
lines changed

src/common.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,3 +187,19 @@ struct call_each<Func, T, Types...> {
187187

188188
template <template <typename> class Func>
189189
struct call_each<Func> {};
190+
191+
template <template <typename> class Func, typename Arg, typename... Types>
192+
struct call_each_arg;
193+
194+
template <template <typename> class Func, typename Arg, typename T, typename... Types>
195+
struct call_each_arg<Func, Arg, T, Types...> {
196+
call_each_arg(Arg& arg) {
197+
Func<T> _1(arg);
198+
call_each_arg<Func, Arg, Types...> _2(arg);
199+
}
200+
};
201+
202+
template <template <typename> class Func, typename Arg>
203+
struct call_each_arg<Func, Arg> {
204+
call_each_arg(Arg& arg) {}
205+
};

src/words.c++

Lines changed: 55 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,18 @@ void global_dict_add_ffi1(str n, const ffi1_table& ffi) {
1717
global_dict_add_new({string(n), array::create(T_FFI, ffi.size(), ffi.begin())});
1818
}
1919

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+
2032
void global_dict_add_ffi2(str n, const ffi2_table& ffi) {
2133
global_dict_add_new({string(n), array::create(T_FFI, ffi.size() * ffi.size(), ffi.begin())});
2234
}
@@ -103,15 +115,15 @@ DEF_WORD("2over", _2over) {
103115

104116
#pragma endregion stack
105117

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) {
107119
POP(x);
108120
assert(x->t == T_ARR);
109121
array_p out = x->alloc_as();
110122
array_p const* src = x->data<arr_t>();
111123
array_p* dst = out->mut_data<arr_t>();
112124
DO(i, x->n) {
113125
PUSH(src[i]);
114-
ffi f = ffi_table[src[i]->t];
126+
ffi f = table[src[i]->t];
115127
assert(f);
116128
f(inter, stack);
117129
dst[i] = stack.pop();
@@ -122,46 +134,45 @@ void thread1(inter_t& inter, stack& stack, ffi ffi_table[T_MAX]) {
122134
#define GEN_THREAD1(name, ffi_table) \
123135
DEF_WORD_HANDLER(name##_arr_t) { thread1(inter, stack, ffi_table); }
124136

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+
125143
#pragma region bool
126144

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+
};
129153

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);
136157

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-
}
143158
#pragma endregion bool
144159

145160
#pragma region math
146161

147162
// neg
148163

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+
};
158172

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);
165176

166177
// abs
167178

@@ -176,7 +187,7 @@ ffi1_table abs_table{};
176187

177188
GEN_ABS(i64_t, labs);
178189
GEN_ABS(f64_t, fabs);
179-
GEN_THREAD1(abs, abs_table.begin())
190+
GEN_THREAD1(abs, abs_table)
180191

181192
CONSTRUCTOR void reg_abs() {
182193
abs_table[T_I64] = abs_i64_t;
@@ -196,7 +207,7 @@ void w_math(struct inter_t& inter, class stack& stack) {
196207

197208
#define GEN_FLOAT(name, fn) \
198209
ffi1_table name##_table; \
199-
GEN_THREAD1(name, name##_table.begin()) \
210+
GEN_THREAD1(name, name##_table) \
200211
CONSTRUCTOR void reg_##name() { \
201212
struct op { \
202213
static f64 call(f64 x) { return fn(x); } \
@@ -235,7 +246,7 @@ GEN_FLOAT(tanh, tanh)
235246

236247
#define GEN_ROUND(name, fn) \
237248
ffi1_table name##_table{}; \
238-
GEN_THREAD1(name, name##_table.begin()) \
249+
GEN_THREAD1(name, name##_table) \
239250
CONSTRUCTOR void reg_##name() { \
240251
struct op { \
241252
static i64 call(f64 x) { return fn(x); } \
@@ -457,19 +468,17 @@ DEF_WORD_1_1("index", index) {
457468

458469
DEF_WORD_1_1("len", len) { return array::atom<i64_t>(x->n); }
459470

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+
};
466479

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);
473482

474483
ttX void take(inter_t& inter, stack& stack) {
475484
POP(y);

tests/words.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ ERROR: expected single value
217217

218218
## unary words
219219

220-
### not
220+
### `not`
221221

222222
```nkt
223223
> 1 not .
@@ -230,6 +230,8 @@ ERROR: expected single value
230230
1
231231
> [ 0. 1. 2. 3. ] not .
232232
[ 1 0 0 0 ]
233+
> [ [ 0 1 ] [ 1 0 ] ] not .
234+
[ [ 1 0 ] [ 0 1 ] ]
233235
```
234236

235237
### neg

0 commit comments

Comments
 (0)