annotate vendor/github.com/dlclark/regexp2/runner.go @ 66:787b5ee0289d draft

Use vendored modules Signed-off-by: Izuru Yakumo <yakumo.izuru@chaotic.ninja>
author yakumo.izuru
date Sun, 23 Jul 2023 13:18:53 +0000
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
66
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1 package regexp2
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
2
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
3 import (
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
4 "bytes"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
5 "errors"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
6 "fmt"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
7 "math"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
8 "strconv"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
9 "strings"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
10 "time"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
11 "unicode"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
12
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
13 "github.com/dlclark/regexp2/syntax"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
14 )
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
15
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
16 type runner struct {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
17 re *Regexp
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
18 code *syntax.Code
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
19
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
20 runtextstart int // starting point for search
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
21
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
22 runtext []rune // text to search
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
23 runtextpos int // current position in text
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
24 runtextend int
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
25
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
26 // The backtracking stack. Opcodes use this to store data regarding
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
27 // what they have matched and where to backtrack to. Each "frame" on
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
28 // the stack takes the form of [CodePosition Data1 Data2...], where
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
29 // CodePosition is the position of the current opcode and
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
30 // the data values are all optional. The CodePosition can be negative, and
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
31 // these values (also called "back2") are used by the BranchMark family of opcodes
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
32 // to indicate whether they are backtracking after a successful or failed
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
33 // match.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
34 // When we backtrack, we pop the CodePosition off the stack, set the current
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
35 // instruction pointer to that code position, and mark the opcode
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
36 // with a backtracking flag ("Back"). Each opcode then knows how to
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
37 // handle its own data.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
38 runtrack []int
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
39 runtrackpos int
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
40
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
41 // This stack is used to track text positions across different opcodes.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
42 // For example, in /(a*b)+/, the parentheses result in a SetMark/CaptureMark
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
43 // pair. SetMark records the text position before we match a*b. Then
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
44 // CaptureMark uses that position to figure out where the capture starts.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
45 // Opcodes which push onto this stack are always paired with other opcodes
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
46 // which will pop the value from it later. A successful match should mean
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
47 // that this stack is empty.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
48 runstack []int
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
49 runstackpos int
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
50
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
51 // The crawl stack is used to keep track of captures. Every time a group
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
52 // has a capture, we push its group number onto the runcrawl stack. In
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
53 // the case of a balanced match, we push BOTH groups onto the stack.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
54 runcrawl []int
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
55 runcrawlpos int
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
56
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
57 runtrackcount int // count of states that may do backtracking
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
58
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
59 runmatch *Match // result object
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
60
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
61 ignoreTimeout bool
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
62 timeout time.Duration // timeout in milliseconds (needed for actual)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
63 timeoutChecksToSkip int
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
64 timeoutAt time.Time
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
65
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
66 operator syntax.InstOp
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
67 codepos int
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
68 rightToLeft bool
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
69 caseInsensitive bool
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
70 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
71
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
72 // run searches for matches and can continue from the previous match
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
73 //
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
74 // quick is usually false, but can be true to not return matches, just put it in caches
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
75 // textstart is -1 to start at the "beginning" (depending on Right-To-Left), otherwise an index in input
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
76 // input is the string to search for our regex pattern
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
77 func (re *Regexp) run(quick bool, textstart int, input []rune) (*Match, error) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
78
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
79 // get a cached runner
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
80 runner := re.getRunner()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
81 defer re.putRunner(runner)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
82
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
83 if textstart < 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
84 if re.RightToLeft() {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
85 textstart = len(input)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
86 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
87 textstart = 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
88 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
89 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
90
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
91 return runner.scan(input, textstart, quick, re.MatchTimeout)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
92 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
93
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
94 // Scans the string to find the first match. Uses the Match object
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
95 // both to feed text in and as a place to store matches that come out.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
96 //
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
97 // All the action is in the Go() method. Our
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
98 // responsibility is to load up the class members before
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
99 // calling Go.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
100 //
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
101 // The optimizer can compute a set of candidate starting characters,
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
102 // and we could use a separate method Skip() that will quickly scan past
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
103 // any characters that we know can't match.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
104 func (r *runner) scan(rt []rune, textstart int, quick bool, timeout time.Duration) (*Match, error) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
105 r.timeout = timeout
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
106 r.ignoreTimeout = (time.Duration(math.MaxInt64) == timeout)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
107 r.runtextstart = textstart
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
108 r.runtext = rt
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
109 r.runtextend = len(rt)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
110
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
111 stoppos := r.runtextend
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
112 bump := 1
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
113
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
114 if r.re.RightToLeft() {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
115 bump = -1
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
116 stoppos = 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
117 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
118
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
119 r.runtextpos = textstart
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
120 initted := false
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
121
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
122 r.startTimeoutWatch()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
123 for {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
124 if r.re.Debug() {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
125 //fmt.Printf("\nSearch content: %v\n", string(r.runtext))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
126 fmt.Printf("\nSearch range: from 0 to %v\n", r.runtextend)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
127 fmt.Printf("Firstchar search starting at %v stopping at %v\n", r.runtextpos, stoppos)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
128 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
129
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
130 if r.findFirstChar() {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
131 if err := r.checkTimeout(); err != nil {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
132 return nil, err
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
133 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
134
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
135 if !initted {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
136 r.initMatch()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
137 initted = true
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
138 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
139
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
140 if r.re.Debug() {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
141 fmt.Printf("Executing engine starting at %v\n\n", r.runtextpos)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
142 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
143
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
144 if err := r.execute(); err != nil {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
145 return nil, err
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
146 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
147
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
148 if r.runmatch.matchcount[0] > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
149 // We'll return a match even if it touches a previous empty match
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
150 return r.tidyMatch(quick), nil
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
151 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
152
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
153 // reset state for another go
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
154 r.runtrackpos = len(r.runtrack)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
155 r.runstackpos = len(r.runstack)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
156 r.runcrawlpos = len(r.runcrawl)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
157 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
158
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
159 // failure!
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
160
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
161 if r.runtextpos == stoppos {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
162 r.tidyMatch(true)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
163 return nil, nil
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
164 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
165
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
166 // Recognize leading []* and various anchors, and bump on failure accordingly
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
167
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
168 // r.bump by one and start again
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
169
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
170 r.runtextpos += bump
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
171 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
172 // We never get here
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
173 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
174
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
175 func (r *runner) execute() error {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
176
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
177 r.goTo(0)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
178
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
179 for {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
180
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
181 if r.re.Debug() {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
182 r.dumpState()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
183 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
184
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
185 if err := r.checkTimeout(); err != nil {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
186 return err
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
187 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
188
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
189 switch r.operator {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
190 case syntax.Stop:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
191 return nil
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
192
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
193 case syntax.Nothing:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
194 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
195
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
196 case syntax.Goto:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
197 r.goTo(r.operand(0))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
198 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
199
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
200 case syntax.Testref:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
201 if !r.runmatch.isMatched(r.operand(0)) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
202 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
203 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
204 r.advance(1)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
205 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
206
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
207 case syntax.Lazybranch:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
208 r.trackPush1(r.textPos())
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
209 r.advance(1)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
210 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
211
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
212 case syntax.Lazybranch | syntax.Back:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
213 r.trackPop()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
214 r.textto(r.trackPeek())
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
215 r.goTo(r.operand(0))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
216 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
217
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
218 case syntax.Setmark:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
219 r.stackPush(r.textPos())
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
220 r.trackPush()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
221 r.advance(0)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
222 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
223
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
224 case syntax.Nullmark:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
225 r.stackPush(-1)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
226 r.trackPush()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
227 r.advance(0)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
228 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
229
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
230 case syntax.Setmark | syntax.Back, syntax.Nullmark | syntax.Back:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
231 r.stackPop()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
232 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
233
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
234 case syntax.Getmark:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
235 r.stackPop()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
236 r.trackPush1(r.stackPeek())
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
237 r.textto(r.stackPeek())
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
238 r.advance(0)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
239 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
240
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
241 case syntax.Getmark | syntax.Back:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
242 r.trackPop()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
243 r.stackPush(r.trackPeek())
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
244 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
245
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
246 case syntax.Capturemark:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
247 if r.operand(1) != -1 && !r.runmatch.isMatched(r.operand(1)) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
248 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
249 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
250 r.stackPop()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
251 if r.operand(1) != -1 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
252 r.transferCapture(r.operand(0), r.operand(1), r.stackPeek(), r.textPos())
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
253 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
254 r.capture(r.operand(0), r.stackPeek(), r.textPos())
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
255 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
256 r.trackPush1(r.stackPeek())
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
257
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
258 r.advance(2)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
259
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
260 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
261
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
262 case syntax.Capturemark | syntax.Back:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
263 r.trackPop()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
264 r.stackPush(r.trackPeek())
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
265 r.uncapture()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
266 if r.operand(0) != -1 && r.operand(1) != -1 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
267 r.uncapture()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
268 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
269
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
270 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
271
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
272 case syntax.Branchmark:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
273 r.stackPop()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
274
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
275 matched := r.textPos() - r.stackPeek()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
276
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
277 if matched != 0 { // Nonempty match -> loop now
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
278 r.trackPush2(r.stackPeek(), r.textPos()) // Save old mark, textpos
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
279 r.stackPush(r.textPos()) // Make new mark
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
280 r.goTo(r.operand(0)) // Loop
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
281 } else { // Empty match -> straight now
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
282 r.trackPushNeg1(r.stackPeek()) // Save old mark
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
283 r.advance(1) // Straight
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
284 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
285 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
286
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
287 case syntax.Branchmark | syntax.Back:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
288 r.trackPopN(2)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
289 r.stackPop()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
290 r.textto(r.trackPeekN(1)) // Recall position
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
291 r.trackPushNeg1(r.trackPeek()) // Save old mark
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
292 r.advance(1) // Straight
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
293 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
294
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
295 case syntax.Branchmark | syntax.Back2:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
296 r.trackPop()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
297 r.stackPush(r.trackPeek()) // Recall old mark
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
298 break // Backtrack
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
299
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
300 case syntax.Lazybranchmark:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
301 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
302 // We hit this the first time through a lazy loop and after each
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
303 // successful match of the inner expression. It simply continues
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
304 // on and doesn't loop.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
305 r.stackPop()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
306
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
307 oldMarkPos := r.stackPeek()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
308
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
309 if r.textPos() != oldMarkPos { // Nonempty match -> try to loop again by going to 'back' state
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
310 if oldMarkPos != -1 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
311 r.trackPush2(oldMarkPos, r.textPos()) // Save old mark, textpos
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
312 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
313 r.trackPush2(r.textPos(), r.textPos())
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
314 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
315 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
316 // The inner expression found an empty match, so we'll go directly to 'back2' if we
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
317 // backtrack. In this case, we need to push something on the stack, since back2 pops.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
318 // However, in the case of ()+? or similar, this empty match may be legitimate, so push the text
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
319 // position associated with that empty match.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
320 r.stackPush(oldMarkPos)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
321
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
322 r.trackPushNeg1(r.stackPeek()) // Save old mark
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
323 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
324 r.advance(1)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
325 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
326 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
327
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
328 case syntax.Lazybranchmark | syntax.Back:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
329
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
330 // After the first time, Lazybranchmark | syntax.Back occurs
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
331 // with each iteration of the loop, and therefore with every attempted
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
332 // match of the inner expression. We'll try to match the inner expression,
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
333 // then go back to Lazybranchmark if successful. If the inner expression
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
334 // fails, we go to Lazybranchmark | syntax.Back2
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
335
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
336 r.trackPopN(2)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
337 pos := r.trackPeekN(1)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
338 r.trackPushNeg1(r.trackPeek()) // Save old mark
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
339 r.stackPush(pos) // Make new mark
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
340 r.textto(pos) // Recall position
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
341 r.goTo(r.operand(0)) // Loop
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
342 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
343
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
344 case syntax.Lazybranchmark | syntax.Back2:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
345 // The lazy loop has failed. We'll do a true backtrack and
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
346 // start over before the lazy loop.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
347 r.stackPop()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
348 r.trackPop()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
349 r.stackPush(r.trackPeek()) // Recall old mark
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
350 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
351
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
352 case syntax.Setcount:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
353 r.stackPush2(r.textPos(), r.operand(0))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
354 r.trackPush()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
355 r.advance(1)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
356 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
357
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
358 case syntax.Nullcount:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
359 r.stackPush2(-1, r.operand(0))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
360 r.trackPush()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
361 r.advance(1)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
362 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
363
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
364 case syntax.Setcount | syntax.Back:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
365 r.stackPopN(2)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
366 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
367
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
368 case syntax.Nullcount | syntax.Back:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
369 r.stackPopN(2)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
370 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
371
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
372 case syntax.Branchcount:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
373 // r.stackPush:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
374 // 0: Mark
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
375 // 1: Count
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
376
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
377 r.stackPopN(2)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
378 mark := r.stackPeek()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
379 count := r.stackPeekN(1)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
380 matched := r.textPos() - mark
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
381
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
382 if count >= r.operand(1) || (matched == 0 && count >= 0) { // Max loops or empty match -> straight now
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
383 r.trackPushNeg2(mark, count) // Save old mark, count
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
384 r.advance(2) // Straight
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
385 } else { // Nonempty match -> count+loop now
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
386 r.trackPush1(mark) // remember mark
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
387 r.stackPush2(r.textPos(), count+1) // Make new mark, incr count
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
388 r.goTo(r.operand(0)) // Loop
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
389 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
390 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
391
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
392 case syntax.Branchcount | syntax.Back:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
393 // r.trackPush:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
394 // 0: Previous mark
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
395 // r.stackPush:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
396 // 0: Mark (= current pos, discarded)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
397 // 1: Count
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
398 r.trackPop()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
399 r.stackPopN(2)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
400 if r.stackPeekN(1) > 0 { // Positive -> can go straight
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
401 r.textto(r.stackPeek()) // Zap to mark
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
402 r.trackPushNeg2(r.trackPeek(), r.stackPeekN(1)-1) // Save old mark, old count
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
403 r.advance(2) // Straight
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
404 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
405 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
406 r.stackPush2(r.trackPeek(), r.stackPeekN(1)-1) // recall old mark, old count
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
407 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
408
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
409 case syntax.Branchcount | syntax.Back2:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
410 // r.trackPush:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
411 // 0: Previous mark
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
412 // 1: Previous count
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
413 r.trackPopN(2)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
414 r.stackPush2(r.trackPeek(), r.trackPeekN(1)) // Recall old mark, old count
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
415 break // Backtrack
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
416
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
417 case syntax.Lazybranchcount:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
418 // r.stackPush:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
419 // 0: Mark
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
420 // 1: Count
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
421
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
422 r.stackPopN(2)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
423 mark := r.stackPeek()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
424 count := r.stackPeekN(1)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
425
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
426 if count < 0 { // Negative count -> loop now
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
427 r.trackPushNeg1(mark) // Save old mark
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
428 r.stackPush2(r.textPos(), count+1) // Make new mark, incr count
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
429 r.goTo(r.operand(0)) // Loop
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
430 } else { // Nonneg count -> straight now
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
431 r.trackPush3(mark, count, r.textPos()) // Save mark, count, position
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
432 r.advance(2) // Straight
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
433 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
434 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
435
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
436 case syntax.Lazybranchcount | syntax.Back:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
437 // r.trackPush:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
438 // 0: Mark
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
439 // 1: Count
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
440 // 2: r.textPos
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
441
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
442 r.trackPopN(3)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
443 mark := r.trackPeek()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
444 textpos := r.trackPeekN(2)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
445
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
446 if r.trackPeekN(1) < r.operand(1) && textpos != mark { // Under limit and not empty match -> loop
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
447 r.textto(textpos) // Recall position
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
448 r.stackPush2(textpos, r.trackPeekN(1)+1) // Make new mark, incr count
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
449 r.trackPushNeg1(mark) // Save old mark
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
450 r.goTo(r.operand(0)) // Loop
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
451 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
452 } else { // Max loops or empty match -> backtrack
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
453 r.stackPush2(r.trackPeek(), r.trackPeekN(1)) // Recall old mark, count
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
454 break // backtrack
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
455 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
456
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
457 case syntax.Lazybranchcount | syntax.Back2:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
458 // r.trackPush:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
459 // 0: Previous mark
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
460 // r.stackPush:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
461 // 0: Mark (== current pos, discarded)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
462 // 1: Count
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
463 r.trackPop()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
464 r.stackPopN(2)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
465 r.stackPush2(r.trackPeek(), r.stackPeekN(1)-1) // Recall old mark, count
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
466 break // Backtrack
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
467
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
468 case syntax.Setjump:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
469 r.stackPush2(r.trackpos(), r.crawlpos())
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
470 r.trackPush()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
471 r.advance(0)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
472 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
473
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
474 case syntax.Setjump | syntax.Back:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
475 r.stackPopN(2)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
476 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
477
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
478 case syntax.Backjump:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
479 // r.stackPush:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
480 // 0: Saved trackpos
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
481 // 1: r.crawlpos
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
482 r.stackPopN(2)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
483 r.trackto(r.stackPeek())
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
484
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
485 for r.crawlpos() != r.stackPeekN(1) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
486 r.uncapture()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
487 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
488
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
489 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
490
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
491 case syntax.Forejump:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
492 // r.stackPush:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
493 // 0: Saved trackpos
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
494 // 1: r.crawlpos
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
495 r.stackPopN(2)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
496 r.trackto(r.stackPeek())
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
497 r.trackPush1(r.stackPeekN(1))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
498 r.advance(0)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
499 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
500
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
501 case syntax.Forejump | syntax.Back:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
502 // r.trackPush:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
503 // 0: r.crawlpos
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
504 r.trackPop()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
505
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
506 for r.crawlpos() != r.trackPeek() {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
507 r.uncapture()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
508 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
509
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
510 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
511
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
512 case syntax.Bol:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
513 if r.leftchars() > 0 && r.charAt(r.textPos()-1) != '\n' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
514 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
515 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
516 r.advance(0)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
517 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
518
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
519 case syntax.Eol:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
520 if r.rightchars() > 0 && r.charAt(r.textPos()) != '\n' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
521 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
522 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
523 r.advance(0)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
524 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
525
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
526 case syntax.Boundary:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
527 if !r.isBoundary(r.textPos(), 0, r.runtextend) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
528 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
529 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
530 r.advance(0)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
531 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
532
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
533 case syntax.Nonboundary:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
534 if r.isBoundary(r.textPos(), 0, r.runtextend) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
535 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
536 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
537 r.advance(0)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
538 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
539
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
540 case syntax.ECMABoundary:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
541 if !r.isECMABoundary(r.textPos(), 0, r.runtextend) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
542 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
543 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
544 r.advance(0)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
545 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
546
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
547 case syntax.NonECMABoundary:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
548 if r.isECMABoundary(r.textPos(), 0, r.runtextend) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
549 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
550 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
551 r.advance(0)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
552 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
553
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
554 case syntax.Beginning:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
555 if r.leftchars() > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
556 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
557 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
558 r.advance(0)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
559 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
560
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
561 case syntax.Start:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
562 if r.textPos() != r.textstart() {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
563 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
564 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
565 r.advance(0)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
566 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
567
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
568 case syntax.EndZ:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
569 rchars := r.rightchars()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
570 if rchars > 1 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
571 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
572 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
573 // RE2 and EcmaScript define $ as "asserts position at the end of the string"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
574 // PCRE/.NET adds "or before the line terminator right at the end of the string (if any)"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
575 if (r.re.options & (RE2 | ECMAScript)) != 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
576 // RE2/Ecmascript mode
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
577 if rchars > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
578 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
579 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
580 } else if rchars == 1 && r.charAt(r.textPos()) != '\n' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
581 // "regular" mode
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
582 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
583 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
584
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
585 r.advance(0)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
586 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
587
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
588 case syntax.End:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
589 if r.rightchars() > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
590 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
591 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
592 r.advance(0)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
593 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
594
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
595 case syntax.One:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
596 if r.forwardchars() < 1 || r.forwardcharnext() != rune(r.operand(0)) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
597 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
598 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
599
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
600 r.advance(1)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
601 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
602
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
603 case syntax.Notone:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
604 if r.forwardchars() < 1 || r.forwardcharnext() == rune(r.operand(0)) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
605 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
606 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
607
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
608 r.advance(1)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
609 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
610
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
611 case syntax.Set:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
612
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
613 if r.forwardchars() < 1 || !r.code.Sets[r.operand(0)].CharIn(r.forwardcharnext()) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
614 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
615 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
616
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
617 r.advance(1)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
618 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
619
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
620 case syntax.Multi:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
621 if !r.runematch(r.code.Strings[r.operand(0)]) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
622 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
623 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
624
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
625 r.advance(1)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
626 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
627
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
628 case syntax.Ref:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
629
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
630 capnum := r.operand(0)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
631
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
632 if r.runmatch.isMatched(capnum) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
633 if !r.refmatch(r.runmatch.matchIndex(capnum), r.runmatch.matchLength(capnum)) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
634 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
635 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
636 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
637 if (r.re.options & ECMAScript) == 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
638 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
639 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
640 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
641
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
642 r.advance(1)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
643 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
644
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
645 case syntax.Onerep:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
646
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
647 c := r.operand(1)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
648
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
649 if r.forwardchars() < c {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
650 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
651 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
652
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
653 ch := rune(r.operand(0))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
654
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
655 for c > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
656 if r.forwardcharnext() != ch {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
657 goto BreakBackward
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
658 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
659 c--
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
660 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
661
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
662 r.advance(2)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
663 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
664
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
665 case syntax.Notonerep:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
666
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
667 c := r.operand(1)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
668
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
669 if r.forwardchars() < c {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
670 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
671 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
672 ch := rune(r.operand(0))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
673
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
674 for c > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
675 if r.forwardcharnext() == ch {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
676 goto BreakBackward
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
677 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
678 c--
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
679 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
680
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
681 r.advance(2)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
682 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
683
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
684 case syntax.Setrep:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
685
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
686 c := r.operand(1)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
687
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
688 if r.forwardchars() < c {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
689 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
690 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
691
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
692 set := r.code.Sets[r.operand(0)]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
693
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
694 for c > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
695 if !set.CharIn(r.forwardcharnext()) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
696 goto BreakBackward
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
697 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
698 c--
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
699 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
700
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
701 r.advance(2)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
702 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
703
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
704 case syntax.Oneloop:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
705
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
706 c := r.operand(1)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
707
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
708 if c > r.forwardchars() {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
709 c = r.forwardchars()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
710 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
711
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
712 ch := rune(r.operand(0))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
713 i := c
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
714
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
715 for ; i > 0; i-- {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
716 if r.forwardcharnext() != ch {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
717 r.backwardnext()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
718 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
719 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
720 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
721
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
722 if c > i {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
723 r.trackPush2(c-i-1, r.textPos()-r.bump())
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
724 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
725
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
726 r.advance(2)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
727 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
728
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
729 case syntax.Notoneloop:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
730
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
731 c := r.operand(1)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
732
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
733 if c > r.forwardchars() {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
734 c = r.forwardchars()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
735 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
736
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
737 ch := rune(r.operand(0))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
738 i := c
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
739
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
740 for ; i > 0; i-- {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
741 if r.forwardcharnext() == ch {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
742 r.backwardnext()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
743 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
744 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
745 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
746
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
747 if c > i {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
748 r.trackPush2(c-i-1, r.textPos()-r.bump())
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
749 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
750
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
751 r.advance(2)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
752 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
753
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
754 case syntax.Setloop:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
755
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
756 c := r.operand(1)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
757
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
758 if c > r.forwardchars() {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
759 c = r.forwardchars()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
760 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
761
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
762 set := r.code.Sets[r.operand(0)]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
763 i := c
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
764
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
765 for ; i > 0; i-- {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
766 if !set.CharIn(r.forwardcharnext()) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
767 r.backwardnext()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
768 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
769 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
770 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
771
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
772 if c > i {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
773 r.trackPush2(c-i-1, r.textPos()-r.bump())
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
774 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
775
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
776 r.advance(2)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
777 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
778
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
779 case syntax.Oneloop | syntax.Back, syntax.Notoneloop | syntax.Back:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
780
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
781 r.trackPopN(2)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
782 i := r.trackPeek()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
783 pos := r.trackPeekN(1)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
784
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
785 r.textto(pos)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
786
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
787 if i > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
788 r.trackPush2(i-1, pos-r.bump())
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
789 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
790
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
791 r.advance(2)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
792 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
793
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
794 case syntax.Setloop | syntax.Back:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
795
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
796 r.trackPopN(2)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
797 i := r.trackPeek()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
798 pos := r.trackPeekN(1)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
799
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
800 r.textto(pos)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
801
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
802 if i > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
803 r.trackPush2(i-1, pos-r.bump())
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
804 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
805
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
806 r.advance(2)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
807 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
808
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
809 case syntax.Onelazy, syntax.Notonelazy:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
810
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
811 c := r.operand(1)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
812
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
813 if c > r.forwardchars() {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
814 c = r.forwardchars()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
815 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
816
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
817 if c > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
818 r.trackPush2(c-1, r.textPos())
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
819 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
820
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
821 r.advance(2)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
822 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
823
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
824 case syntax.Setlazy:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
825
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
826 c := r.operand(1)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
827
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
828 if c > r.forwardchars() {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
829 c = r.forwardchars()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
830 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
831
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
832 if c > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
833 r.trackPush2(c-1, r.textPos())
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
834 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
835
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
836 r.advance(2)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
837 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
838
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
839 case syntax.Onelazy | syntax.Back:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
840
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
841 r.trackPopN(2)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
842 pos := r.trackPeekN(1)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
843 r.textto(pos)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
844
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
845 if r.forwardcharnext() != rune(r.operand(0)) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
846 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
847 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
848
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
849 i := r.trackPeek()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
850
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
851 if i > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
852 r.trackPush2(i-1, pos+r.bump())
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
853 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
854
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
855 r.advance(2)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
856 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
857
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
858 case syntax.Notonelazy | syntax.Back:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
859
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
860 r.trackPopN(2)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
861 pos := r.trackPeekN(1)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
862 r.textto(pos)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
863
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
864 if r.forwardcharnext() == rune(r.operand(0)) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
865 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
866 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
867
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
868 i := r.trackPeek()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
869
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
870 if i > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
871 r.trackPush2(i-1, pos+r.bump())
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
872 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
873
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
874 r.advance(2)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
875 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
876
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
877 case syntax.Setlazy | syntax.Back:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
878
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
879 r.trackPopN(2)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
880 pos := r.trackPeekN(1)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
881 r.textto(pos)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
882
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
883 if !r.code.Sets[r.operand(0)].CharIn(r.forwardcharnext()) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
884 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
885 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
886
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
887 i := r.trackPeek()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
888
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
889 if i > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
890 r.trackPush2(i-1, pos+r.bump())
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
891 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
892
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
893 r.advance(2)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
894 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
895
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
896 default:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
897 return errors.New("unknown state in regex runner")
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
898 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
899
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
900 BreakBackward:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
901 ;
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
902
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
903 // "break Backward" comes here:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
904 r.backtrack()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
905 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
906 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
907
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
908 // increase the size of stack and track storage
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
909 func (r *runner) ensureStorage() {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
910 if r.runstackpos < r.runtrackcount*4 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
911 doubleIntSlice(&r.runstack, &r.runstackpos)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
912 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
913 if r.runtrackpos < r.runtrackcount*4 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
914 doubleIntSlice(&r.runtrack, &r.runtrackpos)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
915 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
916 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
917
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
918 func doubleIntSlice(s *[]int, pos *int) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
919 oldLen := len(*s)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
920 newS := make([]int, oldLen*2)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
921
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
922 copy(newS[oldLen:], *s)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
923 *pos += oldLen
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
924 *s = newS
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
925 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
926
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
927 // Save a number on the longjump unrolling stack
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
928 func (r *runner) crawl(i int) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
929 if r.runcrawlpos == 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
930 doubleIntSlice(&r.runcrawl, &r.runcrawlpos)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
931 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
932 r.runcrawlpos--
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
933 r.runcrawl[r.runcrawlpos] = i
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
934 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
935
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
936 // Remove a number from the longjump unrolling stack
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
937 func (r *runner) popcrawl() int {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
938 val := r.runcrawl[r.runcrawlpos]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
939 r.runcrawlpos++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
940 return val
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
941 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
942
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
943 // Get the height of the stack
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
944 func (r *runner) crawlpos() int {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
945 return len(r.runcrawl) - r.runcrawlpos
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
946 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
947
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
948 func (r *runner) advance(i int) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
949 r.codepos += (i + 1)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
950 r.setOperator(r.code.Codes[r.codepos])
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
951 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
952
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
953 func (r *runner) goTo(newpos int) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
954 // when branching backward or in place, ensure storage
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
955 if newpos <= r.codepos {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
956 r.ensureStorage()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
957 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
958
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
959 r.setOperator(r.code.Codes[newpos])
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
960 r.codepos = newpos
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
961 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
962
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
963 func (r *runner) textto(newpos int) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
964 r.runtextpos = newpos
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
965 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
966
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
967 func (r *runner) trackto(newpos int) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
968 r.runtrackpos = len(r.runtrack) - newpos
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
969 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
970
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
971 func (r *runner) textstart() int {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
972 return r.runtextstart
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
973 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
974
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
975 func (r *runner) textPos() int {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
976 return r.runtextpos
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
977 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
978
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
979 // push onto the backtracking stack
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
980 func (r *runner) trackpos() int {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
981 return len(r.runtrack) - r.runtrackpos
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
982 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
983
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
984 func (r *runner) trackPush() {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
985 r.runtrackpos--
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
986 r.runtrack[r.runtrackpos] = r.codepos
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
987 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
988
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
989 func (r *runner) trackPush1(I1 int) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
990 r.runtrackpos--
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
991 r.runtrack[r.runtrackpos] = I1
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
992 r.runtrackpos--
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
993 r.runtrack[r.runtrackpos] = r.codepos
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
994 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
995
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
996 func (r *runner) trackPush2(I1, I2 int) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
997 r.runtrackpos--
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
998 r.runtrack[r.runtrackpos] = I1
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
999 r.runtrackpos--
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1000 r.runtrack[r.runtrackpos] = I2
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1001 r.runtrackpos--
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1002 r.runtrack[r.runtrackpos] = r.codepos
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1003 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1004
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1005 func (r *runner) trackPush3(I1, I2, I3 int) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1006 r.runtrackpos--
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1007 r.runtrack[r.runtrackpos] = I1
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1008 r.runtrackpos--
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1009 r.runtrack[r.runtrackpos] = I2
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1010 r.runtrackpos--
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1011 r.runtrack[r.runtrackpos] = I3
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1012 r.runtrackpos--
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1013 r.runtrack[r.runtrackpos] = r.codepos
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1014 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1015
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1016 func (r *runner) trackPushNeg1(I1 int) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1017 r.runtrackpos--
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1018 r.runtrack[r.runtrackpos] = I1
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1019 r.runtrackpos--
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1020 r.runtrack[r.runtrackpos] = -r.codepos
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1021 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1022
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1023 func (r *runner) trackPushNeg2(I1, I2 int) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1024 r.runtrackpos--
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1025 r.runtrack[r.runtrackpos] = I1
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1026 r.runtrackpos--
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1027 r.runtrack[r.runtrackpos] = I2
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1028 r.runtrackpos--
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1029 r.runtrack[r.runtrackpos] = -r.codepos
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1030 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1031
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1032 func (r *runner) backtrack() {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1033 newpos := r.runtrack[r.runtrackpos]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1034 r.runtrackpos++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1035
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1036 if r.re.Debug() {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1037 if newpos < 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1038 fmt.Printf(" Backtracking (back2) to code position %v\n", -newpos)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1039 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1040 fmt.Printf(" Backtracking to code position %v\n", newpos)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1041 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1042 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1043
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1044 if newpos < 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1045 newpos = -newpos
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1046 r.setOperator(r.code.Codes[newpos] | syntax.Back2)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1047 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1048 r.setOperator(r.code.Codes[newpos] | syntax.Back)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1049 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1050
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1051 // When branching backward, ensure storage
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1052 if newpos < r.codepos {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1053 r.ensureStorage()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1054 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1055
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1056 r.codepos = newpos
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1057 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1058
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1059 func (r *runner) setOperator(op int) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1060 r.caseInsensitive = (0 != (op & syntax.Ci))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1061 r.rightToLeft = (0 != (op & syntax.Rtl))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1062 r.operator = syntax.InstOp(op & ^(syntax.Rtl | syntax.Ci))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1063 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1064
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1065 func (r *runner) trackPop() {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1066 r.runtrackpos++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1067 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1068
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1069 // pop framesize items from the backtracking stack
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1070 func (r *runner) trackPopN(framesize int) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1071 r.runtrackpos += framesize
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1072 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1073
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1074 // Technically we are actually peeking at items already popped. So if you want to
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1075 // get and pop the top item from the stack, you do
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1076 // r.trackPop();
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1077 // r.trackPeek();
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1078 func (r *runner) trackPeek() int {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1079 return r.runtrack[r.runtrackpos-1]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1080 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1081
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1082 // get the ith element down on the backtracking stack
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1083 func (r *runner) trackPeekN(i int) int {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1084 return r.runtrack[r.runtrackpos-i-1]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1085 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1086
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1087 // Push onto the grouping stack
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1088 func (r *runner) stackPush(I1 int) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1089 r.runstackpos--
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1090 r.runstack[r.runstackpos] = I1
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1091 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1092
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1093 func (r *runner) stackPush2(I1, I2 int) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1094 r.runstackpos--
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1095 r.runstack[r.runstackpos] = I1
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1096 r.runstackpos--
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1097 r.runstack[r.runstackpos] = I2
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1098 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1099
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1100 func (r *runner) stackPop() {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1101 r.runstackpos++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1102 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1103
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1104 // pop framesize items from the grouping stack
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1105 func (r *runner) stackPopN(framesize int) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1106 r.runstackpos += framesize
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1107 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1108
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1109 // Technically we are actually peeking at items already popped. So if you want to
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1110 // get and pop the top item from the stack, you do
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1111 // r.stackPop();
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1112 // r.stackPeek();
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1113 func (r *runner) stackPeek() int {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1114 return r.runstack[r.runstackpos-1]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1115 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1116
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1117 // get the ith element down on the grouping stack
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1118 func (r *runner) stackPeekN(i int) int {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1119 return r.runstack[r.runstackpos-i-1]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1120 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1121
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1122 func (r *runner) operand(i int) int {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1123 return r.code.Codes[r.codepos+i+1]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1124 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1125
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1126 func (r *runner) leftchars() int {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1127 return r.runtextpos
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1128 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1129
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1130 func (r *runner) rightchars() int {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1131 return r.runtextend - r.runtextpos
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1132 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1133
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1134 func (r *runner) bump() int {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1135 if r.rightToLeft {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1136 return -1
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1137 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1138 return 1
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1139 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1140
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1141 func (r *runner) forwardchars() int {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1142 if r.rightToLeft {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1143 return r.runtextpos
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1144 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1145 return r.runtextend - r.runtextpos
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1146 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1147
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1148 func (r *runner) forwardcharnext() rune {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1149 var ch rune
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1150 if r.rightToLeft {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1151 r.runtextpos--
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1152 ch = r.runtext[r.runtextpos]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1153 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1154 ch = r.runtext[r.runtextpos]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1155 r.runtextpos++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1156 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1157
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1158 if r.caseInsensitive {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1159 return unicode.ToLower(ch)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1160 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1161 return ch
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1162 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1163
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1164 func (r *runner) runematch(str []rune) bool {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1165 var pos int
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1166
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1167 c := len(str)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1168 if !r.rightToLeft {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1169 if r.runtextend-r.runtextpos < c {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1170 return false
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1171 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1172
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1173 pos = r.runtextpos + c
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1174 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1175 if r.runtextpos-0 < c {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1176 return false
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1177 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1178
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1179 pos = r.runtextpos
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1180 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1181
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1182 if !r.caseInsensitive {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1183 for c != 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1184 c--
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1185 pos--
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1186 if str[c] != r.runtext[pos] {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1187 return false
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1188 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1189 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1190 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1191 for c != 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1192 c--
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1193 pos--
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1194 if str[c] != unicode.ToLower(r.runtext[pos]) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1195 return false
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1196 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1197 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1198 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1199
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1200 if !r.rightToLeft {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1201 pos += len(str)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1202 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1203
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1204 r.runtextpos = pos
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1205
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1206 return true
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1207 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1208
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1209 func (r *runner) refmatch(index, len int) bool {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1210 var c, pos, cmpos int
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1211
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1212 if !r.rightToLeft {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1213 if r.runtextend-r.runtextpos < len {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1214 return false
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1215 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1216
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1217 pos = r.runtextpos + len
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1218 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1219 if r.runtextpos-0 < len {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1220 return false
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1221 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1222
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1223 pos = r.runtextpos
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1224 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1225 cmpos = index + len
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1226
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1227 c = len
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1228
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1229 if !r.caseInsensitive {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1230 for c != 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1231 c--
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1232 cmpos--
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1233 pos--
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1234 if r.runtext[cmpos] != r.runtext[pos] {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1235 return false
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1236 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1237
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1238 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1239 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1240 for c != 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1241 c--
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1242 cmpos--
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1243 pos--
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1244
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1245 if unicode.ToLower(r.runtext[cmpos]) != unicode.ToLower(r.runtext[pos]) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1246 return false
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1247 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1248 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1249 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1250
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1251 if !r.rightToLeft {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1252 pos += len
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1253 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1254
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1255 r.runtextpos = pos
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1256
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1257 return true
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1258 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1259
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1260 func (r *runner) backwardnext() {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1261 if r.rightToLeft {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1262 r.runtextpos++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1263 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1264 r.runtextpos--
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1265 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1266 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1267
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1268 func (r *runner) charAt(j int) rune {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1269 return r.runtext[j]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1270 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1271
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1272 func (r *runner) findFirstChar() bool {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1273
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1274 if 0 != (r.code.Anchors & (syntax.AnchorBeginning | syntax.AnchorStart | syntax.AnchorEndZ | syntax.AnchorEnd)) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1275 if !r.code.RightToLeft {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1276 if (0 != (r.code.Anchors&syntax.AnchorBeginning) && r.runtextpos > 0) ||
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1277 (0 != (r.code.Anchors&syntax.AnchorStart) && r.runtextpos > r.runtextstart) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1278 r.runtextpos = r.runtextend
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1279 return false
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1280 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1281 if 0 != (r.code.Anchors&syntax.AnchorEndZ) && r.runtextpos < r.runtextend-1 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1282 r.runtextpos = r.runtextend - 1
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1283 } else if 0 != (r.code.Anchors&syntax.AnchorEnd) && r.runtextpos < r.runtextend {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1284 r.runtextpos = r.runtextend
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1285 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1286 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1287 if (0 != (r.code.Anchors&syntax.AnchorEnd) && r.runtextpos < r.runtextend) ||
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1288 (0 != (r.code.Anchors&syntax.AnchorEndZ) && (r.runtextpos < r.runtextend-1 ||
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1289 (r.runtextpos == r.runtextend-1 && r.charAt(r.runtextpos) != '\n'))) ||
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1290 (0 != (r.code.Anchors&syntax.AnchorStart) && r.runtextpos < r.runtextstart) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1291 r.runtextpos = 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1292 return false
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1293 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1294 if 0 != (r.code.Anchors&syntax.AnchorBeginning) && r.runtextpos > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1295 r.runtextpos = 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1296 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1297 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1298
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1299 if r.code.BmPrefix != nil {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1300 return r.code.BmPrefix.IsMatch(r.runtext, r.runtextpos, 0, r.runtextend)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1301 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1302
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1303 return true // found a valid start or end anchor
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1304 } else if r.code.BmPrefix != nil {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1305 r.runtextpos = r.code.BmPrefix.Scan(r.runtext, r.runtextpos, 0, r.runtextend)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1306
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1307 if r.runtextpos == -1 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1308 if r.code.RightToLeft {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1309 r.runtextpos = 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1310 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1311 r.runtextpos = r.runtextend
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1312 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1313 return false
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1314 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1315
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1316 return true
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1317 } else if r.code.FcPrefix == nil {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1318 return true
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1319 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1320
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1321 r.rightToLeft = r.code.RightToLeft
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1322 r.caseInsensitive = r.code.FcPrefix.CaseInsensitive
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1323
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1324 set := r.code.FcPrefix.PrefixSet
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1325 if set.IsSingleton() {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1326 ch := set.SingletonChar()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1327 for i := r.forwardchars(); i > 0; i-- {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1328 if ch == r.forwardcharnext() {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1329 r.backwardnext()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1330 return true
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1331 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1332 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1333 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1334 for i := r.forwardchars(); i > 0; i-- {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1335 n := r.forwardcharnext()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1336 //fmt.Printf("%v in %v: %v\n", string(n), set.String(), set.CharIn(n))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1337 if set.CharIn(n) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1338 r.backwardnext()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1339 return true
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1340 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1341 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1342 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1343
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1344 return false
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1345 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1346
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1347 func (r *runner) initMatch() {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1348 // Use a hashtable'ed Match object if the capture numbers are sparse
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1349
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1350 if r.runmatch == nil {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1351 if r.re.caps != nil {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1352 r.runmatch = newMatchSparse(r.re, r.re.caps, r.re.capsize, r.runtext, r.runtextstart)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1353 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1354 r.runmatch = newMatch(r.re, r.re.capsize, r.runtext, r.runtextstart)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1355 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1356 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1357 r.runmatch.reset(r.runtext, r.runtextstart)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1358 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1359
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1360 // note we test runcrawl, because it is the last one to be allocated
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1361 // If there is an alloc failure in the middle of the three allocations,
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1362 // we may still return to reuse this instance, and we want to behave
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1363 // as if the allocations didn't occur. (we used to test _trackcount != 0)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1364
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1365 if r.runcrawl != nil {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1366 r.runtrackpos = len(r.runtrack)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1367 r.runstackpos = len(r.runstack)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1368 r.runcrawlpos = len(r.runcrawl)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1369 return
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1370 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1371
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1372 r.initTrackCount()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1373
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1374 tracksize := r.runtrackcount * 8
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1375 stacksize := r.runtrackcount * 8
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1376
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1377 if tracksize < 32 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1378 tracksize = 32
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1379 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1380 if stacksize < 16 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1381 stacksize = 16
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1382 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1383
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1384 r.runtrack = make([]int, tracksize)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1385 r.runtrackpos = tracksize
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1386
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1387 r.runstack = make([]int, stacksize)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1388 r.runstackpos = stacksize
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1389
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1390 r.runcrawl = make([]int, 32)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1391 r.runcrawlpos = 32
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1392 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1393
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1394 func (r *runner) tidyMatch(quick bool) *Match {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1395 if !quick {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1396 match := r.runmatch
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1397
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1398 r.runmatch = nil
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1399
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1400 match.tidy(r.runtextpos)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1401 return match
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1402 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1403 // send back our match -- it's not leaving the package, so it's safe to not clean it up
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1404 // this reduces allocs for frequent calls to the "IsMatch" bool-only functions
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1405 return r.runmatch
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1406 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1407 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1408
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1409 // capture captures a subexpression. Note that the
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1410 // capnum used here has already been mapped to a non-sparse
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1411 // index (by the code generator RegexWriter).
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1412 func (r *runner) capture(capnum, start, end int) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1413 if end < start {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1414 T := end
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1415 end = start
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1416 start = T
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1417 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1418
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1419 r.crawl(capnum)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1420 r.runmatch.addMatch(capnum, start, end-start)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1421 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1422
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1423 // transferCapture captures a subexpression. Note that the
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1424 // capnum used here has already been mapped to a non-sparse
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1425 // index (by the code generator RegexWriter).
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1426 func (r *runner) transferCapture(capnum, uncapnum, start, end int) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1427 var start2, end2 int
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1428
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1429 // these are the two intervals that are cancelling each other
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1430
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1431 if end < start {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1432 T := end
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1433 end = start
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1434 start = T
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1435 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1436
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1437 start2 = r.runmatch.matchIndex(uncapnum)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1438 end2 = start2 + r.runmatch.matchLength(uncapnum)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1439
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1440 // The new capture gets the innermost defined interval
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1441
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1442 if start >= end2 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1443 end = start
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1444 start = end2
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1445 } else if end <= start2 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1446 start = start2
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1447 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1448 if end > end2 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1449 end = end2
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1450 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1451 if start2 > start {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1452 start = start2
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1453 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1454 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1455
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1456 r.crawl(uncapnum)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1457 r.runmatch.balanceMatch(uncapnum)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1458
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1459 if capnum != -1 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1460 r.crawl(capnum)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1461 r.runmatch.addMatch(capnum, start, end-start)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1462 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1463 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1464
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1465 // revert the last capture
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1466 func (r *runner) uncapture() {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1467 capnum := r.popcrawl()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1468 r.runmatch.removeMatch(capnum)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1469 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1470
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1471 //debug
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1472
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1473 func (r *runner) dumpState() {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1474 back := ""
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1475 if r.operator&syntax.Back != 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1476 back = " Back"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1477 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1478 if r.operator&syntax.Back2 != 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1479 back += " Back2"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1480 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1481 fmt.Printf("Text: %v\nTrack: %v\nStack: %v\n %s%s\n\n",
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1482 r.textposDescription(),
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1483 r.stackDescription(r.runtrack, r.runtrackpos),
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1484 r.stackDescription(r.runstack, r.runstackpos),
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1485 r.code.OpcodeDescription(r.codepos),
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1486 back)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1487 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1488
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1489 func (r *runner) stackDescription(a []int, index int) string {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1490 buf := &bytes.Buffer{}
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1491
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1492 fmt.Fprintf(buf, "%v/%v", len(a)-index, len(a))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1493 if buf.Len() < 8 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1494 buf.WriteString(strings.Repeat(" ", 8-buf.Len()))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1495 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1496
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1497 buf.WriteRune('(')
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1498 for i := index; i < len(a); i++ {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1499 if i > index {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1500 buf.WriteRune(' ')
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1501 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1502
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1503 buf.WriteString(strconv.Itoa(a[i]))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1504 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1505
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1506 buf.WriteRune(')')
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1507
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1508 return buf.String()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1509 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1510
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1511 func (r *runner) textposDescription() string {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1512 buf := &bytes.Buffer{}
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1513
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1514 buf.WriteString(strconv.Itoa(r.runtextpos))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1515
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1516 if buf.Len() < 8 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1517 buf.WriteString(strings.Repeat(" ", 8-buf.Len()))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1518 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1519
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1520 if r.runtextpos > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1521 buf.WriteString(syntax.CharDescription(r.runtext[r.runtextpos-1]))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1522 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1523 buf.WriteRune('^')
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1524 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1525
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1526 buf.WriteRune('>')
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1527
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1528 for i := r.runtextpos; i < r.runtextend; i++ {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1529 buf.WriteString(syntax.CharDescription(r.runtext[i]))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1530 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1531 if buf.Len() >= 64 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1532 buf.Truncate(61)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1533 buf.WriteString("...")
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1534 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1535 buf.WriteRune('$')
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1536 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1537
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1538 return buf.String()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1539 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1540
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1541 // decide whether the pos
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1542 // at the specified index is a boundary or not. It's just not worth
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1543 // emitting inline code for this logic.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1544 func (r *runner) isBoundary(index, startpos, endpos int) bool {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1545 return (index > startpos && syntax.IsWordChar(r.runtext[index-1])) !=
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1546 (index < endpos && syntax.IsWordChar(r.runtext[index]))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1547 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1548
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1549 func (r *runner) isECMABoundary(index, startpos, endpos int) bool {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1550 return (index > startpos && syntax.IsECMAWordChar(r.runtext[index-1])) !=
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1551 (index < endpos && syntax.IsECMAWordChar(r.runtext[index]))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1552 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1553
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1554 // this seems like a comment to justify randomly picking 1000 :-P
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1555 // We have determined this value in a series of experiments where x86 retail
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1556 // builds (ono-lab-optimized) were run on different pattern/input pairs. Larger values
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1557 // of TimeoutCheckFrequency did not tend to increase performance; smaller values
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1558 // of TimeoutCheckFrequency tended to slow down the execution.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1559 const timeoutCheckFrequency int = 1000
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1560
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1561 func (r *runner) startTimeoutWatch() {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1562 if r.ignoreTimeout {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1563 return
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1564 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1565
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1566 r.timeoutChecksToSkip = timeoutCheckFrequency
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1567 r.timeoutAt = time.Now().Add(r.timeout)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1568 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1569
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1570 func (r *runner) checkTimeout() error {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1571 if r.ignoreTimeout {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1572 return nil
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1573 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1574 r.timeoutChecksToSkip--
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1575 if r.timeoutChecksToSkip != 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1576 return nil
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1577 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1578
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1579 r.timeoutChecksToSkip = timeoutCheckFrequency
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1580 return r.doCheckTimeout()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1581 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1582
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1583 func (r *runner) doCheckTimeout() error {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1584 current := time.Now()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1585
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1586 if current.Before(r.timeoutAt) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1587 return nil
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1588 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1589
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1590 if r.re.Debug() {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1591 //Debug.WriteLine("")
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1592 //Debug.WriteLine("RegEx match timeout occurred!")
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1593 //Debug.WriteLine("Specified timeout: " + TimeSpan.FromMilliseconds(_timeout).ToString())
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1594 //Debug.WriteLine("Timeout check frequency: " + TimeoutCheckFrequency)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1595 //Debug.WriteLine("Search pattern: " + _runregex._pattern)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1596 //Debug.WriteLine("Input: " + r.runtext)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1597 //Debug.WriteLine("About to throw RegexMatchTimeoutException.")
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1598 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1599
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1600 return fmt.Errorf("match timeout after %v on input `%v`", r.timeout, string(r.runtext))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1601 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1602
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1603 func (r *runner) initTrackCount() {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1604 r.runtrackcount = r.code.TrackCount
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1605 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1606
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1607 // getRunner returns a run to use for matching re.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1608 // It uses the re's runner cache if possible, to avoid
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1609 // unnecessary allocation.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1610 func (re *Regexp) getRunner() *runner {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1611 re.muRun.Lock()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1612 if n := len(re.runner); n > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1613 z := re.runner[n-1]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1614 re.runner = re.runner[:n-1]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1615 re.muRun.Unlock()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1616 return z
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1617 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1618 re.muRun.Unlock()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1619 z := &runner{
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1620 re: re,
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1621 code: re.code,
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1622 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1623 return z
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1624 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1625
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1626 // putRunner returns a runner to the re's cache.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1627 // There is no attempt to limit the size of the cache, so it will
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1628 // grow to the maximum number of simultaneous matches
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1629 // run using re. (The cache empties when re gets garbage collected.)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1630 func (re *Regexp) putRunner(r *runner) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1631 re.muRun.Lock()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1632 re.runner = append(re.runner, r)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1633 re.muRun.Unlock()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1634 }