@@ -276,54 +276,48 @@ extension DSLTree.CustomCharacterClass.Member {
276
276
}
277
277
return c
278
278
case let . range( low, high) :
279
- // TODO:
280
279
guard let lhs = low. literalCharacterValue, lhs. hasExactlyOneScalar else {
281
280
throw Unsupported ( " \( low) in range " )
282
281
}
283
282
guard let rhs = high. literalCharacterValue, rhs. hasExactlyOneScalar else {
284
283
throw Unsupported ( " \( high) in range " )
285
284
}
285
+ guard lhs <= rhs else {
286
+ throw Unsupported ( " Invalid range \( low) - \( high) " )
287
+ }
286
288
289
+ let isCaseInsensitive = opts. isCaseInsensitive
287
290
let isCharacterSemantic = opts. semanticLevel == . graphemeCluster
288
291
289
- if opts. isCaseInsensitive {
290
- let lhsLower = lhs. lowercased ( )
291
- let rhsLower = rhs. lowercased ( )
292
- guard lhsLower <= rhsLower else { throw Unsupported ( " Invalid range \( lhs) - \( rhs) " ) }
293
- return { input, bounds in
294
- // TODO: check for out of bounds?
295
- let curIdx = bounds. lowerBound
296
- if isCharacterSemantic {
297
- guard input [ curIdx] . hasExactlyOneScalar else { return nil }
298
- if ( lhsLower... rhsLower) . contains ( input [ curIdx] . lowercased ( ) ) {
299
- return input. index ( after: curIdx)
300
- }
301
- } else {
302
- if ( lhsLower... rhsLower) . contains ( input. unicodeScalars [ curIdx] . properties. lowercaseMapping) {
303
- return input. unicodeScalars. index ( after: curIdx)
304
- }
305
- }
292
+ return { input, bounds in
293
+ // TODO: check for out of bounds?
294
+ let curIdx = bounds. lowerBound
295
+ let nextIndex = isCharacterSemantic
296
+ ? input. index ( after: curIdx)
297
+ : input. unicodeScalars. index ( after: curIdx)
298
+ if isCharacterSemantic && !input[ curIdx] . hasExactlyOneScalar {
306
299
return nil
307
300
}
308
- } else {
309
- guard lhs <= rhs else { throw Unsupported ( " Invalid range \( lhs) - \( rhs) " ) }
310
- return { input, bounds in
311
- // TODO: check for out of bounds?
312
- let curIdx = bounds. lowerBound
313
- if isCharacterSemantic {
314
- guard input [ curIdx] . hasExactlyOneScalar else { return nil }
315
- if ( lhs... rhs) . contains ( input [ curIdx] ) {
316
- return input. index ( after: curIdx)
317
- }
318
- } else {
319
- if ( lhs... rhs) . contains ( Character ( input. unicodeScalars [ curIdx] ) ) {
320
- return input. unicodeScalars. index ( after: curIdx)
321
- }
322
- }
301
+ let scalar = input. unicodeScalars [ curIdx]
302
+ let scalarRange = lhs. unicodeScalars. first! ... rhs. unicodeScalars. first!
303
+ if scalarRange. contains ( scalar) {
304
+ return nextIndex
305
+ }
306
+ if !isCaseInsensitive {
323
307
return nil
324
308
}
309
+
310
+ let stringRange = String ( lhs) ... String ( rhs)
311
+ if ( scalar. properties. changesWhenLowercased
312
+ && stringRange. contains ( scalar. properties. lowercaseMapping) )
313
+ || ( scalar. properties. changesWhenUppercased
314
+ && stringRange. contains ( scalar. properties. uppercaseMapping) ) {
315
+ return nextIndex
316
+ }
317
+
318
+ return nil
325
319
}
326
-
320
+
327
321
case let . custom( ccc) :
328
322
return try ccc. generateConsumer ( opts)
329
323
0 commit comments