1
{-# LANGUAGE CPP, DeriveDataTypeable #-}
2
{-# LANGUAGE DeriveDataTypeable #-}
3
{-# LANGUAGE FlexibleInstances #-}
4
{-# LANGUAGE PatternGuards #-}
5
{-# LANGUAGE TypeSynonymInstances #-}
3
7
{-| Names in the concrete syntax are just strings (or lists of strings for
6
10
module Agda.Syntax.Concrete.Name where
12
import Control.DeepSeq
8
13
import Control.Applicative
15
import Data.ByteString.Char8 (ByteString)
16
import qualified Data.ByteString.Char8 as ByteString
12
18
import Data.Typeable (Typeable)
14
20
import System.FilePath
31
37
Equality and ordering on @Name@s are defined to ignore range so same names
32
38
in different locations are equal.
34
data Name = Name !Range [NamePart]
35
| NoName !Range NameId
38
data NamePart = Hole | Id String
42
noName_ = noName noRange
44
noName :: Range -> Name
45
noName r = NoName r (NameId 0 0)
47
isNoName :: Name -> Bool
48
isNoName (NoName _ _) = True
49
isNoName (Name _ [Hole]) = True -- TODO: Track down where these come from
50
isNoName (Name _ []) = True
54
isOperator :: Name -> Bool
55
isOperator (NoName {}) = False
56
isOperator (Name _ ps) = length ps > 1
58
nameParts :: Name -> [NamePart]
59
nameParts (Name _ ps) = ps
60
nameParts (NoName _ _) = [Hole]
62
nameStringParts :: Name -> [String]
63
nameStringParts n = [ s | Id s <- nameParts n ]
65
qualify :: QName -> Name -> QName
66
qualify (QName m) x = Qual m (QName x)
67
qualify (Qual m m') x = Qual m $ qualify m' x
70
unqualify :: QName -> Name
71
unqualify q = unqualify' q `withRangeOf` q
73
unqualify' (QName x) = x
74
unqualify' (Qual _ x) = unqualify' x
76
qnameParts :: QName -> [Name]
77
qnameParts (Qual x q) = x : qnameParts q
78
qnameParts (QName x) = [x]
41
= Name !Range [NamePart] -- ^ A (mixfix) identifier.
42
| NoName !Range NameId -- ^ @_@.
47
instance Underscore Name where
48
underscore = NoName noRange __IMPOSSIBLE__
49
isUnderscore NoName{} = True
50
isUnderscore (Name _ [Id x]) = isUnderscore x
51
isUnderscore _ = False
53
-- | Mixfix identifiers are composed of words and holes,
54
-- e.g. @_+_@ or @if_then_else_@ or @[_/_]@.
57
| Id RawName -- ^ Identifier part.
60
-- | Define equality on @Name@ to ignore range so same names in different
61
-- locations are equal.
81
63
-- Is there a reason not to do this? -Jeff
122
95
-- equality. We will have to define an equality instance to
123
96
-- non-generative namespaces (as well as having some sort of
124
97
-- lookup table for namespace names).
125
data QName = Qual Name QName
99
= Qual Name QName -- ^ @A.rest@.
100
| QName Name -- ^ @x@.
127
101
deriving (Typeable, Eq, Ord)
103
instance Underscore QName where
104
underscore = QName underscore
105
isUnderscore (QName x) = isUnderscore x
106
isUnderscore Qual{} = False
108
-- | Top-level module names. Used in connection with the file system.
110
-- Invariant: The list must not be empty.
131
112
newtype TopLevelModuleName
132
113
= TopLevelModuleName { moduleNameParts :: [String] }
133
114
deriving (Show, Eq, Ord, Typeable)
116
------------------------------------------------------------------------
117
-- * Operations on 'Name' and 'NamePart'
118
------------------------------------------------------------------------
120
nameToRawName :: Name -> RawName
123
nameParts :: Name -> [NamePart]
124
nameParts (Name _ ps) = ps
125
nameParts (NoName _ _) = [Hole]
127
nameStringParts :: Name -> [RawName]
128
nameStringParts n = [ s | Id s <- nameParts n ]
130
-- | Parse a string to parts of a concrete name.
132
stringNameParts :: String -> [NamePart]
133
stringNameParts "" = []
134
stringNameParts ('_':s) = Hole : stringNameParts s
135
stringNameParts s | (x, s') <- break (== '_') s = Id (stringToRawName x) : stringNameParts s'
137
-- | Is the name an operator?
139
isOperator :: Name -> Bool
140
isOperator (NoName {}) = False
141
isOperator (Name _ ps) = length ps > 1
143
isHole :: NamePart -> Bool
147
isPrefix, isPostfix, isInfix, isNonfix :: Name -> Bool
148
isPrefix x = not (isHole (head xs)) && isHole (last xs) where xs = nameParts x
149
isPostfix x = isHole (head xs) && not (isHole (last xs)) where xs = nameParts x
150
isInfix x = isHole (head xs) && isHole (last xs) where xs = nameParts x
151
isNonfix x = not (isHole (head xs)) && not (isHole (last xs)) where xs = nameParts x
153
------------------------------------------------------------------------
154
-- * Operations on qualified names
155
------------------------------------------------------------------------
157
-- | @qualify A.B x == A.B.x@
158
qualify :: QName -> Name -> QName
159
qualify (QName m) x = Qual m (QName x)
160
qualify (Qual m m') x = Qual m $ qualify m' x
162
-- | @unqualify A.B.x == x@
164
-- The range is preserved.
165
unqualify :: QName -> Name
166
unqualify q = unqualify' q `withRangeOf` q
168
unqualify' (QName x) = x
169
unqualify' (Qual _ x) = unqualify' x
171
-- | @qnameParts A.B.x = [A, B, x]@
172
qnameParts :: QName -> [Name]
173
qnameParts (Qual x q) = x : qnameParts q
174
qnameParts (QName x) = [x]
176
------------------------------------------------------------------------
177
-- * Operations on 'TopLevelModuleName'
178
------------------------------------------------------------------------
135
180
-- | Turns a qualified name into a 'TopLevelModuleName'. The qualified
136
181
-- name is assumed to represent a top-level module name.
166
isHole :: NamePart -> Bool
170
isPrefix, isPostfix, isInfix, isNonfix :: Name -> Bool
171
isPrefix x = not (isHole (head xs)) && isHole (last xs) where xs = nameParts x
172
isPostfix x = isHole (head xs) && not (isHole (last xs)) where xs = nameParts x
173
isInfix x = isHole (head xs) && isHole (last xs) where xs = nameParts x
174
isNonfix x = not (isHole (head xs)) && not (isHole (last xs)) where xs = nameParts x
209
------------------------------------------------------------------------
211
------------------------------------------------------------------------
213
-- | @noName_ = 'noName' 'noRange'@
215
noName_ = noName noRange
217
-- | @noName r = 'Name' r ['Hole']@
218
noName :: Range -> Name
219
noName r = NoName r (NameId 0 0)
221
-- | Check whether a name is the empty name "_".
222
class IsNoName a where
223
isNoName :: a -> Bool
225
instance IsNoName String where
226
isNoName = isUnderscore
228
instance IsNoName ByteString where
229
isNoName = isUnderscore
231
instance IsNoName Name where
232
isNoName (NoName _ _) = True
233
isNoName (Name _ [Hole]) = True -- TODO: Track down where these come from
234
isNoName (Name _ []) = True
237
instance IsNoName QName where
238
isNoName (QName x) = isNoName x
239
isNoName Qual{} = False -- M.A._ does not qualify as empty name
241
-- no instance for TopLevelModuleName
243
------------------------------------------------------------------------
245
------------------------------------------------------------------------
176
247
instance Show Name where
177
248
show (Name _ xs) = concatMap show xs
188
259
instance Pretty TopLevelModuleName where
189
260
pretty (TopLevelModuleName ms) = text $ intercalate "." ms
262
------------------------------------------------------------------------
263
-- * QuickCheck instances
264
------------------------------------------------------------------------
191
266
instance Arbitrary TopLevelModuleName where
192
267
arbitrary = TopLevelModuleName <$> listOf1 (listOf1 $ elements "AB")
194
269
instance CoArbitrary TopLevelModuleName where
195
270
coarbitrary (TopLevelModuleName m) = coarbitrary m
272
------------------------------------------------------------------------
274
------------------------------------------------------------------------
197
276
instance HasRange Name where
198
277
getRange (Name r ps) = r
199
278
getRange (NoName r _) = r