@@ -74,6 +74,73 @@ fileprivate extension Compiler.ByteCodeGen {
74
74
}
75
75
}
76
76
77
+ mutating func emitQuotedLiteral( _ s: String ) {
78
+ if options. semanticLevel == . graphemeCluster {
79
+ if options. isCaseInsensitive {
80
+ // future work: if all ascii, emit matchBitset instructions with
81
+ // case insensitive bitsets
82
+
83
+ // TODO: buildCaseInsensitiveMatchSequence(c) or alternative
84
+ builder. buildConsume { input, bounds in
85
+ var iterator = s. makeIterator ( )
86
+ var currentIndex = bounds. lowerBound
87
+ while let ch = iterator. next ( ) {
88
+ guard currentIndex < bounds. upperBound,
89
+ ch. lowercased ( ) == input [ currentIndex] . lowercased ( )
90
+ else { return nil }
91
+ input. formIndex ( after: & currentIndex)
92
+ }
93
+ return currentIndex
94
+ }
95
+ } else {
96
+ if optimizationsEnabled && s. allSatisfy ( { char in char. isASCII} ) {
97
+ for char in s {
98
+ // Note: only cr-lf is multiple scalars
99
+ for scalar in char. unicodeScalars {
100
+ // Only boundary check if we are the last scalar in the last character
101
+ // to make sure that there isn't a combining scalar after the quoted literal
102
+ let boundaryCheck = char == s. last! && scalar == char. unicodeScalars. last!
103
+ builder. buildMatchScalar ( scalar, boundaryCheck: boundaryCheck)
104
+ }
105
+ }
106
+ } else {
107
+ builder. buildMatchSequence ( s)
108
+ }
109
+ }
110
+ } else {
111
+ if optimizationsEnabled && !options. isCaseInsensitive {
112
+ // Match all scalars exactly, never boundary check because we're in
113
+ // unicode scalars mode
114
+ for char in s {
115
+ for scalar in char. unicodeScalars {
116
+ builder. buildMatchScalar ( scalar, boundaryCheck: false )
117
+ }
118
+ }
119
+ } else {
120
+ builder. buildConsume {
121
+ [ caseInsensitive = options. isCaseInsensitive] input, bounds in
122
+ // TODO: Case folding
123
+ var iterator = s. unicodeScalars. makeIterator ( )
124
+ var currentIndex = bounds. lowerBound
125
+ while let scalar = iterator. next ( ) {
126
+ guard currentIndex < bounds. upperBound else { return nil }
127
+ if caseInsensitive {
128
+ if scalar. properties. lowercaseMapping != input. unicodeScalars [ currentIndex] . properties. lowercaseMapping {
129
+ return nil
130
+ }
131
+ } else {
132
+ if scalar != input. unicodeScalars [ currentIndex] {
133
+ return nil
134
+ }
135
+ }
136
+ input. unicodeScalars. formIndex ( after: & currentIndex)
137
+ }
138
+ return currentIndex
139
+ }
140
+ }
141
+ }
142
+ }
143
+
77
144
mutating func emitBackreference(
78
145
_ ref: AST . Reference
79
146
) throws {
@@ -747,57 +814,7 @@ fileprivate extension Compiler.ByteCodeGen {
747
814
try emitAtom ( a)
748
815
749
816
case let . quotedLiteral( s) :
750
- if options. semanticLevel == . graphemeCluster {
751
- if options. isCaseInsensitive {
752
- // TODO: buildCaseInsensitiveMatchSequence(c) or alternative
753
- builder. buildConsume { input, bounds in
754
- var iterator = s. makeIterator ( )
755
- var currentIndex = bounds. lowerBound
756
- while let ch = iterator. next ( ) {
757
- guard currentIndex < bounds. upperBound,
758
- ch. lowercased ( ) == input [ currentIndex] . lowercased ( )
759
- else { return nil }
760
- input. formIndex ( after: & currentIndex)
761
- }
762
- return currentIndex
763
- }
764
- } else {
765
- if optimizationsEnabled && s. allSatisfy ( { char in char. isASCII} ) {
766
- for char in s {
767
- // Note: only cr-lf is multiple scalars
768
- for scalar in char. unicodeScalars {
769
- // Only boundary check if we are the last scalar in the last character
770
- // to make sure that there isn't a combining scalar after the quoted literal
771
- let boundaryCheck = char == s. last! && scalar == char. unicodeScalars. last!
772
- builder. buildMatchScalar ( scalar, boundaryCheck: boundaryCheck)
773
- }
774
- }
775
- } else {
776
- builder. buildMatchSequence ( s)
777
- }
778
- }
779
- } else {
780
- builder. buildConsume {
781
- [ caseInsensitive = options. isCaseInsensitive] input, bounds in
782
- // TODO: Case folding
783
- var iterator = s. unicodeScalars. makeIterator ( )
784
- var currentIndex = bounds. lowerBound
785
- while let scalar = iterator. next ( ) {
786
- guard currentIndex < bounds. upperBound else { return nil }
787
- if caseInsensitive {
788
- if scalar. properties. lowercaseMapping != input. unicodeScalars [ currentIndex] . properties. lowercaseMapping {
789
- return nil
790
- }
791
- } else {
792
- if scalar != input. unicodeScalars [ currentIndex] {
793
- return nil
794
- }
795
- }
796
- input. unicodeScalars. formIndex ( after: & currentIndex)
797
- }
798
- return currentIndex
799
- }
800
- }
817
+ emitQuotedLiteral ( s)
801
818
802
819
case let . regexLiteral( l) :
803
820
return try emitNode ( l. ast. dslTreeNode)
0 commit comments