summaryrefslogtreecommitdiff
path: root/base/src/main/java/bjc/utils/patterns/PatternMatcher.java
diff options
context:
space:
mode:
Diffstat (limited to 'base/src/main/java/bjc/utils/patterns/PatternMatcher.java')
-rw-r--r--base/src/main/java/bjc/utils/patterns/PatternMatcher.java41
1 files changed, 41 insertions, 0 deletions
diff --git a/base/src/main/java/bjc/utils/patterns/PatternMatcher.java b/base/src/main/java/bjc/utils/patterns/PatternMatcher.java
new file mode 100644
index 0000000..e2ae9f6
--- /dev/null
+++ b/base/src/main/java/bjc/utils/patterns/PatternMatcher.java
@@ -0,0 +1,41 @@
+package bjc.utils.patterns;
+
+import bjc.data.*;
+
+/**
+ * Implements pattern-matching (of a sort) against a collection of patterns.
+ *
+ * @author Ben Culkin
+ *
+ * @param <ReturnType> The type returned by the pattern.
+ */
+public class PatternMatcher<ReturnType, InputType>
+ implements IPatternMatcher<ReturnType, InputType> {
+ private final ComplexPattern<ReturnType, Object, InputType>[] patterns;
+
+ /**
+ * Create a new pattern matcher.
+ *
+ * @param patterns The set of patterns to match against.
+ */
+ @SuppressWarnings("unchecked")
+ @SafeVarargs
+ public PatternMatcher(ComplexPattern<ReturnType, ?, InputType>...patterns) {
+ // Note: this may seem a somewhat questionable cast, but because we never
+ // actually do anything with the value who has a type matching the second
+ // parameter, this should be safe
+ this.patterns = (ComplexPattern<ReturnType, Object, InputType>[]) patterns;
+ }
+
+ @Override
+ public ReturnType matchFor(InputType input) throws NonExhaustiveMatch {
+ for (ComplexPattern<ReturnType, Object, InputType> pattern : patterns) {
+ IPair<Boolean, Object> matches = pattern.matches(input);
+ if (matches.getLeft()) {
+ pattern.apply(input, matches.getRight());
+ }
+ }
+
+ throw new NonExhaustiveMatch("Non-exhaustive match against " + input);
+ }
+}