git.iko.soy/rowtype-yoga/purescript-native
on fb94ed4 help sign in
431 lines 11 kB history raw
1-----------------------------------------------------------------------------
2--
3-- Module : Language.PureScript.Declarations
4-- Copyright : (c) Phil Freeman 2013
5-- License : MIT
6--
7-- Maintainer : Phil Freeman <paf31@cantab.net>
8-- Stability : experimental
9-- Portability :
10--
11-- | Data types for modules and declarations
12--
13-----------------------------------------------------------------------------
15{-# LANGUAGE DeriveDataTypeable #-}
17module Language.PureScript.Declarations where
19import Language.PureScript.Types
20import Language.PureScript.Names
21import Language.PureScript.Kinds
22import Language.PureScript.TypeClassDictionaries
23import Language.PureScript.CodeGen.JS.AST
24import Language.PureScript.Environment
26import qualified Data.Data as D
27import Data.Generics (mkQ, everything)
29-- |
30-- A precedence level for an infix operator
31--
32type Precedence = Integer
34-- |
35-- Associativity for infix operators
36--
37data Associativity = Infixl | Infixr | Infix deriving (D.Data, D.Typeable)
39instance Show Associativity where
40 show Infixl = "infixl"
41 show Infixr = "infixr"
42 show Infix = "infix"
44-- |
45-- Source position information
46--
47data SourcePos = SourcePos
48 { -- |
49 -- Source name
50 --
51 sourceName :: String
52 -- |
53 -- Line number
54 --
55 , sourcePosLine :: Int
56 -- |
57 -- Column number
58 --
59 , sourcePosColumn :: Int
60 } deriving (D.Data, D.Typeable)
62instance Show SourcePos where
63 show sp = (sourceName sp) ++ " line " ++ show (sourcePosLine sp) ++ ", column " ++ show (sourcePosColumn sp)
65-- |
66-- Fixity data for infix operators
67--
68data Fixity = Fixity Associativity Precedence deriving (Show, D.Data, D.Typeable)
70-- |
71-- A module declaration, consisting of a module name, a list of declarations, and a list of the
72-- declarations that are explicitly imported. If the export list is Nothing, everything is exported.
73--
74data Module = Module ModuleName [Declaration] (Maybe [DeclarationRef]) deriving (Show, D.Data, D.Typeable)
76-- |
77-- An item in a list of explicit imports or exports
78--
79data DeclarationRef
80 -- |
81 -- A type constructor with data constructors
82 --
83 = TypeRef ProperName (Maybe [ProperName])
84 -- |
85 -- A value
86 --
87 | ValueRef Ident
88 -- |
89 -- A type class
90 --
91 | TypeClassRef ProperName
92 -- |
93 -- A type class instance, created during typeclass desugaring (name, class name, instance types)
94 --
95 | TypeInstanceRef Ident
96 deriving (Show, Eq, D.Data, D.Typeable)
98-- |
99-- The data type of declarations
100--
101data Declaration
102 -- |
103 -- A data type declaration (name, arguments, data constructors)
104 --
105 = DataDeclaration ProperName [String] [(ProperName, [Type])]
106 -- |
107 -- A minimal mutually recursive set of data type declarations
108 --
109 | DataBindingGroupDeclaration [Declaration]
110 -- |
111 -- A type synonym declaration (name, arguments, type)
112 --
113 | TypeSynonymDeclaration ProperName [String] Type
114 -- |
115 -- A type declaration for a value (name, ty)
116 --
117 | TypeDeclaration Ident Type
118 -- |
119 -- A value declaration (name, top-level binders, optional guard, value)
120 --
121 | ValueDeclaration Ident NameKind [Binder] (Maybe Guard) Value
122 -- |
123 -- A minimal mutually recursive set of value declarations
124 --
125 | BindingGroupDeclaration [(Ident, NameKind, Value)]
126 -- |
127 -- A foreign import declaration (type, name, optional inline Javascript, type)
128 --
129 | ExternDeclaration ForeignImportType Ident (Maybe JS) Type
130 -- |
131 -- A data type foreign import (name, kind)
132 --
133 | ExternDataDeclaration ProperName Kind
134 -- |
135 -- A type class instance foreign import
136 --
137 | ExternInstanceDeclaration Ident [(Qualified ProperName, [Type])] (Qualified ProperName) [Type]
138 -- |
139 -- A fixity declaration (fixity data, operator name)
140 --
141 | FixityDeclaration Fixity String
142 -- |
143 -- A module import (module name, optional set of identifiers to import, optional "qualified as"
144 -- name)
145 --
146 | ImportDeclaration ModuleName (Maybe [DeclarationRef]) (Maybe ModuleName)
147 -- |
148 -- A type class declaration (name, argument, member declarations)
149 --
150 | TypeClassDeclaration ProperName [String] [Declaration]
151 -- |
152 -- A type instance declaration (name, dependencies, class name, instance types, member
153 -- declarations)
154 --
155 | TypeInstanceDeclaration Ident [(Qualified ProperName, [Type])] (Qualified ProperName) [Type] [Declaration]
156 -- |
157 -- A declaration with source position information
158 --
159 | PositionedDeclaration SourcePos Declaration
160 deriving (Show, D.Data, D.Typeable)
162-- |
163-- Test if a declaration is a value declaration
164--
165isValueDecl :: Declaration -> Bool
166isValueDecl ValueDeclaration{} = True
167isValueDecl (PositionedDeclaration _ d) = isValueDecl d
168isValueDecl _ = False
170-- |
171-- Test if a declaration is a data type or type synonym declaration
172--
173isDataDecl :: Declaration -> Bool
174isDataDecl DataDeclaration{} = True
175isDataDecl TypeSynonymDeclaration{} = True
176isDataDecl (PositionedDeclaration _ d) = isDataDecl d
177isDataDecl _ = False
179-- |
180-- Test if a declaration is a module import
181--
182isImportDecl :: Declaration -> Bool
183isImportDecl ImportDeclaration{} = True
184isImportDecl (PositionedDeclaration _ d) = isImportDecl d
185isImportDecl _ = False
187-- |
188-- Test if a declaration is a data type foreign import
189--
190isExternDataDecl :: Declaration -> Bool
191isExternDataDecl ExternDataDeclaration{} = True
192isExternDataDecl (PositionedDeclaration _ d) = isExternDataDecl d
193isExternDataDecl _ = False
195-- |
196-- Test if a declaration is a type class instance foreign import
197--
198isExternInstanceDecl :: Declaration -> Bool
199isExternInstanceDecl ExternInstanceDeclaration{} = True
200isExternInstanceDecl (PositionedDeclaration _ d) = isExternInstanceDecl d
201isExternInstanceDecl _ = False
203-- |
204-- Test if a declaration is a fixity declaration
205--
206isFixityDecl :: Declaration -> Bool
207isFixityDecl FixityDeclaration{} = True
208isFixityDecl (PositionedDeclaration _ d) = isFixityDecl d
209isFixityDecl _ = False
211-- |
212-- Test if a declaration is a foreign import
213--
214isExternDecl :: Declaration -> Bool
215isExternDecl ExternDeclaration{} = True
216isExternDecl (PositionedDeclaration _ d) = isExternDecl d
217isExternDecl _ = False
219-- |
220-- Test if a declaration is a type class or instance declaration
221--
222isTypeClassDeclaration :: Declaration -> Bool
223isTypeClassDeclaration TypeClassDeclaration{} = True
224isTypeClassDeclaration TypeInstanceDeclaration{} = True
225isTypeClassDeclaration (PositionedDeclaration _ d) = isTypeClassDeclaration d
226isTypeClassDeclaration _ = False
228-- |
229-- A guard is just a boolean-valued expression that appears alongside a set of binders
230--
231type Guard = Value
233-- |
234-- Data type for values
235--
236data Value
237 -- |
238 -- A numeric literal
239 --
240 = NumericLiteral (Either Integer Double)
241 -- |
242 -- A string literal
243 --
244 | StringLiteral String
245 -- |
246 -- A boolean literal
247 --
248 | BooleanLiteral Bool
249 -- |
250 -- A prefix -, will be desugared
251 --
252 | UnaryMinus Value
253 -- |
254 -- Binary operator application. During the rebracketing phase of desugaring, this data constructor
255 -- will be removed.
256 --
257 | BinaryNoParens (Qualified Ident) Value Value
258 -- |
259 -- Explicit parentheses. During the rebracketing phase of desugaring, this data constructor
260 -- will be removed.
261 --
262 | Parens Value
263 -- |
264 -- An array literal
265 --
266 | ArrayLiteral [Value]
267 -- |
268 -- An object literal
269 --
270 | ObjectLiteral [(String, Value)]
271 -- |
272 -- An record property accessor expression
273 --
274 | Accessor String Value
275 -- |
276 -- Partial record update
277 --
278 | ObjectUpdate Value [(String, Value)]
279 -- |
280 -- Function introduction
281 --
282 | Abs (Either Ident Binder) Value
283 -- |
284 -- Function application
285 --
286 | App Value Value
287 -- |
288 -- Variable
289 --
290 | Var (Qualified Ident)
291 -- |
292 -- Conditional (if-then-else expression)
293 --
294 | IfThenElse Value Value Value
295 -- |
296 -- A data constructor
297 --
298 | Constructor (Qualified ProperName)
299 -- |
300 -- A case expression. During the case expansion phase of desugaring, top-level binders will get
301 -- desugared into case expressions, hence the need for guards and multiple binders per branch here.
302 --
303 | Case [Value] [CaseAlternative]
304 -- |
305 -- A value with a type annotation
306 --
307 | TypedValue Bool Value Type
308 -- |
309 -- A let binding
310 --
311 | Let [Declaration] Value
312 -- |
313 -- A do-notation block
314 --
315 | Do [DoNotationElement]
316 -- |
317 -- A placeholder for a type class dictionary to be inserted later. At the end of type checking, these
318 -- placeholders will be replaced with actual expressions representing type classes dictionaries which
319 -- can be evaluated at runtime. The constructor arguments represent (in order): the type class name and
320 -- instance type, and the type class dictionaries in scope.
321 --
322 | TypeClassDictionary (Qualified ProperName, [Type]) [TypeClassDictionaryInScope]
323 -- |
324 -- A value with source position information
325 --
326 | PositionedValue SourcePos Value deriving (Show, D.Data, D.Typeable)
328-- |
329-- An alternative in a case statement
330--
331data CaseAlternative = CaseAlternative
332 { -- |
333 -- A collection of binders with which to match the inputs
334 --
335 caseAlternativeBinders :: [Binder]
336 -- |
337 -- An optional guard
338 --
339 , caseAlternativeGuard :: Maybe Guard
340 -- |
341 -- The result expression
342 --
343 , caseAlternativeResult :: Value
344 } deriving (Show, D.Data, D.Typeable)
346-- |
347-- Find the original dictionary which a type class dictionary in scope refers to
348--
349canonicalizeDictionary :: TypeClassDictionaryInScope -> Qualified Ident
350canonicalizeDictionary (TypeClassDictionaryInScope { tcdType = TCDRegular, tcdName = nm }) = nm
351canonicalizeDictionary (TypeClassDictionaryInScope { tcdType = TCDAlias nm }) = nm
353-- |
354-- A statement in a do-notation block
355--
356data DoNotationElement
357 -- |
358 -- A monadic value without a binder
359 --
360 = DoNotationValue Value
361 -- |
362 -- A monadic value with a binder
363 --
364 | DoNotationBind Binder Value
365 -- |
366 -- A let statement, i.e. a pure value with a binder
367 --
368 | DoNotationLet Binder Value
369 -- |
370 -- A do notation element with source position information
371 --
372 | PositionedDoNotationElement SourcePos DoNotationElement deriving (Show, D.Data, D.Typeable)
374-- |
375-- Data type for binders
376--
377data Binder
378 -- |
379 -- Wildcard binder
380 --
381 = NullBinder
382 -- |
383 -- A binder which matches a boolean literal
384 --
385 | BooleanBinder Bool
386 -- |
387 -- A binder which matches a string literal
388 --
389 | StringBinder String
390 -- |
391 -- A binder which matches a numeric literal
392 --
393 | NumberBinder (Either Integer Double)
394 -- |
395 -- A binder which binds an identifier
396 --
397 | VarBinder Ident
398 -- |
399 -- A binder which matches a data constructor
400 --
401 | ConstructorBinder (Qualified ProperName) [Binder]
402 -- |
403 -- A binder which matches a record and binds its properties
404 --
405 | ObjectBinder [(String, Binder)]
406 -- |
407 -- A binder which matches an array and binds its elements
408 --
409 | ArrayBinder [Binder]
410 -- |
411 -- A binder which matches an array and binds its head and tail
412 --
413 | ConsBinder Binder Binder
414 -- |
415 -- A binder which binds its input to an identifier
416 --
417 | NamedBinder Ident Binder
418 -- |
419 -- A binder with source position information
420 --
421 | PositionedBinder SourcePos Binder deriving (Show, D.Data, D.Typeable)
423-- |
424-- Collect all names introduced in binders in an expression
425--
426binderNames :: (D.Data d) => d -> [Ident]
427binderNames = everything (++) (mkQ [] go)
428 where
429 go (VarBinder ident) = [ident]
430 go (NamedBinder ident _) = [ident]
431 go _ = []