Commit d3f83759 authored by Paul's avatar Paul
Browse files

Add ability to find multiple matches

parent 1e0d4551
...@@ -81,6 +81,12 @@ constexpr auto sequence_c(F&& f) ...@@ -81,6 +81,12 @@ constexpr auto sequence_c(F&& f)
return detail::sequence_c_impl(f, detail::gens<N>{}); return detail::sequence_c_impl(f, detail::gens<N>{});
} }
template <class F, class... Ts>
constexpr void each_args(F f, Ts&&... xs)
{
swallow{(f(std::forward<Ts>(xs)), 0)...};
}
/// Implements a fix-point combinator /// Implements a fix-point combinator
template <class R, class F> template <class R, class F>
detail::fix_f<R, F> fix(F f) detail::fix_f<R, F> fix(F f)
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
#include <migraph/ranges.hpp> #include <migraph/ranges.hpp>
#include <migraph/instruction.hpp> #include <migraph/instruction.hpp>
#include <migraph/program.hpp> #include <migraph/program.hpp>
#include <migraph/type_name.hpp> #include <migraph/iterator_for.hpp>
#include <unordered_map> #include <unordered_map>
namespace migraph { namespace migraph {
...@@ -186,6 +186,24 @@ matcher_result match_instruction(program& p, instruction_ref ins, M&& m) ...@@ -186,6 +186,24 @@ matcher_result match_instruction(program& p, instruction_ref ins, M&& m)
return result; return result;
} }
template<class... Ms>
void find_matches(program& p, Ms&&... ms)
{
for(auto ins:iterator_for(p))
{
bool match = false;
each_args([&](auto&& m) {
if(match)
return;
auto r = match_instruction(p, ins, m.matcher());
if(r.result == p.end())
return;
m.apply(r);
match = true;
}, ms...);
}
}
template <class... Ts> template <class... Ts>
auto all_of(Ts... ms) auto all_of(Ts... ms)
{ {
......
...@@ -311,6 +311,45 @@ void match_bind1() ...@@ -311,6 +311,45 @@ void match_bind1()
EXPECT(bool{r.result == pass}); EXPECT(bool{r.result == pass});
} }
struct match_find_sum
{
migraph::instruction_ref ins;
auto matcher() const
{
return matchers::name("sum");
}
void apply(matchers::matcher_result r) const
{
EXPECT(bool{r.result == ins});
}
};
struct match_find_literal
{
migraph::instruction_ref ins;
auto matcher() const
{
return matchers::name("@literal");
}
void apply(matchers::matcher_result r) const
{
EXPECT(bool{r.result != ins});
EXPECT(r.result->name() == "@literal");
}
};
void match_finder()
{
migraph::program p;
auto one = p.add_literal(1);
auto two = p.add_literal(2);
auto sum = p.add_instruction(sum_op{}, one, two);
p.add_instruction(pass_op{}, sum);
matchers::find_matches(p, match_find_sum{sum}, match_find_literal{sum});
}
int main() int main()
{ {
match1(); match1();
...@@ -339,4 +378,6 @@ int main() ...@@ -339,4 +378,6 @@ int main()
match_none_of(); match_none_of();
match_bind1(); match_bind1();
match_finder();
} }
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment