diff options
Diffstat (limited to 'subex/main.go')
-rw-r--r-- | subex/main.go | 49 |
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 |