[project @ 2002-05-10 08:58:34 by simonmar]
[ghc-base.git] / Text / ParserCombinators / ReadPrec.hs
1 {-# OPTIONS -fno-implicit-prelude #-}
2 -----------------------------------------------------------------------------
3 -- |
4 -- Module      :  Text.ParserCombinators.ReadPrec
5 -- Copyright   :  (c) The University of Glasgow 2002
6 -- License     :  BSD-style (see the file libraries/base/LICENSE)
7 -- 
8 -- Maintainer  :  libraries@haskell.org
9 -- Stability   :  provisional
10 -- Portability :  portable
11 --
12 -----------------------------------------------------------------------------
13
14 module Text.ParserCombinators.ReadPrec
15   ( ReadPrec      -- :: * -> *; instance Functor, Monad, MonadPlus
16   
17   -- * Precedences
18   , Prec          -- :: *; = Int
19   , minPrec       -- :: Prec; = 0
20
21   -- * Primitive operations
22   , lift          -- :: ReadP a -> ReadPrec a
23   , prec          -- :: Prec -> ReadPrec a -> ReadPrec a
24   , step          -- :: ReadPrec a -> ReadPrec a
25   , reset         -- :: ReadPrec a -> ReadPrec a
26
27   -- * Other operations
28   , get           -- :: ReadPrec Char
29   , look          -- :: ReadPrec String
30   , (+++)         -- :: ReadPrec a -> ReadPrec a -> ReadPrec a
31   , pfail         -- :: ReadPrec a
32   , choice        -- :: [ReadPrec a] -> ReadPrec a
33
34   -- converters
35   , readPrec_to_P -- :: ReadPrec a       -> (Int -> ReadP a)
36   , readP_to_Prec -- :: (Int -> ReadP a) -> ReadPrec a
37   , readPrec_to_S -- :: ReadPrec a       -> (Int -> ReadS a)
38   , readS_to_Prec -- :: (Int -> ReadS a) -> ReadPrec a
39   )
40  where
41
42
43 import Text.ParserCombinators.ReadP
44   ( ReadP
45   , readP_to_S
46   , readS_to_P
47   )
48
49 import qualified Text.ParserCombinators.ReadP as ReadP
50   ( get
51   , look
52   , (+++)
53   , pfail
54   , choice
55   )
56
57 import Control.Monad( MonadPlus(..) )
58 import GHC.Num( Num(..) )
59 import GHC.Base
60
61 -- ---------------------------------------------------------------------------
62 -- The readPrec type
63
64 newtype ReadPrec a = P { unP :: Prec -> ReadP a }
65
66 -- Functor, Monad, MonadPlus
67
68 instance Functor ReadPrec where
69   fmap h (P f) = P (\n -> fmap h (f n))
70
71 instance Monad ReadPrec where
72   return x  = P (\_ -> return x)
73   fail s    = P (\_ -> fail s)
74   P f >>= k = P (\n -> do a <- f n; let P f' = k a in f' n)
75   
76 instance MonadPlus ReadPrec where
77   mzero = pfail
78   mplus = (+++)
79
80 -- precedences
81   
82 type Prec = Int
83
84 minPrec :: Prec
85 minPrec = 0
86
87 -- ---------------------------------------------------------------------------
88 -- Operations over ReadPrec
89
90 lift :: ReadP a -> ReadPrec a
91 lift m = P (\_ -> m)
92
93 step :: ReadPrec a -> ReadPrec a
94 -- Increases the precedence context by one
95 step (P f) = P (\n -> f (n+1))
96
97 reset :: ReadPrec a -> ReadPrec a
98 -- Resets the precedence context to zero
99 reset (P f) = P (\n -> f minPrec)
100
101 prec :: Prec -> ReadPrec a -> ReadPrec a
102 -- (prec n p) checks that the precedence context is 
103 --                        less than or equal to n,
104 --      if not, fails
105 --      if so, parses p in context n
106 prec n (P f) = P (\c -> if c <= n then f n else ReadP.pfail)
107
108 -- ---------------------------------------------------------------------------
109 -- Derived operations
110
111 get :: ReadPrec Char
112 get = lift ReadP.get
113
114 look :: ReadPrec String
115 look = lift ReadP.look
116
117 (+++) :: ReadPrec a -> ReadPrec a -> ReadPrec a
118 P f1 +++ P f2 = P (\n -> f1 n ReadP.+++ f2 n)
119
120 pfail :: ReadPrec a
121 pfail = lift ReadP.pfail
122
123 choice :: [ReadPrec a] -> ReadPrec a
124 choice ps = foldr (+++) pfail ps
125
126 -- ---------------------------------------------------------------------------
127 -- Converting between ReadPrec and Read
128
129 -- We define a local version of ReadS here,
130 -- because its "real" definition site is in GHC.Read
131 type ReadS a = String -> [(a,String)]
132
133 readPrec_to_P :: ReadPrec a -> (Int -> ReadP a)
134 readPrec_to_P (P f) = f
135
136 readP_to_Prec :: (Int -> ReadP a) -> ReadPrec a
137 readP_to_Prec f = P f
138
139 readPrec_to_S :: ReadPrec a -> (Int -> ReadS a)
140 readPrec_to_S (P f) n = readP_to_S (f n)
141
142 readS_to_Prec :: (Int -> ReadS a) -> ReadPrec a
143 readS_to_Prec f = P (\n -> readS_to_P (f n))