diff options
Diffstat (limited to 'subex/subexast.go')
-rw-r--r-- | subex/subexast.go | 113 |
1 files changed, 68 insertions, 45 deletions
diff --git a/subex/subexast.go b/subex/subexast.go index 92c099a..f5b1178 100644 --- a/subex/subexast.go +++ b/subex/subexast.go @@ -7,15 +7,15 @@ import ( // A node in the AST of a subex type SubexAST interface { - compileWith(next SubexState) SubexState + compileWith(next SubexState, slotMap *SlotMap) SubexState } // Process the first subex, then the second, splitting the input text in two type SubexASTConcat struct { First, Second SubexAST } -func (ast SubexASTConcat) compileWith(next SubexState) SubexState { - return ast.First.compileWith(ast.Second.compileWith(next)) +func (ast SubexASTConcat) compileWith(next SubexState, slotMap *SlotMap) SubexState { + return ast.First.compileWith(ast.Second.compileWith(next, slotMap), slotMap) } func (ast SubexASTConcat) String() string { return fmt.Sprintf("(%v)(%v)", ast.First, ast.Second) @@ -26,12 +26,13 @@ type SubexASTStore struct { Match SubexAST Slot rune } -func (ast SubexASTStore) compileWith(next SubexState) SubexState { +func (ast SubexASTStore) compileWith(next SubexState, slotMap *SlotMap) SubexState { + id := slotMap.getId(ast.Slot) return &SubexCaptureBeginState { next: ast.Match.compileWith(&SubexStoreEndState { - slot: ast.Slot, + slot: id, next: next, - }), + }, slotMap), } } func (ast SubexASTStore) String() string { @@ -42,10 +43,10 @@ func (ast SubexASTStore) String() string { type SubexASTOr struct { First, Second SubexAST } -func (ast SubexASTOr) compileWith(next SubexState) SubexState { +func (ast SubexASTOr) compileWith(next SubexState, slotMap *SlotMap) SubexState { return &SubexGroupState { - ast.First.compileWith(next), - ast.Second.compileWith(next), + ast.First.compileWith(next, slotMap), + ast.Second.compileWith(next, slotMap), } } func (ast SubexASTOr) String() string { @@ -75,19 +76,19 @@ func (cr ConvexRange) decrement() ConvexRange { return ConvexRange{cr.Start - 1, cr.End - 1} } } -func (cr ConvexRange) compile(content SubexAST, next SubexState) SubexState { +func (cr ConvexRange) compile(content SubexAST, next SubexState, slotMap *SlotMap) SubexState { min, _ := cr.minmax() if min != 0 { - return content.compileWith(cr.decrement().compile(content, next)) + return content.compileWith(cr.decrement().compile(content, next, slotMap), slotMap) } if cr.Start == -1 { state := &SubexGroupState {nil, next} - state.first = content.compileWith(state) + state.first = content.compileWith(state, slotMap) return state } if cr.End == -1 { state := &SubexGroupState {next, nil} - state.second = content.compileWith(state) + state.second = content.compileWith(state, slotMap) return state } @@ -95,7 +96,7 @@ func (cr ConvexRange) compile(content SubexAST, next SubexState) SubexState { state := next; for i := 0; i < cr.Start; i += 1 { state = &SubexGroupState { - content.compileWith(state), + content.compileWith(state, slotMap), next, } } @@ -105,7 +106,7 @@ func (cr ConvexRange) compile(content SubexAST, next SubexState) SubexState { for i := 0; i < cr.End; i += 1 { state = &SubexGroupState { next, - content.compileWith(state), + content.compileWith(state, slotMap), } } return state @@ -118,10 +119,10 @@ type SubexASTRepeat struct { Content SubexAST Acceptable []ConvexRange } -func (ast SubexASTRepeat) compileWith(next SubexState) SubexState { +func (ast SubexASTRepeat) compileWith(next SubexState, slotMap *SlotMap) SubexState { var state SubexState = &SubexDeadState{} for _, convex := range ast.Acceptable { - state = &SubexGroupState {state, convex.compile(ast.Content, next)} + state = &SubexGroupState {state, convex.compile(ast.Content, next, slotMap)} } return state } @@ -133,7 +134,7 @@ func (ast SubexASTRepeat) String() string { type SubexASTCopyAtom struct { Atom walk.Atom } -func (ast SubexASTCopyAtom) compileWith(next SubexState) SubexState { +func (ast SubexASTCopyAtom) compileWith(next SubexState, slotMap *SlotMap) SubexState { return &SubexCopyAtomState{ atom: ast.Atom, next: next, @@ -145,7 +146,7 @@ func (ast SubexASTCopyAtom) String() string { // Read in a single atom that must be a boolean and output it unchanged type SubexASTCopyBool struct {} -func (ast SubexASTCopyBool) compileWith(next SubexState) SubexState { +func (ast SubexASTCopyBool) compileWith(next SubexState, slotMap *SlotMap) SubexState { return &SubexCopyBoolState {next} } func (ast SubexASTCopyBool) String() string { @@ -154,7 +155,7 @@ func (ast SubexASTCopyBool) String() string { // Read in a single atom that must be a number and output it unchanged type SubexASTCopyNumber struct {} -func (ast SubexASTCopyNumber) compileWith(next SubexState) SubexState { +func (ast SubexASTCopyNumber) compileWith(next SubexState, slotMap *SlotMap) SubexState { return &SubexCopyNumberState {next} } func (ast SubexASTCopyNumber) String() string { @@ -163,7 +164,7 @@ func (ast SubexASTCopyNumber) String() string { // Read in a single atom that must be a string atom and output it unchanged type SubexASTCopyStringAtom struct {} -func (ast SubexASTCopyStringAtom) compileWith(next SubexState) SubexState { +func (ast SubexASTCopyStringAtom) compileWith(next SubexState, slotMap *SlotMap) SubexState { return &SubexCopyStringAtomState {next} } func (ast SubexASTCopyStringAtom) String() string { @@ -173,7 +174,7 @@ func (ast SubexASTCopyStringAtom) String() string { // Read in a full string value and copy it out unchanged // # is equivalent to "_{-0}" type SubexASTCopyString struct {} -func (ast SubexASTCopyString) compileWith(next SubexState) SubexState { +func (ast SubexASTCopyString) compileWith(next SubexState, slotMap *SlotMap) SubexState { stringAtomState := &SubexCopyStringAtomState { next: nil, } @@ -197,9 +198,9 @@ func (ast SubexASTCopyString) String() string { // Read in a value and copy it out unchanged // , is equivalent to `null`|?|%|#|[`{}[]`] type SubexASTCopyValue struct {} -func (ast SubexASTCopyValue) compileWith(next SubexState) SubexState { +func (ast SubexASTCopyValue) compileWith(next SubexState, slotMap *SlotMap) SubexState { return &SubexGroupState { - SubexASTCopyString{}.compileWith(next), + SubexASTCopyString{}.compileWith(next, slotMap), &SubexCopyNonStringAtomState {next}, } } @@ -209,20 +210,42 @@ func (ast SubexASTCopyValue) String() string { // Read in any single Atom and output it unchanged type SubexASTCopyAny struct {} -func (ast SubexASTCopyAny) compileWith(next SubexState) SubexState { +func (ast SubexASTCopyAny) compileWith(next SubexState, slotMap *SlotMap) SubexState { return &SubexCopyAnyState{next} } func (ast SubexASTCopyAny) String() string { return "." } +type OutputContentAST interface { + compile(slotMap *SlotMap) OutputContent +} + +type OutputLoadAST struct { + slot rune +} +func (ast OutputLoadAST) compile(slotMap *SlotMap) OutputContent { + return OutputLoad {slotMap.getId(ast.slot)} +} + +type OutputAtomLiteralAST struct { + atom walk.Atom +} +func (ast OutputAtomLiteralAST) compile(slotMap *SlotMap) OutputContent { + return OutputAtomLiteral {ast.atom} +} + // Output a series of Atoms without reading anything from input type SubexASTOutput struct { - Replacement []OutputContent + Replacement []OutputContentAST } -func (ast SubexASTOutput) compileWith(next SubexState) SubexState { +func (ast SubexASTOutput) compileWith(next SubexState, slotMap *SlotMap) SubexState { + var content []OutputContent + for _, el := range ast.Replacement { + content = append(content, el.compile(slotMap)) + } return &SubexOutputState{ - content: ast.Replacement, + content: content, next: next, } } @@ -234,13 +257,13 @@ func (ast SubexASTOutput) String() string { type SubexASTJoin struct { Content, Delimiter SubexAST } -func (ast SubexASTJoin) compileWith(next SubexState) SubexState { +func (ast SubexASTJoin) compileWith(next SubexState, slotMap *SlotMap) SubexState { afterContentState := &SubexGroupState { nil, next, } - manyContentsState := ast.Content.compileWith(afterContentState) - afterContentState.first = ast.Delimiter.compileWith(manyContentsState) + manyContentsState := ast.Content.compileWith(afterContentState, slotMap) + afterContentState.first = ast.Delimiter.compileWith(manyContentsState, slotMap) return &SubexGroupState { manyContentsState, next, @@ -255,7 +278,7 @@ func (ast SubexASTJoin) String() string { type SubexASTRange struct { Parts map[walk.Atom]walk.Atom } -func (ast SubexASTRange) compileWith(next SubexState) SubexState { +func (ast SubexASTRange) compileWith(next SubexState, slotMap *SlotMap) SubexState { return &SubexRangeState { parts: ast.Parts, next: next, @@ -270,12 +293,12 @@ func (ast SubexASTRange) String() string { type SubexASTSum struct { Content SubexAST } -func (ast SubexASTSum) compileWith(next SubexState) SubexState { +func (ast SubexASTSum) compileWith(next SubexState, slotMap *SlotMap) SubexState { return &SubexCaptureBeginState { next: ast.Content.compileWith(&SubexArithmeticEndState { next: next, calculate: sumValues, - }), + }, slotMap), } } func (ast SubexASTSum) String() string { @@ -286,12 +309,12 @@ func (ast SubexASTSum) String() string { type SubexASTProduct struct { Content SubexAST } -func (ast SubexASTProduct) compileWith(next SubexState) SubexState { +func (ast SubexASTProduct) compileWith(next SubexState, slotMap *SlotMap) SubexState { return &SubexCaptureBeginState { next: ast.Content.compileWith(&SubexArithmeticEndState { next: next, calculate: multiplyValues, - }), + }, slotMap), } } func (ast SubexASTProduct) String() string { @@ -303,12 +326,12 @@ func (ast SubexASTProduct) String() string { type SubexASTNegate struct { Content SubexAST } -func (ast SubexASTNegate) compileWith(next SubexState) SubexState { +func (ast SubexASTNegate) compileWith(next SubexState, slotMap *SlotMap) SubexState { return &SubexCaptureBeginState { next: ast.Content.compileWith(&SubexArithmeticEndState { next: next, calculate: negateValues, - }), + }, slotMap), } } func (ast SubexASTNegate) String() string { @@ -321,12 +344,12 @@ func (ast SubexASTNegate) String() string { type SubexASTReciprocal struct { Content SubexAST } -func (ast SubexASTReciprocal) compileWith(next SubexState) SubexState { +func (ast SubexASTReciprocal) compileWith(next SubexState, slotMap *SlotMap) SubexState { return &SubexCaptureBeginState { next: ast.Content.compileWith(&SubexArithmeticEndState { next: next, calculate: reciprocalValues, - }), + }, slotMap), } } func (ast SubexASTReciprocal) String() string { @@ -339,12 +362,12 @@ func (ast SubexASTReciprocal) String() string { type SubexASTNot struct { Content SubexAST } -func (ast SubexASTNot) compileWith(next SubexState) SubexState { +func (ast SubexASTNot) compileWith(next SubexState, slotMap *SlotMap) SubexState { return &SubexCaptureBeginState { next: ast.Content.compileWith(&SubexArithmeticEndState { next: next, calculate: notValues, - }), + }, slotMap), } } func (ast SubexASTNot) String() string { @@ -353,7 +376,7 @@ func (ast SubexASTNot) String() string { // Does nothing type SubexASTEmpty struct {} -func (ast SubexASTEmpty) compileWith(next SubexState) SubexState { +func (ast SubexASTEmpty) compileWith(next SubexState, slotMap *SlotMap) SubexState { return next } func (ast SubexASTEmpty) String() string { @@ -364,9 +387,9 @@ func (ast SubexASTEmpty) String() string { type SubexASTDiscard struct { Content SubexAST } -func (ast SubexASTDiscard) compileWith(next SubexState) SubexState { +func (ast SubexASTDiscard) compileWith(next SubexState, slotMap *SlotMap) SubexState { return &SubexCaptureBeginState { - next: ast.Content.compileWith(&SubexDiscardState {next}), + next: ast.Content.compileWith(&SubexDiscardState {next}, slotMap), } } func (ast SubexASTDiscard) String() string { |