@@ -23,6 +23,8 @@ import Prelude hiding (length)
23import qualified Control.Applicative as Applicative ( Applicative(..), Alternative(..) )
23import qualified Control.Applicative as Applicative ( Applicative(..), Alternative(..) )
24import Control.Monad
24import Control.Monad
25import qualified Data.ByteString as BS
25import qualified Data.ByteString as BS
26+import qualified Data.ByteString.Builder as BS (toLazyByteString, word16HexFixed)
27+import qualified Data.ByteString.Lazy as BS (toStrict)
26import qualified Data.Char as Char
28import qualified Data.Char as Char
27import Data.Monoid ((<>))
29import Data.Monoid ((<>))
28import qualified Data.Set as Set
30import qualified Data.Set as Set
@@ -33,7 +35,7 @@ import qualified Data.Text.Encoding as Text
33import qualified Data.Text.Internal as Text
35import qualified Data.Text.Internal as Text
34import qualified Data.Text.Unsafe as Text
36import qualified Data.Text.Unsafe as Text
35import qualified Data.Text.Lazy as LT
37import qualified Data.Text.Lazy as LT
36−import qualified Data.Text.Lazy.Builder as LB
38+import qualified Data.Text.Lazy.Builder as B
37import Data.Text.Internal.Encoding.Utf16 (chr2)
39import Data.Text.Internal.Encoding.Utf16 (chr2)
38import Data.Text.Internal.Unsafe.Char (unsafeChr)
40import Data.Text.Internal.Unsafe.Char (unsafeChr)
39import GHC.Word (Word8, Word16)
41import GHC.Word (Word8, Word16)
@@ -107,19 +109,24 @@ runAt sRow sCol parser (Text.Text array offset length) =
107 Err (ParseError row col problem) ->
109 Err (ParseError row col problem) ->
109 pos = R.Position row col
111 pos = R.Position row col
110− region = R.Region pos pos
111 mkError overallRegion subRegion =
112 mkError overallRegion subRegion =
112 Left (A.A overallRegion (E.Parse subRegion problem))
113 Left (A.A overallRegion (E.Parse subRegion problem))
114 case problem of
115 case problem of
117+ mkError (R.Region pos (R.Position row endCol)) Nothing
119+ BadEscape width _ ->
120+ mkError (R.Region pos (R.Position row (col + width))) Nothing
115 BadOp _ ((_, start) : _) ->
122 BadOp _ ((_, start) : _) ->
116− mkError (R.Region start pos) (Just region)
123+ mkError (R.Region start pos) (Just (R.Region pos pos))
118 Theories ((_, start) : _) _ ->
125 Theories ((_, start) : _) _ ->
119− mkError (R.Region start pos) (Just region)
126+ mkError (R.Region start pos) (Just (R.Region pos pos))
122− mkError region Nothing
129+ mkError (R.Region pos pos) Nothing
125data Result a
132data Result a
@@ -323,7 +330,7 @@ moveCursor array offset length row col =
323 if word == 0x000A {- \n -} then
330 if word == 0x000A {- \n -} then
324 moveCursor array (offset + 1) (length - 1) (row + 1) 1
331 moveCursor array (offset + 1) (length - 1) (row + 1) 1
326− else if word < 0xD800 || word > 0xDBFF then
333+ else if word < 0xD800 || 0xDBFF < word then
327 moveCursor array (offset + 1) (length - 1) row (col + 1)
334 moveCursor array (offset + 1) (length - 1) row (col + 1)
@@ -447,7 +454,7 @@ peek array offset =
448 !word = Text.unsafeIndex array offset
455 !word = Text.unsafeIndex array offset
450− if word < 0xD800 || word > 0xDBFF then
457+ if word < 0xD800 || 0xDBFF < word then
451 Text.Iter (unsafeChr word) 1
458 Text.Iter (unsafeChr word) 1
453 Text.Iter (chr2 word (Text.unsafeIndex array (offset + 1))) 2
460 Text.Iter (chr2 word (Text.unsafeIndex array (offset + 1))) 2
@@ -459,7 +466,7 @@ peekChar array offset =
460 !word = Text.unsafeIndex array offset
467 !word = Text.unsafeIndex array offset
462− if word < 0xD800 || word > 0xDBFF then
469+ if word < 0xD800 || 0xDBFF < word then
463 unsafeChr word
470 unsafeChr word
465 chr2 word (Text.unsafeIndex array (offset + 1))
472 chr2 word (Text.unsafeIndex array (offset + 1))
@@ -661,7 +668,7 @@ eatLineCommentHelp array offset length row col =
661 if word == 0x000A {- \n -} then
668 if word == 0x000A {- \n -} then
662 eatSpaces array (offset + 1) (length - 1) (row + 1) 1
669 eatSpaces array (offset + 1) (length - 1) (row + 1) 1
664− else if word < 0xD800 || word > 0xDBFF then
671+ else if word < 0xD800 || 0xDBFF < word then
665 eatLineCommentHelp array (offset + 1) (length - 1) row (col + 1)
672 eatLineCommentHelp array (offset + 1) (length - 1) row (col + 1)
@@ -715,7 +722,7 @@ eatMultiCommentHelp array offset length row col openComments =
716 eatMultiCommentHelp array (offset + 2) (length - 2) row (col + 2) (openComments + 1)
723 eatMultiCommentHelp array (offset + 2) (length - 2) row (col + 2) (openComments + 1)
718− else if word < 0xD800 || word > 0xDBFF then
725+ else if word < 0xD800 || 0xDBFF < word then
720 eatMultiCommentHelp array (offset + 1) (length - 1) row (col + 1) openComments
727 eatMultiCommentHelp array (offset + 1) (length - 1) row (col + 1) openComments
@@ -771,7 +778,7 @@ eatDocs array offset length row col =
771 if word == 0x000A {- \n -} then
778 if word == 0x000A {- \n -} then
772 eatDocs array (offset + 1) (length - 1) (row + 1) 1
779 eatDocs array (offset + 1) (length - 1) (row + 1) 1
774− else if word < 0xD800 || word > 0xDBFF then
781+ else if word < 0xD800 || 0xDBFF < word then
775 eatDocs array (offset + 1) (length - 1) row (col + 1)
782 eatDocs array (offset + 1) (length - 1) row (col + 1)
@@ -819,7 +826,7 @@ string =
820 Right ( newOffset, newLength, newCol, builder ) ->
827 Right ( newOffset, newLength, newCol, builder ) ->
822− (LT.toStrict (LB.toLazyText builder))
829+ (LT.toStrict (B.toLazyText builder))
823 (State array newOffset newLength indent row newCol ctx)
830 (State array newOffset newLength indent row newCol ctx)
@@ -834,7 +841,7 @@ isQuote array offset =
834-- SINGLE STRINGS
841-- SINGLE STRINGS
837−singleString :: Text.Array -> Int -> Int -> Int -> Int -> Int -> LB.Builder -> Either ParseError ( Int, Int, Int, LB.Builder )
844+singleString :: Text.Array -> Int -> Int -> Int -> Int -> Int -> B.Builder -> Either ParseError ( Int, Int, Int, B.Builder )
838singleString array offset length row col initialOffset builder =
845singleString array offset length row col initialOffset builder =
839 if length == 0 then
846 if length == 0 then
840 Left (ParseError row col EndOfFile_String)
847 Left (ParseError row col EndOfFile_String)
@@ -844,75 +851,55 @@ singleString array offset length row col initialOffset builder =
844 !word = Text.unsafeIndex array offset
851 !word = Text.unsafeIndex array offset
846 if word == 0x0022 {- " -} then
853 if word == 0x0022 {- " -} then
848− finalBuilder =
855+ ( offset + 1
849− mappend builder $ LB.fromText $
856+ , length - 1
850− Text.Text array initialOffset (offset - initialOffset)
858+ , builder <> B.fromText (copyText array initialOffset (offset - initialOffset))
852− Right ( offset + 1, length - 1, col + 1, finalBuilder )
854 else if word == 0x000A {- \n -} then
861 else if word == 0x000A {- \n -} then
855 Left (ParseError row col NewLineInString)
862 Left (ParseError row col NewLineInString)
857 else if word == 0x0027 {- ' -} then
864 else if word == 0x0027 {- ' -} then
858−
865+ singleStringHelp array offset length row col initialOffset builder 1 "\\'"
860− !newOffset = offset + 1
861− chunk = Text.Text array initialOffset (offset - initialOffset)
862− newBuilder = builder <> LB.fromText chunk <> LB.fromText "\\'"
864− singleString array newOffset (length - 1) row (col + 1) newOffset newBuilder
866 else if word == 0x005C {- \ -} then
867 else if word == 0x005C {- \ -} then
867− case eatEscape array (offset + 1) (length - 1) row (col + 1) EndOfFile_String of
868+ case eatEscape array (offset + 1) (length - 1) of
868− Left err ->
869+ EscapeNormal ->
869− Left err
870+ singleString array (offset + 2) (length - 2) row (col + 2) initialOffset builder
871− Right size ->
872+ EscapeUnicode delta code ->
872− singleString array (offset + size) (length - size) row (col + size) initialOffset builder
873+ singleStringHelp array offset length row col initialOffset builder delta code
875+ EscapeProblem newOffset problem ->
876+ Left (ParseError row col (BadEscape (newOffset - offset) problem))
879+ Left (ParseError row (col + 1) EndOfFile_String)
874− else if word < 0xD800 || word > 0xDBFF then
881+ else if word < 0xD800 || 0xDBFF < word then
875 singleString array (offset + 1) (length - 1) row (col + 1) initialOffset builder
882 singleString array (offset + 1) (length - 1) row (col + 1) initialOffset builder
878 singleString array (offset + 2) (length - 2) row (col + 1) initialOffset builder
885 singleString array (offset + 2) (length - 2) row (col + 1) initialOffset builder
881−eatEscape :: Text.Array -> Int -> Int -> Int -> Int -> Problem -> Either ParseError Int
888+singleStringHelp :: Text.Array -> Int -> Int -> Int -> Int -> Int -> B.Builder -> Int -> Text.Text -> Either ParseError ( Int, Int, Int, B.Builder )
882−eatEscape array offset length row col problem =
889+singleStringHelp array offset length row col initialOffset builder delta escape =
883− if length == 0 then
890+ let
884− Left (ParseError row col problem)
891+ chunk = copyText array initialOffset (offset - initialOffset)
885−
892+ newBuilder = builder <> B.fromText chunk <> B.fromText escape
886− else
893+ !newOffset = offset + delta
887− case Text.unsafeIndex array offset of
894+ in
888− 0x0061 {- a -} -> Right 2
895+ singleString array newOffset (length - delta) row (col + delta) newOffset newBuilder
889− 0x0062 {- b -} -> Right 2
890− 0x0066 {- f -} -> Right 2
891− 0x006E {- n -} -> Right 2
892− 0x0072 {- r -} -> Right 2
893− 0x0074 {- t -} -> Right 2
894− 0x0076 {- v -} -> Right 2
895− 0x0022 {- " -} -> Right 2
896− 0x005C {- \ -} -> Right 2
897− 0x0027 {- ' -} -> Right 2
898− 0x0075 {- u -} | length >= 5 && fourHex array offset -> Right 6
900− Left (ParseError row col BadEscape)
903−fourHex :: Text.Array -> Int -> Bool
904−fourHex array offset =
905− isHex (Text.unsafeIndex array (offset + 1))
906− && isHex (Text.unsafeIndex array (offset + 2))
907− && isHex (Text.unsafeIndex array (offset + 3))
908− && isHex (Text.unsafeIndex array (offset + 4))
912-- MULTI STRINGS
899-- MULTI STRINGS
915−multiString :: Text.Array -> Int -> Int -> Int -> Int -> Int -> LB.Builder -> Either ParseError ( Int, Int, Int, LB.Builder )
902+multiString :: Text.Array -> Int -> Int -> Int -> Int -> Int -> B.Builder -> Either ParseError ( Int, Int, Int, B.Builder )
916multiString array offset length row col initialOffset builder =
903multiString array offset length row col initialOffset builder =
917 if length < 3 then
904 if length < 3 then
918 Left (ParseError row col EndOfFile_MultiString)
905 Left (ParseError row col EndOfFile_MultiString)
@@ -922,48 +909,51 @@ multiString array offset length row col initialOffset builder =
922 !word = Text.unsafeIndex array offset
909 !word = Text.unsafeIndex array offset
924 if word == 0x0022 {- " -} && isQuote array (offset + 1) && isQuote array (offset + 2) then
911 if word == 0x0022 {- " -} && isQuote array (offset + 1) && isQuote array (offset + 2) then
926− let
913+ ( offset + 3
927− finalBuilder =
914+ , length - 3
928− mappend builder $ LB.fromText $
915+ , col + 3
929− Text.Text array initialOffset (offset - initialOffset)
916+ , builder <> B.fromText (copyText array initialOffset (offset - initialOffset))
931− Right ( offset + 3, length - 3, col + 3, finalBuilder )
933 else if word == 0x0027 {- ' -} then
919 else if word == 0x0027 {- ' -} then
934−
920+ multiStringHelp array offset length row col initialOffset builder 1 "\\'"
936− !newOffset = offset + 1
937− chunk = Text.Text array initialOffset (offset - initialOffset)
938− newBuilder = builder <> LB.fromText chunk <> LB.fromText "\\'"
940− multiString array newOffset (length - 1) row (col + 1) newOffset newBuilder
942 else if word == 0x000A {- \n -} then
922 else if word == 0x000A {- \n -} then
943−
923+ multiStringHelp array offset length row col initialOffset builder 1 "\\n"
945− !newOffset = offset + 1
946− chunk = Text.Text array initialOffset (offset - initialOffset)
947− newBuilder = builder <> LB.fromText chunk <> LB.fromText "\\n"
949− multiString array newOffset (length - 1) (row + 1) 1 newOffset newBuilder
951 else if word == 0x005C {- \ -} then
925 else if word == 0x005C {- \ -} then
953− case eatEscape array (offset + 1) (length - 1) row (col + 1) EndOfFile_MultiString of
927+ case eatEscape array (offset + 1) (length - 1) of
954− Left err ->
928+ EscapeNormal ->
955− Left err
929+ multiString array (offset + 2) (length - 2) row (col + 2) initialOffset builder
931+ EscapeUnicode delta code ->
932+ multiStringHelp array offset length row col initialOffset builder delta code
957− Right size ->
934+ EscapeProblem newOffset problem ->
958− multiString array (offset + size) (length - size) row (col + size) initialOffset builder
935+ Left (ParseError row col (BadEscape (newOffset - offset) problem))
938+ Left (ParseError row (col + 1) EndOfFile_MultiString)
960− else if word < 0xD800 || word > 0xDBFF then
940+ else if word < 0xD800 || 0xDBFF < word then
961 multiString array (offset + 1) (length - 1) row (col + 1) initialOffset builder
941 multiString array (offset + 1) (length - 1) row (col + 1) initialOffset builder
964 multiString array (offset + 2) (length - 2) row (col + 1) initialOffset builder
944 multiString array (offset + 2) (length - 2) row (col + 1) initialOffset builder
947+multiStringHelp :: Text.Array -> Int -> Int -> Int -> Int -> Int -> B.Builder -> Int -> Text.Text -> Either ParseError ( Int, Int, Int, B.Builder )
948+multiStringHelp array offset length row col initialOffset builder delta escape =
950+ chunk = copyText array initialOffset (offset - initialOffset)
951+ newBuilder = builder <> B.fromText chunk <> B.fromText escape
952+ !newOffset = offset + delta
954+ multiString array newOffset (length - delta) row (col + delta) newOffset newBuilder
968-- CHARACTER
958-- CHARACTER
@@ -978,49 +968,136 @@ character =
978 if Text.unsafeIndex array offset /= 0x0027 {- ' -} then
968 if Text.unsafeIndex array offset /= 0x0027 {- ' -} then
979 eerr noError
969 eerr noError
981− else if length < 3 then
982− cerr (ParseError row col BadChar)
985− case characterHelp array (offset + 1) (length - 1) row (col + 1) of
972+ case chompChar array (offset + 1) (length - 1) row (col + 1) 0 "" of
986 Left err ->
973 Left err ->
989− Right (endCol, size) ->
976+ Right ( newOffset, newLength, newCol, numChars, mostRecentChar ) ->
990− let
977+ if numChars /= 1 then
991− !newOffset = offset + size + 1
992− !newLength = length - size - 1
994− if newLength == 0 || Text.unsafeIndex array newOffset /= 0x0027 {- ' -} then
995− cerr (ParseError row col BadChar)
978+ cerr (ParseError row col (BadChar newCol))
981+ (State array newOffset newLength indent row newCol ctx)
997− else
984+chompChar :: Text.Array -> Int -> Int -> Int -> Int -> Int -> Text.Text -> Either ParseError ( Int, Int, Int, Int, Text.Text )
998− cok
985+chompChar array offset length row col numChars mostRecentChar =
999− (copyText array (offset + 1) size)
986+ if length == 0 then
1000− (State array (newOffset + 1) (newLength - 1) indent row endCol ctx)
987+ Left (ParseError row col EndOfFile_Char)
991+ !word = Text.unsafeIndex array offset
993+ if word == 0x0027 {- ' -} then
1004−characterHelp :: Text.Array -> Int -> Int -> Int -> Int -> Either ParseError ( Int, Int )
1005−characterHelp array offset length row col =
1007− !word = Text.unsafeIndex array offset
1009− if word == 0x0027 {- ' -} || word == 0x000A {- \n -} then
1002+ else if word == 0x000A {- \n -} then
1010− Left (ParseError row col BadChar)
1003+ Left (ParseError row col NewLineInChar)
1005+ else if word == 0x0022 {- " -} then
1006+ chompChar array (offset + 1) (length - 1) row (col + 1) (numChars + 1) "\\\""
1012− else if word == 0x005C {- \ -} then
1008+ else if word == 0x005C {- \ -} then
1013− do n <- eatEscape array (offset + 1) (length - 1) row (col + 1) BadChar
1009+ case eatEscape array (offset + 1) (length - 1) of
1014− return (col + n + 2, n)
1010+ EscapeNormal ->
1011+ chompChar array (offset + 2) (length - 2) row (col + 2) (numChars + 1) (copyText array offset 2)
1013+ EscapeUnicode delta code ->
1014+ chompChar array (offset + delta) (length - delta) row (col + delta) (numChars + 1) code
1016+ EscapeProblem newOffset problem ->
1017+ Left (ParseError row col (BadEscape (newOffset - offset) problem))
1020+ Left (ParseError row col EndOfFile_Char)
1022+ else if word < 0xD800 || 0xDBFF < word then
1023+ chompChar array (offset + 1) (length - 1) row (col + 1) (numChars + 1) (copyText array offset 1)
1026+ chompChar array (offset + 2) (length - 2) row (col + 1) (numChars + 1) (copyText array offset 2)
1016− else if word < 0xD800 || word > 0xDBFF then
1019− else if length > 2 then
1029+
1020− Right (col + 3, 2)
1030+-- ESCAPE CHARACTERS
1035+ | EscapeUnicode !Int Text.Text
1036+ | EscapeProblem !Int E.EscapeProblem
1040+eatEscape :: Text.Array -> Int -> Int -> Escape
1041+eatEscape array offset length =
1042+ if length == 0 then
1046+ case Text.unsafeIndex array offset of
1047+ 0x006E {- n -} -> EscapeNormal
1048+ 0x0074 {- t -} -> EscapeNormal
1049+ 0x0022 {- " -} -> EscapeNormal
1050+ 0x0027 {- ' -} -> EscapeNormal
1051+ 0x005C {- \ -} -> EscapeNormal
1052+ 0x0075 {- u -} -> eatUnicode array (offset + 1) (length - 1)
1053+ _ -> EscapeProblem offset E.UnknownEscape
1056+eatUnicode :: Text.Array -> Int -> Int -> Escape
1057+eatUnicode array offset length =
1058+ if length == 0 || Text.unsafeIndex array offset /= 0x007B {- { -} then
1059+ EscapeProblem offset E.UnicodeSyntax
1065+ (# newOffset, newLength, code #) =
1066+ chompHex array digitOffset (length - 1)
1069+ newOffset - digitOffset
1071+ if newLength == 0 || Text.unsafeIndex array newOffset /= 0x007D {- } -} then
1072+ EscapeProblem newOffset E.UnicodeSyntax
1074+ else if code < 0 || 0x10FFFF < code then
1075+ EscapeProblem (newOffset + 1) E.UnicodeRange
1077+ else if numDigits < 4 || 6 < numDigits then
1078+ EscapeProblem (newOffset + 1) $
1079+ E.UnicodeLength numDigits (copyText array digitOffset numDigits)
1023− Left (ParseError row col BadChar)
1082+ EscapeUnicode (numDigits + 4) (codePointToBuilder code)
1085+{-# INLINE codePointToBuilder #-}
1086+codePointToBuilder :: Int -> Text.Text
1087+codePointToBuilder code =
1088+ if code < 0xFFFF then
1089+ "\\u" <> toHex code
1092+ "\\u" <> toHex ((code `div` 0x400) + 0xD800)
1094+ "\\u" <> toHex ((code `mod` 0x400) + 0xDC00)
1097+toHex :: Int -> Text.Text
1099+ Text.decodeUtf8 $ BS.toStrict $ BS.toLazyByteString $
1100+ BS.word16HexFixed (fromIntegral word16)
@@ -1198,7 +1275,7 @@ chompZero array startOffset offset length =
1198 !word = Text.unsafeIndex array offset
1275 !word = Text.unsafeIndex array offset
1200 if word == 0x0078 {- x -} then
1277 if word == 0x0078 {- x -} then
1201− chompHex array startOffset (offset + 1) (length - 1)
1278+ chompHexNumber array (offset + 1) (length - 1)
1203 else if word == 0x002E {- . -} then
1280 else if word == 0x002E {- . -} then
1204 chompFraction array startOffset (offset + 1) (length - 1)
1281 chompFraction array startOffset (offset + 1) (length - 1)
@@ -1210,28 +1287,16 @@ chompZero array startOffset offset length =
1210 Right ( offset, length, L.IntNum 0 )
1287 Right ( offset, length, L.IntNum 0 )
1213−chompHex :: Text.Array -> Int -> Int -> Int -> Either (Int, Problem) (Int, Int, L.Literal)
1290+chompHexNumber :: Text.Array -> Int -> Int -> Either (Int, Problem) (Int, Int, L.Literal)
1214−chompHex array startOffset offset length =
1291+chompHexNumber array offset length =
1215− if length == 0 then
1292+ let
1216− Left (offset, BadNumberHex)
1293+ (# newOffset, newLength, hexNumber #) =
1218− else if isHex (Text.unsafeIndex array offset) then
1219− chompHexHelp array startOffset (offset + 1) (length - 1)
1294+ chompHex array offset length
1222− Left (offset, BadNumberHex)
1225−chompHexHelp :: Text.Array -> Int -> Int -> Int -> Either (Int, Problem) (Int, Int, L.Literal)
1226−chompHexHelp array startOffset offset length =
1227− if length == 0 then
1296+ if hexNumber == -1 then
1228− Right ( offset, length, readInt array startOffset offset )
1297+ Left ( newOffset, BadNumberHex )
1230− else if isHex (Text.unsafeIndex array offset) then
1231− chompHexHelp array startOffset (offset + 1) (length - 1)
1234− Right ( offset, length, readInt array startOffset offset )
1299+ Right ( newOffset, newLength, L.IntNum hexNumber )
@@ -1244,18 +1309,6 @@ isDigit word =
1244 word <= 0x0039 {- 9 -} && word >= 0x0030 {- 0 -}
1309 word <= 0x0039 {- 9 -} && word >= 0x0030 {- 0 -}
1247−{-# INLINE isHex #-}
1248−isHex :: Word16 -> Bool
1250− word <= 0x0066 {- f -} && (word >= 0x0061 {- a -} || isDigit word || isCapHex word)
1253−{-# INLINE isCapHex #-}
1254−isCapHex :: Word16 -> Bool
1256− 0x0041 {- A -} <= word && word <= 0x0046 {- F -}
1259{-# INLINE readInt #-}
1312{-# INLINE readInt #-}
1260readInt :: Text.Array -> Int -> Int -> L.Literal
1313readInt :: Text.Array -> Int -> Int -> L.Literal
1261readInt array startOffset endOffset =
1314readInt array startOffset endOffset =
@@ -1271,6 +1324,50 @@ readFloat array startOffset endOffset =
1330+-- Return -1 if it has NO digits
1331+-- Return -2 if it has BAD digits
1333+{-# INLINE chompHex #-}
1334+chompHex :: Text.Array -> Int -> Int -> (# Int, Int, Int #)
1335+chompHex array offset length =
1336+ chompHexHelp array offset length (-1) 0
1339+chompHexHelp :: Text.Array -> Int -> Int -> Int -> Int -> (# Int, Int, Int #)
1340+chompHexHelp array offset length finalNumber hexNumber =
1341+ if length == 0 then
1342+ (# offset, length, finalNumber #)
1346+ stepHex (Text.unsafeIndex array offset) hexNumber
1348+ if newNumber < 0 then
1349+ (# offset, length, if newNumber == -1 then finalNumber else -2 #)
1351+ chompHexHelp array (offset + 1) (length - 1) newNumber newNumber
1354+{-# INLINE stepHex #-}
1355+stepHex :: Word16 -> Int -> Int
1356+stepHex word hexNumber =
1357+ if word <= 0x0039 {- 9 -} && word >= 0x0030 {- 0 -} then
1358+ 16 * hexNumber + fromIntegral (word - 0x0030 {- 0 -})
1360+ else if word <= 0x0066 {- f -} && word >= 0x0061 {- a -} then
1361+ 16 * hexNumber + 10 + fromIntegral (word - 0x0061 {- a -})
1363+ else if word <= 0x0046 {- F -} && word >= 0x0041 {- A -} then
1364+ 16 * hexNumber + 10 + fromIntegral (word - 0x0041 {- A -})
1274-- SHADER
1371-- SHADER
@@ -1306,7 +1403,7 @@ eatShader array offset length row col =
1306 else if word == 0x000A {- \n -} then
1403 else if word == 0x000A {- \n -} then
1307 eatShader array (offset + 1) (length - 1) (row + 1) 1
1404 eatShader array (offset + 1) (length - 1) (row + 1) 1
1309− else if word < 0xD800 || word > 0xDBFF then
1406+ else if word < 0xD800 || 0xDBFF < word then
1310 eatShader array (offset + 1) (length - 1) row (col + 1)
1407 eatShader array (offset + 1) (length - 1) row (col + 1)
@@ -1333,7 +1430,7 @@ kernelChunk =
1333 chompChunk array offset length row col
1430 chompChunk array offset length row col
1335 !javascript =
1432 !javascript =
1336− Text.encodeUtf8 (Text.Text array offset (jsOffset - offset))
1433+ Text.encodeUtf8 (copyText array offset (jsOffset - offset))
1338 !newState =
1435 !newState =
1339 State array newOffset newLength indent newRow newCol ctx
1436 State array newOffset newLength indent newRow newCol ctx
@@ -1356,7 +1453,7 @@ chompChunk array offset length row col =
1356 else if word == 0x000A {- \n -} then
1453 else if word == 0x000A {- \n -} then
1357 chompChunk array (offset + 1) (length - 1) (row + 1) 1
1454 chompChunk array (offset + 1) (length - 1) (row + 1) 1
1359− else if word < 0xD800 || word > 0xDBFF then
1456+ else if word < 0xD800 || 0xDBFF < word then
1360 chompChunk array (offset + 1) (length - 1) row (col + 1)
1457 chompChunk array (offset + 1) (length - 1) row (col + 1)
@@ -1374,10 +1471,10 @@ chompChunkTag array jsOffset offset length row col =
1375 !chunkTag =
1472 !chunkTag =
1376 if word == 0x0024 {- $ -} then
1473 if word == 0x0024 {- $ -} then
1377− KernelElmField (Text.Text array (offset + 1) (newOffset - offset - 1))
1474+ KernelElmField (copyText array (offset + 1) (newOffset - offset - 1))
1380− let !chunk = Text.Text array offset (newOffset - offset) in
1477+ let !chunk = copyText array offset (newOffset - offset) in
1381 if isDigit word then
1478 if isDigit word then
1382 KernelEnum (fromIntegral (word - 0x0030 {- 0 -})) chunk
1479 KernelEnum (fromIntegral (word - 0x0030 {- 0 -})) chunk