@@ -20,6 +20,7 @@ import Prelude hiding (length)
2020import qualified Control.Applicative as Applicative ( Applicative(..), Alternative(..) )
2121import Control.Monad
2222import qualified Data.Char as Char
23+import Data.Monoid ((<>))
2324import qualified Data.Set as Set
2425import Data.Text (Text)
2526import qualified Data.Text as Text
@@ -688,8 +689,10 @@ string =
688689 Left err ->
689690 cerr err
690691
691− Right ( newOffset, newLength, newCol, str ) ->
692− cok str (State array newOffset newLength indent row newCol)
692+ Right ( newOffset, newLength, newCol, builder ) ->
693+ cok
694+ (LT.toStrict (LB.toLazyText builder))
695+ (State array newOffset newLength indent row newCol)
693696
694697
695698{-# INLINE isQuote #-}
@@ -702,7 +705,7 @@ isQuote array offset =
702705-- SINGLE STRINGS
703706
704707
705−singleString :: Text.Array -> Int -> Int -> Int -> Int -> Int -> LB.Builder -> Either ParseError ( Int, Int, Int, Text.Text )
708+singleString :: Text.Array -> Int -> Int -> Int -> Int -> Int -> LB.Builder -> Either ParseError ( Int, Int, Int, LB.Builder )
706709singleString array offset length row col initialOffset builder =
707710 if length == 0 then
708711 Left (ParseError row col EndOfFile_String)
@@ -716,15 +719,21 @@ singleString array offset length row col initialOffset builder =
716719 finalBuilder =
717720 mappend builder $ LB.fromText $
718721 Text.Text array initialOffset (offset - initialOffset)
719−
720− str =
721− LT.toStrict (LB.toLazyTextWith (offset - initialOffset) finalBuilder)
722722 in
723− Right ( offset + 1, length - 1, col + 1, str )
723+ Right ( offset + 1, length - 1, col + 1, finalBuilder )
724724
725725 else if word == 0x000A {- \n -} then
726726 Left (ParseError row col NewLineInString)
727727
728+ else if word == 0x0027 {- ' -} then
729+
730+ let
731+ !newOffset = offset + 1
732+ chunk = Text.Text array initialOffset (offset - initialOffset)
733+ newBuilder = builder <> LB.fromText chunk <> LB.fromText "\\'"
734+ in
735+ singleString array newOffset (length - 1) row (col + 1) newOffset newBuilder
736+
728737 else if word == 0x005C {- \ -} then
729738 case eatEscape array (offset + 1) (length - 1) row (col + 1) EndOfFile_String of
730739 Left err ->
@@ -734,7 +743,7 @@ singleString array offset length row col initialOffset builder =
734743 let
735744 !newOffset = offset + size
736745 chunk = Text.Text array initialOffset (offset - initialOffset)
737− newBuilder = mappend builder (mappend (LB.fromText chunk) (LB.singleton char))
746+ newBuilder = builder <> LB.fromText chunk <> LB.singleton char
738747 in
739748 singleString array newOffset (length - size) row (col + size) newOffset newBuilder
740749
@@ -803,9 +812,9 @@ eatHex array offset length n =
803812-- MULTI STRINGS
804813
805814
806−multiString :: Text.Array -> Int -> Int -> Int -> Int -> Int -> LB.Builder -> Either ParseError ( Int, Int, Int, Text.Text )
815+multiString :: Text.Array -> Int -> Int -> Int -> Int -> Int -> LB.Builder -> Either ParseError ( Int, Int, Int, LB.Builder )
807816multiString array offset length row col initialOffset builder =
808− if length == 0 then
817+ if length < 3 then
809818 Left (ParseError row col EndOfFile_MultiString)
810819
811820 else
@@ -813,17 +822,34 @@ multiString array offset length row col initialOffset builder =
813822 !word = Text.unsafeIndex array offset
814823 in
815824 if word == 0x0022 {- " -} && isQuote array (offset + 1) && isQuote array (offset + 2) then
825+
826+ let
827+ finalBuilder =
828+ mappend builder $ LB.fromText $
829+ Text.Text array initialOffset (offset - initialOffset)
830+ in
831+ Right ( offset + 3, length - 3, col + 3, finalBuilder )
832+
833+ else if word == 0x0027 {- ' -} then
834+
816835 let
817− finalBuilder =
818− mappend builder $ LB.fromText $
819− Text.Text array initialOffset (offset - initialOffset)
836+ !newOffset = offset + 1
837+ chunk = Text.Text array initialOffset (offset - initialOffset)
838+ newBuilder = builder <> LB.fromText chunk <> LB.fromText "\\'"
839+ in
840+ multiString array newOffset (length - 1) row (col + 1) newOffset newBuilder
841+
842+ else if word == 0x000A {- \n -} then
820843
821− str =
822− LT.toStrict (LB.toLazyTextWith (offset - initialOffset) finalBuilder)
844+ let
845+ !newOffset = offset + 1
846+ chunk = Text.Text array initialOffset (offset - initialOffset)
847+ newBuilder = builder <> LB.fromText chunk <> LB.fromText "\\n"
823848 in
824− Right ( offset + 3, length - 3, col + 3, str )
849+ multiString array newOffset (length - 1) (row + 1) 1 newOffset newBuilder
825850
826851 else if word == 0x005C {- \ -} then
852+
827853 case eatEscape array (offset + 1) (length - 1) row (col + 1) EndOfFile_MultiString of
828854 Left err ->
829855 Left err
@@ -832,7 +858,7 @@ multiString array offset length row col initialOffset builder =
832858 let
833859 !newOffset = offset + size
834860 chunk = Text.Text array initialOffset (offset - initialOffset)
835− newBuilder = mappend builder (mappend (LB.fromText chunk) (LB.singleton char))
861+ newBuilder = builder <> LB.fromText chunk <> LB.singleton char
836862 in
837863 multiString array newOffset (length - size) row (col + size) newOffset newBuilder
838864