<- Back to shtanton's homepage
aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharlie Stanton <charlie@shtanton.xyz>2023-04-24 19:28:48 +0100
committerCharlie Stanton <charlie@shtanton.xyz>2023-04-24 19:28:48 +0100
commitfa750707cd3dd44bcbf59d9271d389c92b293621 (patch)
tree1d1e18afcafb6c0e660609d6b1e9392abf37acc7
parentc10bca852dfd2ed3ae8f776c12705675a8ab99bf (diff)
downloadstred-go-fa750707cd3dd44bcbf59d9271d389c92b293621.tar
Simplify the OutputStack, improves performance by simplifying from an interface to a single struct
-rw-r--r--subex/main.go46
1 files changed, 21 insertions, 25 deletions
diff --git a/subex/main.go b/subex/main.go
index c1718a4..5aedd09 100644
--- a/subex/main.go
+++ b/subex/main.go
@@ -27,39 +27,32 @@ func CompileTransducer(transducerAst SubexAST) SubexState {
}
// An immutable stack for outputting to
-type OutputStack interface {
- pop() ([]walk.Atom, OutputStack)
- push(atoms []walk.Atom) OutputStack
+type OutputStack struct {
+ head []walk.Atom
+ tail *OutputStack
}
-
-type OutputStackNil struct {}
-func (stack OutputStackNil) pop() ([]walk.Atom, OutputStack) {
- panic("Tried to pop from an empty OutputStack")
+func (stack OutputStack) pop() ([]walk.Atom, OutputStack) {
+ return stack.head, *stack.tail
}
-func (stack OutputStackNil) push(atoms []walk.Atom) OutputStack {
- return &OutputStackCons {
+func (stack OutputStack) push(atoms []walk.Atom) OutputStack {
+ return OutputStack {
head: atoms,
- tail: stack,
+ tail: &stack,
}
}
-
-type OutputStackCons struct {
- head []walk.Atom
- tail OutputStack
-}
-func (stack OutputStackCons) pop() ([]walk.Atom, OutputStack) {
- return stack.head, stack.tail
-}
-func (stack OutputStackCons) push(atoms []walk.Atom) OutputStack {
- return &OutputStackCons {
+func (stack OutputStack) replace(atoms []walk.Atom) OutputStack {
+ return OutputStack {
head: atoms,
- tail: stack,
+ tail: stack.tail,
}
}
+func (stack OutputStack) peek() []walk.Atom {
+ return stack.head
+}
func topAppend(outputStack OutputStack, atoms []walk.Atom) OutputStack {
- head, tail := outputStack.pop()
- return tail.push(walk.ConcatData(head, atoms))
+ head := outputStack.peek()
+ return outputStack.replace(walk.ConcatData(head, atoms))
}
// One branch of subex execution
@@ -103,7 +96,10 @@ func pruneStates(states []SubexBranch) (newStates []SubexBranch) {
func RunTransducer(transducer SubexState, input []walk.Atom) (output []walk.Atom, err bool) {
states := []SubexBranch{{
state: transducer,
- outputStack: OutputStackNil{}.push(nil),
+ outputStack: OutputStack {
+ head: nil,
+ tail: nil,
+ },
store: make(Store),
}}
for _, piece := range input {
@@ -119,7 +115,7 @@ func RunTransducer(transducer SubexState, input []walk.Atom) (output []walk.Atom
for _, state := range states {
acceptingStacks := state.accepting()
for _, stack := range acceptingStacks {
- output, _ := stack.pop()
+ output := stack.head
return output, false
}
}