@@ -39,7 +39,12 @@ struct Lexer {
3939 }
4040
4141 private var eof : Token {
42- return Token ( kind: . eof, range: source. endIndex..< source. endIndex)
42+ return Token (
43+ kind: . eof,
44+ range: SourceLocation (
45+ range: source. endIndex..< source. endIndex
46+ )
47+ )
4348 }
4449
4550 mutating func next( ) -> Token {
@@ -82,9 +87,9 @@ struct Lexer {
8287 advance ( )
8388 if self . current == " > " {
8489 advance ( )
85- return Token ( kind: . doubleArrow, range: currentIndex..< peekIndex)
90+ return Token ( kind: . doubleArrow, range: location ( from : currentIndex, to : peekIndex) )
8691 } else {
87- return Token ( kind: . arrow, range: currentIndex..< peekIndex)
92+ return Token ( kind: . arrow, range: location ( from : currentIndex, to : peekIndex) )
8893 }
8994 case ( " * " , _) : return consumeSingle ( of: . star)
9095 case ( " = " , _) : return consumeSingle ( of: . equal)
@@ -109,7 +114,7 @@ struct Lexer {
109114 case ( " ~ " , _) : return consumeSingle ( of: . tilde)
110115 case ( " ' " , _) : return parseString ( )
111116 default :
112- diagnostics. add ( . init( " Unexpected character: ' \( current) ' " , at: currentIndex..< peekIndex) )
117+ diagnostics. add ( . init( " Unexpected character: ' \( current) ' " , at: location ( from : currentIndex, to : peekIndex) ) )
113118 advance ( )
114119 return next ( )
115120 }
@@ -130,8 +135,8 @@ struct Lexer {
130135 advance ( )
131136 }
132137
133- let range = start..< currentIndex
134- return Token ( kind: Token . Kind ( word: source [ range] ) , range: range )
138+ let location = location ( from : start, to : currentIndex)
139+ return Token ( kind: Token . Kind ( word: source [ location . range] ) , range: location )
135140 }
136141
137142 private mutating func parseNumber( ) -> Token {
@@ -152,16 +157,16 @@ struct Lexer {
152157 return scientificNotation ( mantissa: start..< currentIndex)
153158 }
154159
155- let range = start..< currentIndex
156- let string = source [ range]
160+ let location = location ( from : start, to : currentIndex)
161+ let string = source [ location . range]
157162
158163 let kind : Token . Kind = if hasSeenDecimal {
159- . double( double ( from: string, at: range) )
164+ . double( double ( from: string, at: location . range) )
160165 } else {
161- . int( integer ( from: string, at: range) )
166+ . int( integer ( from: string, at: location . range) )
162167 }
163168
164- return Token ( kind: kind, range: range )
169+ return Token ( kind: kind, range: location )
165170 }
166171
167172 private mutating func scientificNotation(
@@ -209,7 +214,10 @@ struct Lexer {
209214 let exponentUnsigned = double ( from: source [ exponentRange] , at: exponentRange)
210215 let exponent = isExpoinentPositive ? exponentUnsigned : - exponentUnsigned
211216 let value = mantissa * pow( 10 , exponent)
212- return Token ( kind: . double( value) , range: mantissaRange. lowerBound..< exponentRange. upperBound)
217+ return Token (
218+ kind: . double( value) ,
219+ range: location ( from: mantissaRange. lowerBound, to: exponentRange. upperBound)
220+ )
213221 }
214222
215223 private mutating func consumeDigits( ) {
@@ -231,13 +239,14 @@ struct Lexer {
231239 }
232240
233241 let numberRange = numberStart..< currentIndex
242+ let location = location ( from: tokenStart, to: currentIndex)
234243
235244 guard let value = Int ( source [ numberRange] , radix: 16 ) else {
236- diagnostics. add ( . init( " Invalid hex number " , at: tokenStart ..< currentIndex ) )
237- return Token ( kind: . hex( 0 ) , range: tokenStart ..< currentIndex )
245+ diagnostics. add ( . init( " Invalid hex number " , at: location ) )
246+ return Token ( kind: . hex( 0 ) , range: location )
238247 }
239248
240- return Token ( kind: . hex( value) , range: tokenStart ..< currentIndex )
249+ return Token ( kind: . hex( value) , range: location )
241250 }
242251
243252 private mutating func parseString( ) -> Token {
@@ -254,10 +263,10 @@ struct Lexer {
254263 if current == " ' " {
255264 advance ( )
256265 } else {
257- diagnostics. add ( . init( " Unterminated string " , at: start..< currentIndex) )
266+ diagnostics. add ( . init( " Unterminated string " , at: location ( from : start, to : currentIndex) ) )
258267 }
259268
260- return Token ( kind: . string( source [ stringRange] ) , range: tokenStart..< currentIndex)
269+ return Token ( kind: . string( source [ stringRange] ) , range: location ( from : tokenStart, to : currentIndex) )
261270 }
262271
263272 private mutating func skipWhitespace( ) {
@@ -269,22 +278,22 @@ struct Lexer {
269278 private mutating func consumeSingle( of kind: Token . Kind ) -> Token {
270279 let start = currentIndex
271280 advance ( )
272- return Token ( kind: kind, range: start..< currentIndex)
281+ return Token ( kind: kind, range: location ( from : start, to : currentIndex) )
273282 }
274283
275284 private mutating func consumeDouble( of kind: Token . Kind ) -> Token {
276285 let start = currentIndex
277286 advance ( )
278287 advance ( )
279- return Token ( kind: kind, range: start..< currentIndex)
288+ return Token ( kind: kind, range: location ( from : start, to : currentIndex) )
280289 }
281290
282291 private mutating func integer< S: StringProtocol > (
283292 from source: S ,
284293 at range: Range < String . Index >
285294 ) -> Int {
286295 guard let int = Int ( source. replacingOccurrences ( of: " _ " , with: " " ) ) else {
287- diagnostics. add ( . init( " Invalid integer ' \( source) ' " , at: range) )
296+ diagnostics. add ( . init( " Invalid integer ' \( source) ' " , at: SourceLocation ( range: range ) ) )
288297 return 0
289298 }
290299
@@ -296,7 +305,7 @@ struct Lexer {
296305 at range: Range < String . Index >
297306 ) -> Double {
298307 guard let double = Double ( source. replacingOccurrences ( of: " _ " , with: " " ) ) else {
299- diagnostics. add ( . init( " Invalid double ' \( source) ' " , at: range) )
308+ diagnostics. add ( . init( " Invalid double ' \( source) ' " , at: SourceLocation ( range: range ) ) )
300309 return 0
301310 }
302311
@@ -311,4 +320,11 @@ struct Lexer {
311320 advance ( )
312321 }
313322 }
323+
324+ private func location(
325+ from lowerBound: Substring . Index ,
326+ to upperBound: Substring . Index
327+ ) -> SourceLocation {
328+ return SourceLocation ( range: lowerBound ..< upperBound)
329+ }
314330}
0 commit comments