<- Back to shtanton's homepage
aboutsummaryrefslogtreecommitdiff
path: root/subex/main.go
diff options
context:
space:
mode:
Diffstat (limited to 'subex/main.go')
-rw-r--r--subex/main.go49
1 files changed, 38 insertions, 11 deletions
diff --git a/subex/main.go b/subex/main.go
index 5aedd09..635b1de 100644
--- a/subex/main.go
+++ b/subex/main.go
@@ -4,26 +4,53 @@ import (
"main/walk"
)
+type Transducer struct {
+ storeSize int
+ initialState SubexState
+}
+
+type StoreItem struct {}
// Where slots are stored
-type Store map[rune][]walk.Atom
+type Store [][]walk.Atom
// Return a new store with all the data from this one
func (store Store) clone() Store {
- newStore := make(Store)
- for key, val := range store {
- newStore[key] = val
- }
+ newStore := make([][]walk.Atom, len(store))
+ copy(newStore, store)
return newStore
}
// Return a copy of this store but with an additional slot set
-func (store Store) withValue(key rune, value []walk.Atom) Store {
+func (store Store) withValue(key int, value []walk.Atom) Store {
newStore := store.clone()
newStore[key] = value
return newStore
}
+type SlotMap struct {
+ nextId int
+ ids map[rune]int
+}
+func (m *SlotMap) getId(slot rune) int {
+ id, exists := m.ids[slot]
+ if exists {
+ return id
+ }
+ id = m.nextId
+ m.nextId++
+ m.ids[slot] = id
+ return id
+}
+
// Compile the SubexAST into a transducer SubexState that can be run
-func CompileTransducer(transducerAst SubexAST) SubexState {
- return transducerAst.compileWith(&SubexNoneState{})
+func CompileTransducer(transducerAst SubexAST) Transducer {
+ slotMap := SlotMap {
+ nextId: 0,
+ ids: make(map[rune]int),
+ }
+ initial := transducerAst.compileWith(&SubexNoneState{}, &slotMap)
+ return Transducer {
+ storeSize: slotMap.nextId,
+ initialState: initial,
+ }
}
// An immutable stack for outputting to
@@ -93,14 +120,14 @@ func pruneStates(states []SubexBranch) (newStates []SubexBranch) {
}
// Run the subex transducer
-func RunTransducer(transducer SubexState, input []walk.Atom) (output []walk.Atom, err bool) {
+func RunTransducer(transducer Transducer, input []walk.Atom) (output []walk.Atom, err bool) {
states := []SubexBranch{{
- state: transducer,
+ state: transducer.initialState,
outputStack: OutputStack {
head: nil,
tail: nil,
},
- store: make(Store),
+ store: make([][]walk.Atom, transducer.storeSize),
}}
for _, piece := range input {
var newStates []SubexBranch