diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ir/match.h | 116 |
1 files changed, 82 insertions, 34 deletions
diff --git a/src/ir/match.h b/src/ir/match.h index 9b7d1ff0f..2ab3afe65 100644 --- a/src/ir/match.h +++ b/src/ir/match.h @@ -476,82 +476,108 @@ template<class S> inline decltype(auto) ConstMatcher(Const** binder, S&& s) { return Matcher<Const*, S>(binder, {}, s); } -// Unary and AbstractUnary -struct UnaryK { +// Unary, UnaryOp and AbstractUnaryOp +template<> struct NumComponents<Unary*> { static constexpr size_t value = 2; }; +template<> struct GetComponent<Unary*, 0> { + UnaryOp operator()(Unary* curr) { return curr->op; } +}; +template<> struct GetComponent<Unary*, 1> { + Expression* operator()(Unary* curr) { return curr->value; } +}; +struct UnaryOpK { using Op = UnaryOp; static UnaryOp getOp(Type, Op op) { return op; } }; -struct AbstractUnaryK { +struct AbstractUnaryOpK { using Op = Abstract::Op; static UnaryOp getOp(Type type, Abstract::Op op) { return Abstract::getUnary(type, op); } }; -template<class T> struct UnaryKind {}; -template<class T> struct KindTypeRegistry<UnaryKind<T>> { +template<class T> struct UnaryOpKind {}; +template<class T> struct KindTypeRegistry<UnaryOpKind<T>> { using matched_t = Unary*; using data_t = typename T::Op; }; -template<class T> struct MatchSelf<UnaryKind<T>> { +template<class T> struct MatchSelf<UnaryOpKind<T>> { bool operator()(Unary* curr, typename T::Op op) { return curr->op == T::getOp(curr->value->type, op); } }; -template<class T> struct NumComponents<UnaryKind<T>> { +template<class T> struct NumComponents<UnaryOpKind<T>> { static constexpr size_t value = 1; }; -template<class T> struct GetComponent<UnaryKind<T>, 0> { +template<class T> struct GetComponent<UnaryOpKind<T>, 0> { Expression* operator()(Unary* curr) { return curr->value; } }; +template<class S1, class S2> +inline decltype(auto) UnaryMatcher(Unary** binder, S1&& s1, S2&& s2) { + return Matcher<Unary*, S1, S2>(binder, {}, s1, s2); +} template<class S> -inline decltype(auto) UnaryMatcher(Unary** binder, UnaryOp op, S&& s) { - return Matcher<UnaryKind<UnaryK>, S>(binder, op, s); +inline decltype(auto) UnaryOpMatcher(Unary** binder, UnaryOp op, S&& s) { + return Matcher<UnaryOpKind<UnaryOpK>, S>(binder, op, s); } template<class S> inline decltype(auto) -AbstractUnaryMatcher(Unary** binder, Abstract::Op op, S&& s) { - return Matcher<UnaryKind<AbstractUnaryK>, S>(binder, op, s); +AbstractUnaryOpMatcher(Unary** binder, Abstract::Op op, S&& s) { + return Matcher<UnaryOpKind<AbstractUnaryOpK>, S>(binder, op, s); } -// Binary and AbstractBinary -struct BinaryK { +// Binary, BinaryOp and AbstractBinaryOp +template<> struct NumComponents<Binary*> { static constexpr size_t value = 3; }; +template<> struct GetComponent<Binary*, 0> { + BinaryOp operator()(Binary* curr) { return curr->op; } +}; +template<> struct GetComponent<Binary*, 1> { + Expression* operator()(Binary* curr) { return curr->left; } +}; +template<> struct GetComponent<Binary*, 2> { + Expression* operator()(Binary* curr) { return curr->right; } +}; +struct BinaryOpK { using Op = BinaryOp; static BinaryOp getOp(Type, Op op) { return op; } }; -struct AbstractBinaryK { +struct AbstractBinaryOpK { using Op = Abstract::Op; static BinaryOp getOp(Type type, Abstract::Op op) { return Abstract::getBinary(type, op); } }; -template<class T> struct BinaryKind {}; -template<class T> struct KindTypeRegistry<BinaryKind<T>> { +template<class T> struct BinaryOpKind {}; +template<class T> struct KindTypeRegistry<BinaryOpKind<T>> { using matched_t = Binary*; using data_t = typename T::Op; }; -template<class T> struct MatchSelf<BinaryKind<T>> { +template<class T> struct MatchSelf<BinaryOpKind<T>> { bool operator()(Binary* curr, typename T::Op op) { return curr->op == T::getOp(curr->left->type, op); } }; -template<class T> struct NumComponents<BinaryKind<T>> { +template<class T> struct NumComponents<BinaryOpKind<T>> { static constexpr size_t value = 2; }; -template<class T> struct GetComponent<BinaryKind<T>, 0> { +template<class T> struct GetComponent<BinaryOpKind<T>, 0> { Expression* operator()(Binary* curr) { return curr->left; } }; -template<class T> struct GetComponent<BinaryKind<T>, 1> { +template<class T> struct GetComponent<BinaryOpKind<T>, 1> { Expression* operator()(Binary* curr) { return curr->right; } }; +template<class S1, class S2, class S3> +inline decltype(auto) +BinaryMatcher(Binary** binder, S1&& s1, S2&& s2, S3&& s3) { + return Matcher<Binary*, S1, S2, S3>(binder, {}, s1, s2, s3); +} template<class S1, class S2> inline decltype(auto) -BinaryMatcher(Binary** binder, BinaryOp op, S1&& s1, S2&& s2) { - return Matcher<BinaryKind<BinaryK>, S1, S2>(binder, op, s1, s2); +BinaryOpMatcher(Binary** binder, BinaryOp op, S1&& s1, S2&& s2) { + return Matcher<BinaryOpKind<BinaryOpK>, S1, S2>(binder, op, s1, s2); } template<class S1, class S2> inline decltype(auto) -AbstractBinaryMatcher(Binary** binder, Abstract::Op op, S1&& s1, S2&& s2) { - return Matcher<BinaryKind<AbstractBinaryK>, S1, S2>(binder, op, s1, s2); +AbstractBinaryOpMatcher(Binary** binder, Abstract::Op op, S1&& s1, S2&& s2) { + return Matcher<BinaryOpKind<AbstractBinaryOpK>, S1, S2>(binder, op, s1, s2); } // Select @@ -751,37 +777,59 @@ inline decltype(auto) constant(Const** binder, int32_t x) { inline decltype(auto) any() { return Internal::Any<Expression*>(nullptr); } inline decltype(auto) any(Expression** binder) { return Internal::Any(binder); } +template<class S> inline decltype(auto) unary(S&& s) { + return Internal::UnaryMatcher(nullptr, Internal::Any<UnaryOp>(nullptr), s); +} +template<class S> inline decltype(auto) unary(Unary** binder, S&& s) { + return Internal::UnaryMatcher(binder, Internal::Any<UnaryOp>(nullptr), s); +} +template<class S> inline decltype(auto) unary(UnaryOp* binder, S&& s) { + return Internal::UnaryMatcher(nullptr, Internal::Any<UnaryOp>(binder), s); +} template<class S> inline decltype(auto) unary(UnaryOp op, S&& s) { - return Internal::UnaryMatcher(nullptr, op, s); + return Internal::UnaryOpMatcher(nullptr, op, s); } template<class S> inline decltype(auto) unary(Abstract::Op op, S&& s) { - return Internal::AbstractUnaryMatcher(nullptr, op, s); + return Internal::AbstractUnaryOpMatcher(nullptr, op, s); } template<class S> inline decltype(auto) unary(Unary** binder, UnaryOp op, S&& s) { - return Internal::UnaryMatcher(binder, op, s); + return Internal::UnaryOpMatcher(binder, op, s); } template<class S> inline decltype(auto) unary(Unary** binder, Abstract::Op op, S&& s) { - return Internal::AbstractUnaryMatcher(binder, op, s); + return Internal::AbstractUnaryOpMatcher(binder, op, s); +} +template<class S1, class S2> inline decltype(auto) binary(S1&& s1, S2&& s2) { + return Internal::BinaryMatcher( + nullptr, Internal::Any<BinaryOp>(nullptr), s1, s2); +} +template<class S1, class S2> +inline decltype(auto) binary(Binary** binder, S1&& s1, S2&& s2) { + return Internal::BinaryMatcher( + binder, Internal::Any<BinaryOp>(nullptr), s1, s2); +} +template<class S1, class S2> +inline decltype(auto) binary(BinaryOp* binder, S1&& s1, S2&& s2) { + return Internal::BinaryMatcher( + nullptr, Internal::Any<BinaryOp>(binder), s1, s2); } - template<class S1, class S2> inline decltype(auto) binary(BinaryOp op, S1&& s1, S2&& s2) { - return Internal::BinaryMatcher(nullptr, op, s1, s2); + return Internal::BinaryOpMatcher(nullptr, op, s1, s2); } template<class S1, class S2> inline decltype(auto) binary(Abstract::Op op, S1&& s1, S2&& s2) { - return Internal::AbstractBinaryMatcher(nullptr, op, s1, s2); + return Internal::AbstractBinaryOpMatcher(nullptr, op, s1, s2); } template<class S1, class S2> inline decltype(auto) binary(Binary** binder, BinaryOp op, S1&& s1, S2&& s2) { - return Internal::BinaryMatcher(binder, op, s1, s2); + return Internal::BinaryOpMatcher(binder, op, s1, s2); } template<class S1, class S2> inline decltype(auto) binary(Binary** binder, Abstract::Op op, S1&& s1, S2&& s2) { - return Internal::AbstractBinaryMatcher(binder, op, s1, s2); + return Internal::AbstractBinaryOpMatcher(binder, op, s1, s2); } template<class S1, class S2, class S3> |