1+ //===----------------------------------------------------------------------===//
2+ //
3+ // This source file is part of the Swift.org open source project
4+ //
5+ // Copyright (c) 2021-2022 Apple Inc. and the Swift project authors
6+ // Licensed under Apache License v2.0 with Runtime Library Exception
7+ //
8+ // See https://swift.org/LICENSE.txt for license information
9+ //
10+ //===----------------------------------------------------------------------===//
11+
12+ @_spi ( _Unicode)
13+ import Swift
14+
115@_implementationOnly import _RegexParser
216
317extension Compiler {
@@ -107,12 +121,13 @@ fileprivate extension Compiler.ByteCodeGen {
107121 // need to supply both a slice bounds and a per-search bounds.
108122 switch kind {
109123 case . startOfSubject:
110- builder. buildAssert { ( input, pos, subjectBounds) in
124+ builder. buildAssert { ( _ , _ , input, pos, subjectBounds) in
111125 pos == subjectBounds. lowerBound
112126 }
113127
114128 case . endOfSubjectBeforeNewline:
115- builder. buildAssert { [ semanticLevel = options. semanticLevel] ( input, pos, subjectBounds) in
129+ builder. buildAssert { [ semanticLevel = options. semanticLevel]
130+ ( _, _, input, pos, subjectBounds) in
116131 if pos == subjectBounds. upperBound { return true }
117132 switch semanticLevel {
118133 case . graphemeCluster:
@@ -125,7 +140,7 @@ fileprivate extension Compiler.ByteCodeGen {
125140 }
126141
127142 case . endOfSubject:
128- builder. buildAssert { ( input, pos, subjectBounds) in
143+ builder. buildAssert { ( _ , _ , input, pos, subjectBounds) in
129144 pos == subjectBounds. upperBound
130145 }
131146
@@ -138,16 +153,16 @@ fileprivate extension Compiler.ByteCodeGen {
138153
139154 // FIXME: This needs to be based on `searchBounds`,
140155 // not the `subjectBounds` given as an argument here
141- builder. buildAssert { ( input, pos, subjectBounds) in false }
156+ builder. buildAssert { ( _ , _ , input, pos, subjectBounds) in false }
142157
143158 case . textSegment:
144- builder. buildAssert { ( input, pos, _) in
159+ builder. buildAssert { ( _ , _ , input, pos, _) in
145160 // FIXME: Grapheme or word based on options
146161 input. isOnGraphemeClusterBoundary ( pos)
147162 }
148163
149164 case . notTextSegment:
150- builder. buildAssert { ( input, pos, _) in
165+ builder. buildAssert { ( _ , _ , input, pos, _) in
151166 // FIXME: Grapheme or word based on options
152167 !input. isOnGraphemeClusterBoundary ( pos)
153168 }
@@ -158,7 +173,8 @@ fileprivate extension Compiler.ByteCodeGen {
158173 // the DSL-based `.startOfLine` anchor should always match the start
159174 // of a line. Right now we don't distinguish between those anchors.
160175 if options. anchorsMatchNewlines {
161- builder. buildAssert { [ semanticLevel = options. semanticLevel] ( input, pos, subjectBounds) in
176+ builder. buildAssert { [ semanticLevel = options. semanticLevel]
177+ ( _, _, input, pos, subjectBounds) in
162178 if pos == subjectBounds. lowerBound { return true }
163179 switch semanticLevel {
164180 case . graphemeCluster:
@@ -168,7 +184,7 @@ fileprivate extension Compiler.ByteCodeGen {
168184 }
169185 }
170186 } else {
171- builder. buildAssert { ( input, pos, subjectBounds) in
187+ builder. buildAssert { ( _ , _ , input, pos, subjectBounds) in
172188 pos == subjectBounds. lowerBound
173189 }
174190 }
@@ -179,7 +195,8 @@ fileprivate extension Compiler.ByteCodeGen {
179195 // the DSL-based `.endOfLine` anchor should always match the end
180196 // of a line. Right now we don't distinguish between those anchors.
181197 if options. anchorsMatchNewlines {
182- builder. buildAssert { [ semanticLevel = options. semanticLevel] ( input, pos, subjectBounds) in
198+ builder. buildAssert { [ semanticLevel = options. semanticLevel]
199+ ( _, _, input, pos, subjectBounds) in
183200 if pos == subjectBounds. upperBound { return true }
184201 switch semanticLevel {
185202 case . graphemeCluster:
@@ -189,25 +206,41 @@ fileprivate extension Compiler.ByteCodeGen {
189206 }
190207 }
191208 } else {
192- builder. buildAssert { ( input, pos, subjectBounds) in
209+ builder. buildAssert { ( _ , _ , input, pos, subjectBounds) in
193210 pos == subjectBounds. upperBound
194211 }
195212 }
196213
197214 case . wordBoundary:
198- // TODO: May want to consider Unicode level
199- builder. buildAssert { [ options] ( input, pos, subjectBounds) in
200- // TODO: How should we handle bounds?
201- _CharacterClassModel. word. isBoundary (
202- input, at: pos, bounds: subjectBounds, with: options)
215+ builder. buildAssert { [ options]
216+ ( cache, maxIndex, input, pos, subjectBounds) in
217+ if options. usesSimpleUnicodeBoundaries {
218+ // TODO: How should we handle bounds?
219+ return _CharacterClassModel. word. isBoundary (
220+ input,
221+ at: pos,
222+ bounds: subjectBounds,
223+ with: options
224+ )
225+ } else {
226+ return input. isOnWordBoundary ( at: pos, using: & cache, & maxIndex)
227+ }
203228 }
204229
205230 case . notWordBoundary:
206- // TODO: May want to consider Unicode level
207- builder. buildAssert { [ options] ( input, pos, subjectBounds) in
208- // TODO: How should we handle bounds?
209- !_CharacterClassModel. word. isBoundary (
210- input, at: pos, bounds: subjectBounds, with: options)
231+ builder. buildAssert { [ options]
232+ ( cache, maxIndex, input, pos, subjectBounds) in
233+ if options. usesSimpleUnicodeBoundaries {
234+ // TODO: How should we handle bounds?
235+ return !_CharacterClassModel. word. isBoundary (
236+ input,
237+ at: pos,
238+ bounds: subjectBounds,
239+ with: options
240+ )
241+ } else {
242+ return !input. isOnWordBoundary ( at: pos, using: & cache, & maxIndex)
243+ }
211244 }
212245 }
213246 }
0 commit comments