Wolfgang Jeltsch pushed to branch wip/jeltsch/text-read-implementation-into-base at Glasgow Haskell Compiler / GHC

Commits:

10 changed files:

Changes:

  • libraries/base/src/Data/Functor/Classes.hs
    ... ... @@ -85,7 +85,7 @@ import GHC.Internal.Read (expectP, list, paren, readField)
    85 85
     import GHC.Internal.Show (appPrec)
    
    86 86
     
    
    87 87
     import GHC.Internal.Text.ParserCombinators.ReadPrec (ReadPrec, readPrec_to_S, readS_to_Prec, pfail)
    
    88
    -import GHC.Internal.Text.Read (Read(..), parens, prec, step, reset)
    
    88
    +import Text.Read (Read(..), parens, prec, step, reset)
    
    89 89
     import GHC.Internal.Text.Read.Lex (Lexeme(..))
    
    90 90
     import GHC.Internal.Text.Show (showListWith)
    
    91 91
     import Prelude
    

  • libraries/base/src/Data/Functor/Compose.hs
    ... ... @@ -35,7 +35,7 @@ import GHC.Internal.Data.Foldable (Foldable(..))
    35 35
     import GHC.Internal.Data.Monoid (Sum(..), All(..), Any(..), Product(..))
    
    36 36
     import GHC.Internal.Data.Type.Equality (TestEquality(..), (:~:)(..))
    
    37 37
     import GHC.Generics (Generic, Generic1)
    
    38
    -import GHC.Internal.Text.Read (Read(..), ReadPrec, readListDefault, readListPrecDefault)
    
    38
    +import Text.Read (Read(..), ReadPrec, readListDefault, readListPrecDefault)
    
    39 39
     import Prelude
    
    40 40
     
    
    41 41
     infixr 9 `Compose`
    

  • libraries/base/src/Prelude.hs
    ... ... @@ -179,7 +179,7 @@ import GHC.Internal.Data.Tuple
    179 179
     import GHC.Internal.Base hiding ( foldr, mapM, sequence )
    
    180 180
     import GHC.Internal.Classes
    
    181 181
     import GHC.Internal.Err
    
    182
    -import GHC.Internal.Text.Read
    
    182
    +import Text.Read
    
    183 183
     import GHC.Internal.Enum
    
    184 184
     import GHC.Internal.Num
    
    185 185
     import GHC.Internal.Prim (seq)
    

  • libraries/base/src/Text/Read.hs
    ... ... @@ -39,5 +39,84 @@ module Text.Read
    39 39
          readMaybe
    
    40 40
          ) where
    
    41 41
     
    
    42
    -import GHC.Internal.Text.Read
    
    42
    +import GHC.Err (errorWithoutStackTrace)
    
    43
    +import GHC.Read
    
    44
    +       (
    
    45
    +           ReadS,
    
    46
    +           Read (readsPrec, readList, readPrec, readListPrec),
    
    47
    +           lex,
    
    48
    +           readParen,
    
    49
    +           readListDefault,
    
    50
    +           lexP,
    
    51
    +           parens,
    
    52
    +           readListPrecDefault
    
    53
    +       )
    
    54
    +import Control.Monad (return)
    
    55
    +import Data.Function (id)
    
    56
    +import Data.Maybe (Maybe (Nothing, Just))
    
    57
    +import Data.Either (Either (Left, Right), either)
    
    58
    +import Data.String (String)
    
    59
    +import Text.Read.Lex (Lexeme (Char, String, Punc, Ident, Symbol, Number, EOF))
    
    60
    +import Text.ParserCombinators.ReadP (skipSpaces)
    
    43 61
     import Text.ParserCombinators.ReadPrec
    
    62
    +
    
    63
    +-- $setup
    
    64
    +-- >>> import Prelude
    
    65
    +
    
    66
    +------------------------------------------------------------------------
    
    67
    +-- utility functions
    
    68
    +
    
    69
    +-- | equivalent to 'readsPrec' with a precedence of 0.
    
    70
    +reads :: Read a => ReadS a
    
    71
    +reads = readsPrec minPrec
    
    72
    +
    
    73
    +-- | Parse a string using the 'Read' instance.
    
    74
    +-- Succeeds if there is exactly one valid result.
    
    75
    +-- A 'Left' value indicates a parse error.
    
    76
    +--
    
    77
    +-- >>> readEither "123" :: Either String Int
    
    78
    +-- Right 123
    
    79
    +--
    
    80
    +-- >>> readEither "hello" :: Either String Int
    
    81
    +-- Left "Prelude.read: no parse"
    
    82
    +--
    
    83
    +-- @since base-4.6.0.0
    
    84
    +readEither :: Read a => String -> Either String a
    
    85
    +readEither s =
    
    86
    +  case [ x | (x,"") <- readPrec_to_S read' minPrec s ] of
    
    87
    +    [x] -> Right x
    
    88
    +    []  -> Left "Prelude.read: no parse"
    
    89
    +    _   -> Left "Prelude.read: ambiguous parse"
    
    90
    + where
    
    91
    +  read' =
    
    92
    +    do x <- readPrec
    
    93
    +       lift skipSpaces
    
    94
    +       return x
    
    95
    +
    
    96
    +-- | Parse a string using the 'Read' instance.
    
    97
    +-- Succeeds if there is exactly one valid result.
    
    98
    +--
    
    99
    +-- >>> readMaybe "123" :: Maybe Int
    
    100
    +-- Just 123
    
    101
    +--
    
    102
    +-- >>> readMaybe "hello" :: Maybe Int
    
    103
    +-- Nothing
    
    104
    +--
    
    105
    +-- @since base-4.6.0.0
    
    106
    +readMaybe :: Read a => String -> Maybe a
    
    107
    +readMaybe s = case readEither s of
    
    108
    +                Left _  -> Nothing
    
    109
    +                Right a -> Just a
    
    110
    +
    
    111
    +-- | The 'read' function reads input from a string, which must be
    
    112
    +-- completely consumed by the input process. 'read' fails with an 'error' if the
    
    113
    +-- parse is unsuccessful, and it is therefore discouraged from being used in
    
    114
    +-- real applications. Use 'readMaybe' or 'readEither' for safe alternatives.
    
    115
    +--
    
    116
    +-- >>> read "123" :: Int
    
    117
    +-- 123
    
    118
    +--
    
    119
    +-- >>> read "hello" :: Int
    
    120
    +-- *** Exception: Prelude.read: no parse
    
    121
    +read :: Read a => String -> a
    
    122
    +read s = either errorWithoutStackTrace id (readEither s)

  • libraries/ghc-internal/ghc-internal.cabal.in
    ... ... @@ -329,7 +329,6 @@ Library
    329 329
             GHC.Internal.System.Posix.Types
    
    330 330
             GHC.Internal.Text.ParserCombinators.ReadP
    
    331 331
             GHC.Internal.Text.ParserCombinators.ReadPrec
    
    332
    -        GHC.Internal.Text.Read
    
    333 332
             GHC.Internal.Text.Read.Lex
    
    334 333
             GHC.Internal.Text.Show
    
    335 334
             GHC.Internal.Type.Reflection
    

  • libraries/ghc-internal/src/GHC/Internal/IO/Encoding.hs
    ... ... @@ -46,7 +46,7 @@ import GHC.Internal.IO.Encoding.Types
    46 46
     import qualified GHC.Internal.IO.Encoding.Iconv as Iconv
    
    47 47
     #else
    
    48 48
     import qualified GHC.Internal.IO.Encoding.CodePage as CodePage
    
    49
    -import GHC.Internal.Text.Read (reads)
    
    49
    +import GHC.Internal.Text.Read (readsPrec)
    
    50 50
     #endif
    
    51 51
     import qualified GHC.Internal.IO.Encoding.Latin1 as Latin1
    
    52 52
     import qualified GHC.Internal.IO.Encoding.UTF8   as UTF8
    
    ... ... @@ -319,7 +319,8 @@ mkTextEncoding' cfm enc =
    319 319
         _ | isAscii -> return (Latin1.mkAscii cfm)
    
    320 320
         _ | isLatin1 -> return (Latin1.mkLatin1_checked cfm)
    
    321 321
     #if defined(mingw32_HOST_OS)
    
    322
    -    'C':'P':n | [(cp,"")] <- reads n -> return $ CodePage.mkCodePageEncoding cfm cp
    
    322
    +    'C':'P':n | [(cp,"")] <- readsPrec 0 n -> return $ CodePage.mkCodePageEncoding cfm cp
    
    323
    +        -- 'readsPrec 0' is the same as 'reads', but 'reads' is only defined in @base@.
    
    323 324
         _ -> unknownEncodingErr (enc ++ codingFailureModeSuffix cfm)
    
    324 325
     #else
    
    325 326
         -- Otherwise, handle other encoding needs via iconv.
    

  • libraries/ghc-internal/src/GHC/Internal/Text/Read.hs deleted
    1
    -{-# LANGUAGE Trustworthy #-}
    
    2
    -{-# LANGUAGE NoImplicitPrelude #-}
    
    3
    -
    
    4
    ------------------------------------------------------------------------------
    
    5
    --- |
    
    6
    --- Module      :  GHC.Internal.Text.Read
    
    7
    --- Copyright   :  (c) The University of Glasgow 2001
    
    8
    --- License     :  BSD-style (see the file libraries/base/LICENSE)
    
    9
    ---
    
    10
    --- Maintainer  :  libraries@haskell.org
    
    11
    --- Stability   :  provisional
    
    12
    --- Portability :  non-portable (uses Text.ParserCombinators.ReadP)
    
    13
    ---
    
    14
    --- Converting strings to values.
    
    15
    ---
    
    16
    --- The "Text.Read" library is the canonical library to import for
    
    17
    --- 'Read'-class facilities.  For GHC only, it offers an extended and much
    
    18
    --- improved 'Read' class, which constitutes a proposed alternative to the
    
    19
    --- Haskell 2010 'Read'.  In particular, writing parsers is easier, and
    
    20
    --- the parsers are much more efficient.
    
    21
    ---
    
    22
    ------------------------------------------------------------------------------
    
    23
    -
    
    24
    -module GHC.Internal.Text.Read (
    
    25
    -   -- * The 'Read' class
    
    26
    -   Read(..),
    
    27
    -   ReadS,
    
    28
    -
    
    29
    -   -- * Haskell 2010 functions
    
    30
    -   reads,
    
    31
    -   read,
    
    32
    -   readParen,
    
    33
    -   lex,
    
    34
    -
    
    35
    -   -- * New parsing functions
    
    36
    -   module GHC.Internal.Text.ParserCombinators.ReadPrec,
    
    37
    -   L.Lexeme(..),
    
    38
    -   lexP,
    
    39
    -   parens,
    
    40
    -   readListDefault,
    
    41
    -   readListPrecDefault,
    
    42
    -   readEither,
    
    43
    -   readMaybe
    
    44
    -
    
    45
    - ) where
    
    46
    -
    
    47
    -import GHC.Internal.Base (String, id, return)
    
    48
    -import GHC.Internal.Err (errorWithoutStackTrace)
    
    49
    -import GHC.Internal.Maybe (Maybe(..))
    
    50
    -import GHC.Internal.Read
    
    51
    -import GHC.Internal.Data.Either
    
    52
    -import GHC.Internal.Text.ParserCombinators.ReadP as P
    
    53
    -import GHC.Internal.Text.ParserCombinators.ReadPrec
    
    54
    -import qualified GHC.Internal.Text.Read.Lex as L
    
    55
    -
    
    56
    --- $setup
    
    57
    --- >>> import Prelude
    
    58
    -
    
    59
    -------------------------------------------------------------------------
    
    60
    --- utility functions
    
    61
    -
    
    62
    --- | equivalent to 'readsPrec' with a precedence of 0.
    
    63
    -reads :: Read a => ReadS a
    
    64
    -reads = readsPrec minPrec
    
    65
    -
    
    66
    --- | Parse a string using the 'Read' instance.
    
    67
    --- Succeeds if there is exactly one valid result.
    
    68
    --- A 'Left' value indicates a parse error.
    
    69
    ---
    
    70
    --- >>> readEither "123" :: Either String Int
    
    71
    --- Right 123
    
    72
    ---
    
    73
    --- >>> readEither "hello" :: Either String Int
    
    74
    --- Left "Prelude.read: no parse"
    
    75
    ---
    
    76
    --- @since base-4.6.0.0
    
    77
    -readEither :: Read a => String -> Either String a
    
    78
    -readEither s =
    
    79
    -  case [ x | (x,"") <- readPrec_to_S read' minPrec s ] of
    
    80
    -    [x] -> Right x
    
    81
    -    []  -> Left "Prelude.read: no parse"
    
    82
    -    _   -> Left "Prelude.read: ambiguous parse"
    
    83
    - where
    
    84
    -  read' =
    
    85
    -    do x <- readPrec
    
    86
    -       lift P.skipSpaces
    
    87
    -       return x
    
    88
    -
    
    89
    --- | Parse a string using the 'Read' instance.
    
    90
    --- Succeeds if there is exactly one valid result.
    
    91
    ---
    
    92
    --- >>> readMaybe "123" :: Maybe Int
    
    93
    --- Just 123
    
    94
    ---
    
    95
    --- >>> readMaybe "hello" :: Maybe Int
    
    96
    --- Nothing
    
    97
    ---
    
    98
    --- @since base-4.6.0.0
    
    99
    -readMaybe :: Read a => String -> Maybe a
    
    100
    -readMaybe s = case readEither s of
    
    101
    -                Left _  -> Nothing
    
    102
    -                Right a -> Just a
    
    103
    -
    
    104
    --- | The 'read' function reads input from a string, which must be
    
    105
    --- completely consumed by the input process. 'read' fails with an 'error' if the
    
    106
    --- parse is unsuccessful, and it is therefore discouraged from being used in
    
    107
    --- real applications. Use 'readMaybe' or 'readEither' for safe alternatives.
    
    108
    ---
    
    109
    --- >>> read "123" :: Int
    
    110
    --- 123
    
    111
    ---
    
    112
    --- >>> read "hello" :: Int
    
    113
    --- *** Exception: Prelude.read: no parse
    
    114
    -read :: Read a => String -> a
    
    115
    -read s = either errorWithoutStackTrace id (readEither s)

  • testsuite/tests/th/T24111.stdout
    ... ... @@ -3,6 +3,6 @@ pattern (:+_0) :: GHC.Internal.Types.Int ->
    3 3
                       (GHC.Internal.Types.Int, GHC.Internal.Types.Int)
    
    4 4
     pattern x_1 :+_0 y_2 = (x_1, y_2)
    
    5 5
     pattern A_0 :: GHC.Internal.Types.Int -> GHC.Internal.Base.String
    
    6
    -pattern A_0 n_1 <- (GHC.Internal.Text.Read.read -> n_1) where
    
    6
    +pattern A_0 n_1 <- (Text.Read.read -> n_1) where
    
    7 7
                            A_0 0 = "hi"
    
    8 8
                            A_0 1 = "bye"

  • testsuite/tests/typecheck/should_compile/subsumption_sort_hole_fits.stderr
    ... ... @@ -11,14 +11,13 @@ subsumption_sort_hole_fits.hs:2:5: warning: [GHC-88464] [-Wtyped-holes (in -Wdef
    11 11
             words :: String -> [String]
    
    12 12
               (imported from ‘Prelude’
    
    13 13
                (and originally defined in ‘GHC.Internal.Data.OldList’))
    
    14
    -        read :: forall a. Read a => String -> a
    
    15
    -          with read @[String]
    
    16
    -          (imported from ‘Prelude’
    
    17
    -           (and originally defined in ‘GHC.Internal.Text.Read’))
    
    18 14
             repeat :: forall a. a -> [a]
    
    19 15
               with repeat @String
    
    20 16
               (imported from ‘Prelude’
    
    21 17
                (and originally defined in ‘GHC.Internal.List’))
    
    18
    +        read :: forall a. Read a => String -> a
    
    19
    +          with read @[String]
    
    20
    +          (imported from ‘Prelude’ (and originally defined in ‘Text.Read’))
    
    22 21
             mempty :: forall a. Monoid a => a
    
    23 22
               with mempty @(String -> [String])
    
    24 23
               (imported from ‘Prelude’
    

  • testsuite/tests/typecheck/should_fail/T21130.stderr
    ... ... @@ -6,6 +6,9 @@ T21130.hs:10:6: error: [GHC-88464]
    6 6
           In an equation for ‘x’: x = (_ f) :: Int
    
    7 7
         • Relevant bindings include x :: Int (bound at T21130.hs:10:1)
    
    8 8
           Valid hole fits include
    
    9
    +        read :: forall a. Read a => String -> a
    
    10
    +          with read @Int
    
    11
    +          (imported from ‘Prelude’ (and originally defined in ‘Text.Read’))
    
    9 12
             head :: forall a. GHC.Internal.Stack.Types.HasCallStack => [a] -> a
    
    10 13
               with head @Int
    
    11 14
               (imported from ‘Prelude’
    
    ... ... @@ -14,10 +17,6 @@ T21130.hs:10:6: error: [GHC-88464]
    14 17
               with last @Int
    
    15 18
               (imported from ‘Prelude’
    
    16 19
                (and originally defined in ‘GHC.Internal.List’))
    
    17
    -        read :: forall a. Read a => String -> a
    
    18
    -          with read @Int
    
    19
    -          (imported from ‘Prelude’
    
    20
    -           (and originally defined in ‘GHC.Internal.Text.Read’))
    
    21 20
     
    
    22 21
     T21130.hs:10:8: error: [GHC-39999]
    
    23 22
         • Ambiguous type variable ‘t0’ arising from a use of ‘f’