summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ir/match.h116
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>