@@ -1545,8 +1545,8 @@ extension Lexer.Cursor {
1545
1545
case success( Unicode . Scalar )
1546
1546
1547
1547
/// An escaped character, e.g. `\n` or `\u{1234}`. It has been validated that
1548
- /// this is a valid character
1549
- case validatedEscapeSequence( Character )
1548
+ /// this is a valid unicode scalar.
1549
+ case validatedEscapeSequence( Unicode . Scalar )
1550
1550
1551
1551
/// The end of a string literal has been reached.
1552
1552
case endOfString
@@ -1608,13 +1608,8 @@ extension Lexer.Cursor {
1608
1608
return . success( Unicode . Scalar ( " \\ " ) )
1609
1609
}
1610
1610
switch self . lexEscapedCharacter ( isMultilineString: stringLiteralKind == . multiLine) {
1611
- case . success( let escapedCharacterCode) :
1612
- // Check to see if the encoding is valid.
1613
- if let validatedScalar = Unicode . Scalar ( escapedCharacterCode) {
1614
- return . validatedEscapeSequence( Character ( validatedScalar) )
1615
- } else {
1616
- return . error( . invalidEscapeSequenceInStringLiteral)
1617
- }
1611
+ case . success( let codePoint) :
1612
+ return . validatedEscapeSequence( codePoint)
1618
1613
case . error( let kind) :
1619
1614
return . error( kind)
1620
1615
}
@@ -1635,7 +1630,7 @@ extension Lexer.Cursor {
1635
1630
enum EscapedCharacterLex {
1636
1631
// Successfully lexed an escape sequence that represents the Unicode character
1637
1632
// at the given codepoint
1638
- case success( UInt32 )
1633
+ case success( Unicode . Scalar )
1639
1634
case error( TokenDiagnostic . Kind )
1640
1635
}
1641
1636
@@ -1649,13 +1644,13 @@ extension Lexer.Cursor {
1649
1644
// Escape processing. We already ate the "\".
1650
1645
switch self . peek ( ) {
1651
1646
// Simple single-character escapes.
1652
- case " 0 " : _ = self . advance ( ) ; return . success( UInt32 ( UInt8 ( ascii : " \0 " ) ) )
1653
- case " n " : _ = self . advance ( ) ; return . success( UInt32 ( UInt8 ( ascii : " \n " ) ) )
1654
- case " r " : _ = self . advance ( ) ; return . success( UInt32 ( UInt8 ( ascii : " \r " ) ) )
1655
- case " t " : _ = self . advance ( ) ; return . success( UInt32 ( UInt8 ( ascii : " \t " ) ) )
1656
- case #"""# : _ = self . advance ( ) ; return . success( UInt32 ( UInt8 ( ascii : #"""# ) ) )
1657
- case " ' " : _ = self . advance ( ) ; return . success( UInt32 ( UInt8 ( ascii : " ' " ) ) )
1658
- case " \\ " : _ = self . advance ( ) ; return . success( UInt32 ( UInt8 ( ascii : " \\ " ) ) )
1647
+ case " 0 " : _ = self . advance ( ) ; return . success( " \0 " )
1648
+ case " n " : _ = self . advance ( ) ; return . success( " \n " )
1649
+ case " r " : _ = self . advance ( ) ; return . success( " \r " )
1650
+ case " t " : _ = self . advance ( ) ; return . success( " \t " )
1651
+ case #"""# : _ = self . advance ( ) ; return . success( #"""# )
1652
+ case " ' " : _ = self . advance ( ) ; return . success( " ' " )
1653
+ case " \\ " : _ = self . advance ( ) ; return . success( " \\ " )
1659
1654
1660
1655
case " u " : // e.g. \u{1234}
1661
1656
_ = self . advance ( )
@@ -1667,7 +1662,7 @@ extension Lexer.Cursor {
1667
1662
return self . lexUnicodeEscape ( )
1668
1663
case " \n " , " \r " :
1669
1664
if isMultilineString && self . maybeConsumeNewlineEscape ( ) {
1670
- return . success( UInt32 ( UInt8 ( ascii : " \n " ) ) )
1665
+ return . success( " \n " )
1671
1666
}
1672
1667
return . error( . invalidEscapeSequenceInStringLiteral)
1673
1668
case nil :
@@ -1692,24 +1687,30 @@ extension Lexer.Cursor {
1692
1687
precondition ( quoteConsumed)
1693
1688
1694
1689
let digitStart = self
1695
- var numDigits = 0
1696
- while self . advance ( if: { $0. isHexDigit } ) {
1697
- numDigits += 1
1698
- }
1690
+ self . advance ( while: { $0. isHexDigit } )
1691
+
1692
+ let digitText = SyntaxText (
1693
+ baseAddress: digitStart. pointer,
1694
+ count: digitStart. distance ( to: self )
1695
+ )
1699
1696
1700
1697
guard self . advance ( matching: " } " ) else {
1701
1698
return . error( . expectedClosingBraceInUnicodeEscape)
1702
1699
}
1703
1700
1704
- if numDigits == 0 || numDigits > 8 {
1701
+ guard 1 <= digitText . count && digitText . count <= 8 else {
1705
1702
return . error( . invalidNumberOfHexDigitsInUnicodeEscape)
1706
1703
}
1707
1704
1708
- if let codePoint = UInt32 ( String ( decoding: digitStart. input [ 0 ..< numDigits] , as: UTF8 . self) , radix: 16 ) {
1709
- return . success( codePoint)
1710
- } else {
1705
+ guard
1706
+ // FIXME: Implement 'UInt32(_: SyntaxText, radix:)'.
1707
+ let codePoint = UInt32 ( String ( syntaxText: digitText) , radix: 16 ) ,
1708
+ let scalar = Unicode . Scalar. init ( codePoint)
1709
+ else {
1711
1710
return . error( . invalidEscapeSequenceInStringLiteral)
1712
1711
}
1712
+
1713
+ return . success( scalar)
1713
1714
}
1714
1715
1715
1716
private mutating func maybeConsumeNewlineEscape( ) -> Bool {
0 commit comments