<- Back to shtanton's homepage
aboutsummaryrefslogtreecommitdiff
path: root/main/pathfilter.go
diff options
context:
space:
mode:
Diffstat (limited to 'main/pathfilter.go')
-rw-r--r--main/pathfilter.go78
1 files changed, 78 insertions, 0 deletions
diff --git a/main/pathfilter.go b/main/pathfilter.go
new file mode 100644
index 0000000..7b6c64f
--- /dev/null
+++ b/main/pathfilter.go
@@ -0,0 +1,78 @@
+package main
+
+type MapTerminalFilter struct {}
+func (filter MapTerminalFilter) exec(state *ProgramState) bool {
+ terminal, isTerminal := state.space.value.(TerminalValue)
+ if !isTerminal {
+ return false
+ }
+ return terminal == MapBegin || terminal == MapEnd
+}
+
+type NonTerminalFilter struct {}
+func (filter NonTerminalFilter) exec(state *ProgramState) bool {
+ _, isTerminal := state.space.value.(TerminalValue)
+ return !isTerminal
+}
+
+type AnySegmentPathFilter struct {
+ next PathFilterState
+}
+func (filter AnySegmentPathFilter) eat(segment PathSegment) map[PathFilterState]struct{} {
+ res := make(map[PathFilterState]struct{})
+ res[filter.next] = struct{}{}
+ return res
+}
+func (filter AnySegmentPathFilter) accept() bool {
+ return false
+}
+
+type GroupPathFilter struct {
+ filters []PathFilterState
+}
+func (filter GroupPathFilter) eat(segment PathSegment) map[PathFilterState]struct{} {
+ res := make(map[PathFilterState]struct{})
+ for _, f := range filter.filters {
+ for r := range f.eat(segment) {
+ res[r] = struct{}{}
+ }
+ }
+ return res
+}
+func (filter GroupPathFilter) accept() bool {
+ for _, f := range filter.filters {
+ if f.accept() {
+ return true
+ }
+ }
+ return false
+}
+
+type NonePathFilter struct {}
+func (filter NonePathFilter) eat(segment PathSegment) map[PathFilterState]struct{} {
+ return make(map[PathFilterState]struct{})
+}
+func (filter NonePathFilter) accept() bool {
+ return true
+}
+
+type StringSegmentPathFilter struct {
+ index string
+ next PathFilterState
+}
+func (filter StringSegmentPathFilter) eat(segment PathSegment) map[PathFilterState]struct{} {
+ s, isString := segment.(string)
+ res := make(map[PathFilterState]struct{})
+ if isString && s == filter.index {
+ res[filter.next] = struct{}{}
+ }
+ return res
+}
+func (filter StringSegmentPathFilter) accept() bool {
+ return false
+}
+
+type PathFilterState interface {
+ eat(PathSegment) map[PathFilterState]struct{}
+ accept() bool
+}