compiler: de-lhs hsSyn/
[ghc.git] / compiler / hsSyn / HsLit.hs
1 {-
2 (c) The University of Glasgow 2006
3 (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
4
5 \section[HsLit]{Abstract syntax: source-language literals}
6 -}
7
8 {-# LANGUAGE CPP, DeriveDataTypeable #-}
9 {-# LANGUAGE TypeSynonymInstances #-}
10 {-# LANGUAGE StandaloneDeriving #-}
11 {-# LANGUAGE FlexibleInstances #-}
12 {-# LANGUAGE FlexibleContexts #-}
13 {-# LANGUAGE UndecidableInstances #-} -- Note [Pass sensitive types]
14 -- in module PlaceHolder
15 {-# LANGUAGE ConstraintKinds #-}
16
17 module HsLit where
18
19 #include "HsVersions.h"
20
21 import {-# SOURCE #-} HsExpr( SyntaxExpr, pprExpr )
22 import BasicTypes ( FractionalLit(..) )
23 import Type ( Type )
24 import Outputable
25 import FastString
26 import PlaceHolder ( PostTc,PostRn,DataId )
27 import Lexer ( SourceText )
28
29 import Data.ByteString (ByteString)
30 import Data.Data hiding ( Fixity )
31
32 {-
33 ************************************************************************
34 * *
35 \subsection[HsLit]{Literals}
36 * *
37 ************************************************************************
38 -}
39
40 -- Note [literal source text] for SourceText fields in the following
41 data HsLit
42 = HsChar SourceText Char -- Character
43 | HsCharPrim SourceText Char -- Unboxed character
44 | HsString SourceText FastString -- String
45 | HsStringPrim SourceText ByteString -- Packed bytes
46 | HsInt SourceText Integer -- Genuinely an Int; arises from
47 -- TcGenDeriv, and from TRANSLATION
48 | HsIntPrim SourceText Integer -- literal Int#
49 | HsWordPrim SourceText Integer -- literal Word#
50 | HsInt64Prim SourceText Integer -- literal Int64#
51 | HsWord64Prim SourceText Integer -- literal Word64#
52 | HsInteger SourceText Integer Type -- Genuinely an integer; arises only
53 -- from TRANSLATION (overloaded
54 -- literals are done with HsOverLit)
55 | HsRat FractionalLit Type -- Genuinely a rational; arises only from
56 -- TRANSLATION (overloaded literals are
57 -- done with HsOverLit)
58 | HsFloatPrim FractionalLit -- Unboxed Float
59 | HsDoublePrim FractionalLit -- Unboxed Double
60 deriving (Data, Typeable)
61
62 instance Eq HsLit where
63 (HsChar _ x1) == (HsChar _ x2) = x1==x2
64 (HsCharPrim _ x1) == (HsCharPrim _ x2) = x1==x2
65 (HsString _ x1) == (HsString _ x2) = x1==x2
66 (HsStringPrim _ x1) == (HsStringPrim _ x2) = x1==x2
67 (HsInt _ x1) == (HsInt _ x2) = x1==x2
68 (HsIntPrim _ x1) == (HsIntPrim _ x2) = x1==x2
69 (HsWordPrim _ x1) == (HsWordPrim _ x2) = x1==x2
70 (HsInt64Prim _ x1) == (HsInt64Prim _ x2) = x1==x2
71 (HsWord64Prim _ x1) == (HsWord64Prim _ x2) = x1==x2
72 (HsInteger _ x1 _) == (HsInteger _ x2 _) = x1==x2
73 (HsRat x1 _) == (HsRat x2 _) = x1==x2
74 (HsFloatPrim x1) == (HsFloatPrim x2) = x1==x2
75 (HsDoublePrim x1) == (HsDoublePrim x2) = x1==x2
76 _ == _ = False
77
78 data HsOverLit id -- An overloaded literal
79 = OverLit {
80 ol_val :: OverLitVal,
81 ol_rebindable :: PostRn id Bool, -- Note [ol_rebindable]
82 ol_witness :: SyntaxExpr id, -- Note [Overloaded literal witnesses]
83 ol_type :: PostTc id Type }
84 deriving (Typeable)
85 deriving instance (DataId id) => Data (HsOverLit id)
86
87 -- Note [literal source text] for SourceText fields in the following
88 data OverLitVal
89 = HsIntegral !SourceText !Integer -- Integer-looking literals;
90 | HsFractional !FractionalLit -- Frac-looking literals
91 | HsIsString !SourceText !FastString -- String-looking literals
92 deriving (Data, Typeable)
93
94 overLitType :: HsOverLit a -> PostTc a Type
95 overLitType = ol_type
96
97 {-
98 Note [literal source text]
99 ~~~~~~~~~~~~~~~~~~~~~~~~~~
100
101 The lexer/parser converts literals from their original source text
102 versions to an appropriate internal representation. This is a problem
103 for tools doing source to source conversions, so the original source
104 text is stored in literals where this can occur.
105
106 Motivating examples for HsLit
107
108 HsChar '\n', '\x20`
109 HsCharPrim '\x41`#
110 HsString "\x20\x41" == " A"
111 HsStringPrim "\x20"#
112 HsInt 001
113 HsIntPrim 002#
114 HsWordPrim 003##
115 HsInt64Prim 004##
116 HsWord64Prim 005##
117 HsInteger 006
118
119 For OverLitVal
120
121 HsIntegral 003,0x001
122 HsIsString "\x41nd"
123
124
125
126
127
128 Note [ol_rebindable]
129 ~~~~~~~~~~~~~~~~~~~~
130 The ol_rebindable field is True if this literal is actually
131 using rebindable syntax. Specifically:
132
133 False iff ol_witness is the standard one
134 True iff ol_witness is non-standard
135
136 Equivalently it's True if
137 a) RebindableSyntax is on
138 b) the witness for fromInteger/fromRational/fromString
139 that happens to be in scope isn't the standard one
140
141 Note [Overloaded literal witnesses]
142 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
143 *Before* type checking, the SyntaxExpr in an HsOverLit is the
144 name of the coercion function, 'fromInteger' or 'fromRational'.
145 *After* type checking, it is a witness for the literal, such as
146 (fromInteger 3) or lit_78
147 This witness should replace the literal.
148
149 This dual role is unusual, because we're replacing 'fromInteger' with
150 a call to fromInteger. Reason: it allows commoning up of the fromInteger
151 calls, which wouldn't be possible if the desguarar made the application.
152
153 The PostTcType in each branch records the type the overload literal is
154 found to have.
155 -}
156
157 -- Comparison operations are needed when grouping literals
158 -- for compiling pattern-matching (module MatchLit)
159 instance Eq (HsOverLit id) where
160 (OverLit {ol_val = val1}) == (OverLit {ol_val=val2}) = val1 == val2
161
162 instance Eq OverLitVal where
163 (HsIntegral _ i1) == (HsIntegral _ i2) = i1 == i2
164 (HsFractional f1) == (HsFractional f2) = f1 == f2
165 (HsIsString _ s1) == (HsIsString _ s2) = s1 == s2
166 _ == _ = False
167
168 instance Ord (HsOverLit id) where
169 compare (OverLit {ol_val=val1}) (OverLit {ol_val=val2}) = val1 `compare` val2
170
171 instance Ord OverLitVal where
172 compare (HsIntegral _ i1) (HsIntegral _ i2) = i1 `compare` i2
173 compare (HsIntegral _ _) (HsFractional _) = LT
174 compare (HsIntegral _ _) (HsIsString _ _) = LT
175 compare (HsFractional f1) (HsFractional f2) = f1 `compare` f2
176 compare (HsFractional _) (HsIntegral _ _) = GT
177 compare (HsFractional _) (HsIsString _ _) = LT
178 compare (HsIsString _ s1) (HsIsString _ s2) = s1 `compare` s2
179 compare (HsIsString _ _) (HsIntegral _ _) = GT
180 compare (HsIsString _ _) (HsFractional _) = GT
181
182 instance Outputable HsLit where
183 -- Use "show" because it puts in appropriate escapes
184 ppr (HsChar _ c) = pprHsChar c
185 ppr (HsCharPrim _ c) = pprHsChar c <> char '#'
186 ppr (HsString _ s) = pprHsString s
187 ppr (HsStringPrim _ s) = pprHsBytes s <> char '#'
188 ppr (HsInt _ i) = integer i
189 ppr (HsInteger _ i _) = integer i
190 ppr (HsRat f _) = ppr f
191 ppr (HsFloatPrim f) = ppr f <> char '#'
192 ppr (HsDoublePrim d) = ppr d <> text "##"
193 ppr (HsIntPrim _ i) = integer i <> char '#'
194 ppr (HsWordPrim _ w) = integer w <> text "##"
195 ppr (HsInt64Prim _ i) = integer i <> text "L#"
196 ppr (HsWord64Prim _ w) = integer w <> text "L##"
197
198 -- in debug mode, print the expression that it's resolved to, too
199 instance OutputableBndr id => Outputable (HsOverLit id) where
200 ppr (OverLit {ol_val=val, ol_witness=witness})
201 = ppr val <+> (ifPprDebug (parens (pprExpr witness)))
202
203 instance Outputable OverLitVal where
204 ppr (HsIntegral _ i) = integer i
205 ppr (HsFractional f) = ppr f
206 ppr (HsIsString _ s) = pprHsString s