<- Back to shtanton's homepage
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharlie Stanton <charlie@shtanton.xyz>2022-12-22 15:23:28 +0000
committerCharlie Stanton <charlie@shtanton.xyz>2022-12-22 15:23:28 +0000
commitfb1f51d1da22f34509cf3fe1d174296d36a0f0ad (patch)
treef07260b169af51288e76ae095b3dce3a21f01148
parentf3911888915f6aa96e6b28bd2a98a662faf20f47 (diff)
downloadsubex-fb1f51d1da22f34509cf3fe1d174296d36a0f0ad.tar
Expressions inside stores are now subexes instead of regexes
This simplifies things by no longer needing a regex implementation It also enables transforming text as it is being read into a slot
-rw-r--r--main/main.go5
-rw-r--r--main/parse.go2
-rw-r--r--main/subexast.go4
-rw-r--r--main/subexstate.go32
4 files changed, 25 insertions, 18 deletions
diff --git a/main/main.go b/main/main.go
index be43d90..0466371 100644
--- a/main/main.go
+++ b/main/main.go
@@ -27,6 +27,11 @@ func (store Store) clone() Store {
}
return newStore
}
+func (store Store) withValue(key rune, value string) Store {
+ newStore := store.clone()
+ newStore[key] = value
+ return newStore
+}
func compileTransducer(transducerAst SubexAST) SubexState {
return transducerAst.compileWith(SubexNoneState{})
diff --git a/main/parse.go b/main/parse.go
index 6cc20ea..18941f2 100644
--- a/main/parse.go
+++ b/main/parse.go
@@ -91,7 +91,7 @@ func parseSubex(l *RuneReader, minPower int) SubexAST {
if slot == eof {
panic("Missing slot character")
}
- match := parseRegex(l, 100)
+ match := parseSubex(l, 100)
if match == nil {
panic("Missing regex for store")
}
diff --git a/main/subexast.go b/main/subexast.go
index 54cc5fe..510335f 100644
--- a/main/subexast.go
+++ b/main/subexast.go
@@ -19,12 +19,12 @@ func (ast SubexASTConcat) String() string {
}
type SubexASTStore struct {
- match RegexAST
+ match SubexAST
slot rune
}
func (ast SubexASTStore) compileWith(next SubexState) SubexState {
return SubexStoreState {
- match: ast.match.compileWith(RegexNoneState{}),
+ match: ast.match.compileWith(SubexNoneState{}),
slot: ast.slot,
next: next,
}
diff --git a/main/subexstate.go b/main/subexstate.go
index cc697f0..00b9e75 100644
--- a/main/subexstate.go
+++ b/main/subexstate.go
@@ -21,25 +21,25 @@ func (state SubexGroupState) accepting(store Store) []string {
}
type SubexStoreState struct {
- match RegexState
+ match SubexState
slot rune
next SubexState
- input string
+ toStore string
}
-func (state SubexStoreState) eat(store Store, char rune) []SubexBranch {
- var nextStates []SubexBranch
- if state.match.accepting() {
- store[state.slot] = state.input
- nextStates = state.next.eat(store, char)
+func (state SubexStoreState) eat(store Store, char rune) (nextStates []SubexBranch) {
+ acceptedOutputs := state.match.accepting(store)
+ for _, acceptedOutput := range acceptedOutputs {
+ nextStore := store.withValue(state.slot, state.toStore + acceptedOutput)
+ nextStates = append(nextStates, state.next.eat(nextStore.clone(), char)...)
}
- nextRegexStates := state.match.eat(char)
- for _, regexState := range nextRegexStates {
+ nextMatchStates := state.match.eat(store.clone(), char)
+ for _, matchState := range nextMatchStates {
nextStates = append(nextStates, SubexBranch {
state: SubexStoreState {
- match: regexState,
+ match: matchState.state,
slot: state.slot,
next: state.next,
- input: state.input + string(char),
+ toStore: state.toStore + matchState.output,
},
output: "",
store: store.clone(),
@@ -47,11 +47,13 @@ func (state SubexStoreState) eat(store Store, char rune) []SubexBranch {
}
return nextStates
}
-func (state SubexStoreState) accepting(store Store) []string {
- if state.match.accepting() {
- return state.next.accepting(store)
+func (state SubexStoreState) accepting(store Store) (outputs []string) {
+ acceptedOutputs := state.match.accepting(store)
+ for _, acceptedOutput := range acceptedOutputs {
+ nextStore := store.withValue(state.slot, state.toStore + acceptedOutput)
+ outputs = append(outputs, state.next.accepting(nextStore)...)
}
- return nil
+ return outputs
}
type SubexOutputState struct {