@@ -1756,12 +1756,7 @@ te_expr* te_parser::base(te_parser::state* theState)
17561756 next_token (theState);
17571757 ret->m_parameters [0 ] = power (theState);
17581758 }
1759- else if (is_function2 (theState->m_value ) || is_closure2 (theState->m_value ) ||
1760- is_function3 (theState->m_value ) || is_closure3 (theState->m_value ) ||
1761- is_function4 (theState->m_value ) || is_closure4 (theState->m_value ) ||
1762- is_function5 (theState->m_value ) || is_closure5 (theState->m_value ) ||
1763- is_function6 (theState->m_value ) || is_closure6 (theState->m_value ) ||
1764- is_function7 (theState->m_value ) || is_closure7 (theState->m_value ))
1759+ else if (is_function (theState->m_value ) || is_closure (theState->m_value ))
17651760 {
17661761 const int arity = get_arity (theState->m_value );
17671762
@@ -2155,6 +2150,19 @@ te_expr* te_parser::power(te_parser::state* theState)
21552150 }
21562151
21572152// --------------------------------------------------
2153+ // tuple-list-maker
2154+ template <typename F, size_t ... Indices>
2155+ auto make_closure_arg_list (const F& fn, te_expr* ctx, std::index_sequence<Indices...>)
2156+ {
2157+ return std::make_tuple (ctx, fn (Indices)...);
2158+ }
2159+
2160+ template <typename F, size_t ... Indices>
2161+ auto make_function_arg_list (const F& fn, std::index_sequence<Indices...>)
2162+ {
2163+ return std::make_tuple (fn (Indices)...);
2164+ }
2165+
21582166te_type te_parser::te_eval (const te_expr* texp)
21592167 {
21602168 if (texp == nullptr )
@@ -2167,49 +2175,46 @@ te_type te_parser::te_eval(const te_expr* texp)
21672175 const auto M = [&texp = std::as_const (texp)](const size_t e)
21682176 { return (e < texp->m_parameters .size ()) ? te_eval (texp->m_parameters [e]) : te_nan; };
21692177
2170- switch (texp->m_value .index ())
2171- {
2172- case 0 :
2173- return get_constant (texp->m_value );
2174- case 1 :
2175- return *(get_variable (texp->m_value ));
2176- case 2 :
2177- return get_function0 (texp->m_value )();
2178- case 3 :
2179- return get_function1 (texp->m_value )(M (0 ));
2180- case 4 :
2181- return get_function2 (texp->m_value )(M (0 ), M (1 ));
2182- case 5 :
2183- return get_function3 (texp->m_value )(M (0 ), M (1 ), M (2 ));
2184- case 6 :
2185- return get_function4 (texp->m_value )(M (0 ), M (1 ), M (2 ), M (3 ));
2186- case 7 :
2187- return get_function5 (texp->m_value )(M (0 ), M (1 ), M (2 ), M (3 ), M (4 ));
2188- case 8 :
2189- return get_function6 (texp->m_value )(M (0 ), M (1 ), M (2 ), M (3 ), M (4 ), M (5 ));
2190- case 9 :
2191- return get_function7 (texp->m_value )(M (0 ), M (1 ), M (2 ), M (3 ), M (4 ), M (5 ), M (6 ));
2192- case 10 :
2193- return get_closure0 (texp->m_value )(texp->m_parameters [0 ]);
2194- case 11 :
2195- return get_closure1 (texp->m_value )(texp->m_parameters [1 ], M (0 ));
2196- case 12 :
2197- return get_closure2 (texp->m_value )(texp->m_parameters [2 ], M (0 ), M (1 ));
2198- case 13 :
2199- return get_closure3 (texp->m_value )(texp->m_parameters [3 ], M (0 ), M (1 ), M (2 ));
2200- case 14 :
2201- return get_closure4 (texp->m_value )(texp->m_parameters [4 ], M (0 ), M (1 ), M (2 ), M (3 ));
2202- case 15 :
2203- return get_closure5 (texp->m_value )(texp->m_parameters [5 ], M (0 ), M (1 ), M (2 ), M (3 ), M (4 ));
2204- case 16 :
2205- return get_closure6 (texp->m_value )(texp->m_parameters [6 ], M (0 ), M (1 ), M (2 ), M (3 ), M (4 ),
2206- M (5 ));
2207- case 17 :
2208- return get_closure7 (texp->m_value )(texp->m_parameters [7 ], M (0 ), M (1 ), M (2 ), M (3 ), M (4 ),
2209- M (5 ), M (6 ));
2210- default :
2211- return te_nan;
2212- };
2178+ return std::visit (
2179+ [&, texp](const auto & var) -> te_type
2180+ {
2181+ using T = std::decay_t <decltype (var)>;
2182+ if constexpr (te_is_constant_v<T>)
2183+ {
2184+ return var;
2185+ }
2186+ else if constexpr (te_is_variable_v<T>)
2187+ {
2188+ return *var;
2189+ }
2190+ else if constexpr (std::is_same_v<T, te_fun0>)
2191+ {
2192+ return var ();
2193+ }
2194+ else if constexpr (std::is_same_v<T, te_confun0>)
2195+ {
2196+ return var (texp->m_parameters [0 ]);
2197+ }
2198+ else if constexpr (te_is_closure_v<T>)
2199+ {
2200+ constexpr size_t n_args = te_function_arity<T>;
2201+ static_assert (n_args > 0 );
2202+ return std::apply (var,
2203+ make_closure_arg_list (M, texp->m_parameters [n_args - 1 ],
2204+ std::make_index_sequence<n_args - 1 >{}));
2205+ }
2206+ else if constexpr (te_is_function_v<T>)
2207+ {
2208+ constexpr size_t n_args = te_function_arity<T>;
2209+ return std::apply (var,
2210+ make_function_arg_list (M, std::make_index_sequence<n_args>{}));
2211+ }
2212+ else
2213+ {
2214+ return te_nan;
2215+ }
2216+ },
2217+ texp->m_value );
22132218 // NOLINTEND
22142219 }
22152220
0 commit comments