@@ -201,6 +201,8 @@ extension Lexer {
201
201
struct Cursor {
202
202
var input : UnsafeBufferPointer < UInt8 >
203
203
var previous : UInt8
204
+ /// If we have already lexed a token, the kind of the previously lexed token
205
+ var previousTokenKind : RawTokenBaseKind ?
204
206
private var stateStack : StateStack = StateStack ( )
205
207
206
208
init ( input: UnsafeBufferPointer < UInt8 > , previous: UInt8 ) {
@@ -335,6 +337,7 @@ extension Lexer.Cursor {
335
337
flags. insert ( . isAtStartOfLine)
336
338
}
337
339
340
+ self . previousTokenKind = result. tokenKind. base
338
341
let error = result. error. map { error in
339
342
return LexerError ( error. kind, byteOffset: cursor. distance ( to: error. position) )
340
343
}
@@ -676,6 +679,9 @@ extension Lexer.Cursor {
676
679
}
677
680
678
681
/// Rever the lexer by `offset` bytes. This should only be used by `resetForSplit`.
682
+ /// This must not back up by more bytes than the last token because that would
683
+ /// require us to also update `previousTokenKind`, which we don't do in this
684
+ /// function
679
685
mutating func backUp( by offset: Int ) {
680
686
assert ( !self . isAtStartOfFile)
681
687
self . previous = self . input. baseAddress!. advanced ( by: - ( offset + 1 ) ) . pointee
@@ -1224,11 +1230,16 @@ extension Lexer.Cursor {
1224
1230
1225
1231
// TODO: This can probably be unified with lexHexNumber somehow
1226
1232
1227
- // Lex things like 4.x as '4' followed by a tok::period.
1228
1233
if self . is ( at: " . " ) {
1229
- // NextToken is the soon to be previous token
1230
- // Therefore: x.0.1 is sub-tuple access, not x.float_literal
1231
- if let peeked = self . peek ( at: 1 ) , !Unicode. Scalar ( peeked) . isDigit || tokenStart. previous == UInt8 ( ascii: " . " ) {
1234
+ if self . peek ( at: 1 ) == nil {
1235
+ // If there are no more digits following the '.', we don't have a float
1236
+ // literal.
1237
+ return Lexer . Result ( . integerLiteral)
1238
+ } else if let peeked = self . peek ( at: 1 ) , !Unicode. Scalar ( peeked) . isDigit {
1239
+ // ".a" is a member access and certainly not a float literal
1240
+ return Lexer . Result ( . integerLiteral)
1241
+ } else if self . previousTokenKind == . period {
1242
+ // Lex x.0.1 is sub-tuple access, not x.float_literal.
1232
1243
return Lexer . Result ( . integerLiteral)
1233
1244
}
1234
1245
} else if self . isAtEndOfFile || self . is ( notAt: " e " , " E " ) {
0 commit comments