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