1-----------------------------------------------------------------------------
3-- Module : Language.PureScript.Declarations
4-- Copyright : (c) Phil Freeman 2013
7-- Maintainer : Phil Freeman <paf31@cantab.net>
8-- Stability : experimental
11-- | Data types for modules and declarations
13-----------------------------------------------------------------------------
15{-# LANGUAGE DeriveDataTypeable #-}
17module Language.PureScript.Declarations where
19import Data.Monoid (Monoid(..), mconcat)
21import Language.PureScript.Types
22import Language.PureScript.Names
23import Language.PureScript.Kinds
24import Language.PureScript.TypeClassDictionaries
25import Language.PureScript.CodeGen.JS.AST
26import Language.PureScript.Environment
28import qualified Data.Data as D
31-- A precedence level for an infix operator
33type Precedence = Integer
36-- Associativity for infix operators
38data Associativity = Infixl | Infixr | Infix deriving (D.Data, D.Typeable)
40instance Show Associativity where
41 show Infixl = "infixl"
42 show Infixr = "infixr"
46-- Source position information
48data SourcePos = SourcePos
56 , sourcePosLine :: Int
60 , sourcePosColumn :: Int
61 } deriving (D.Data, D.Typeable)
63instance Show SourcePos where
64 show sp = (sourceName sp) ++ " line " ++ show (sourcePosLine sp) ++ ", column " ++ show (sourcePosColumn sp)
67-- Fixity data for infix operators
69data Fixity = Fixity Associativity Precedence deriving (Show, D.Data, D.Typeable)
72-- A module declaration, consisting of a module name, a list of declarations, and a list of the
73-- declarations that are explicitly exported. If the export list is Nothing, everything is exported.
75data Module = Module ModuleName [Declaration] (Maybe [DeclarationRef]) deriving (Show, D.Data, D.Typeable)
78-- An item in a list of explicit imports or exports
82 -- A type constructor with data constructors
84 = TypeRef ProperName (Maybe [ProperName])
92 | TypeClassRef ProperName
94 -- A type class instance, created during typeclass desugaring (name, class name, instance types)
96 | TypeInstanceRef Ident
98 -- A declaration reference with source position information
100 | PositionedDeclarationRef SourcePos DeclarationRef
101 deriving (Show, D.Data, D.Typeable)
103instance Eq DeclarationRef where
104 (TypeRef name dctors) == (TypeRef name' dctors') = name == name' && dctors == dctors'
105 (ValueRef name) == (ValueRef name') = name == name'
106 (TypeClassRef name) == (TypeClassRef name') = name == name'
107 (TypeInstanceRef name) == (TypeInstanceRef name') = name == name'
108 (PositionedDeclarationRef _ r) == r' = r == r'
109 r == (PositionedDeclarationRef _ r') = r == r'
113-- The data type of declarations
117 -- A data type declaration (name, arguments, data constructors)
119 = DataDeclaration ProperName [String] [(ProperName, [Type])]
121 -- A minimal mutually recursive set of data type declarations
123 | DataBindingGroupDeclaration [Declaration]
125 -- A type synonym declaration (name, arguments, type)
127 | TypeSynonymDeclaration ProperName [String] Type
129 -- A type declaration for a value (name, ty)
131 | TypeDeclaration Ident Type
133 -- A value declaration (name, top-level binders, optional guard, value)
135 | ValueDeclaration Ident NameKind [Binder] (Maybe Guard) Value
137 -- A minimal mutually recursive set of value declarations
139 | BindingGroupDeclaration [(Ident, NameKind, Value)]
141 -- A foreign import declaration (type, name, optional inline Javascript, type)
143 | ExternDeclaration ForeignImportType Ident (Maybe JS) Type
145 -- A data type foreign import (name, kind)
147 | ExternDataDeclaration ProperName Kind
149 -- A type class instance foreign import
151 | ExternInstanceDeclaration Ident [(Qualified ProperName, [Type])] (Qualified ProperName) [Type]
153 -- A fixity declaration (fixity data, operator name)
155 | FixityDeclaration Fixity String
157 -- A module import (module name, optional set of identifiers to import, optional "qualified as"
160 | ImportDeclaration ModuleName (Maybe [DeclarationRef]) (Maybe ModuleName)
162 -- A type class declaration (name, argument, implies, member declarations)
164 | TypeClassDeclaration ProperName [String] [(Qualified ProperName, [Type])] [Declaration]
166 -- A type instance declaration (name, dependencies, class name, instance types, member
169 | TypeInstanceDeclaration Ident [(Qualified ProperName, [Type])] (Qualified ProperName) [Type] [Declaration]
171 -- A declaration with source position information
173 | PositionedDeclaration SourcePos Declaration
174 deriving (Show, D.Data, D.Typeable)
177-- Test if a declaration is a value declaration
179isValueDecl :: Declaration -> Bool
180isValueDecl ValueDeclaration{} = True
181isValueDecl (PositionedDeclaration _ d) = isValueDecl d
185-- Test if a declaration is a data type or type synonym declaration
187isDataDecl :: Declaration -> Bool
188isDataDecl DataDeclaration{} = True
189isDataDecl TypeSynonymDeclaration{} = True
190isDataDecl (PositionedDeclaration _ d) = isDataDecl d
194-- Test if a declaration is a module import
196isImportDecl :: Declaration -> Bool
197isImportDecl ImportDeclaration{} = True
198isImportDecl (PositionedDeclaration _ d) = isImportDecl d
199isImportDecl _ = False
202-- Test if a declaration is a data type foreign import
204isExternDataDecl :: Declaration -> Bool
205isExternDataDecl ExternDataDeclaration{} = True
206isExternDataDecl (PositionedDeclaration _ d) = isExternDataDecl d
207isExternDataDecl _ = False
210-- Test if a declaration is a type class instance foreign import
212isExternInstanceDecl :: Declaration -> Bool
213isExternInstanceDecl ExternInstanceDeclaration{} = True
214isExternInstanceDecl (PositionedDeclaration _ d) = isExternInstanceDecl d
215isExternInstanceDecl _ = False
218-- Test if a declaration is a fixity declaration
220isFixityDecl :: Declaration -> Bool
221isFixityDecl FixityDeclaration{} = True
222isFixityDecl (PositionedDeclaration _ d) = isFixityDecl d
223isFixityDecl _ = False
226-- Test if a declaration is a foreign import
228isExternDecl :: Declaration -> Bool
229isExternDecl ExternDeclaration{} = True
230isExternDecl (PositionedDeclaration _ d) = isExternDecl d
231isExternDecl _ = False
234-- Test if a declaration is a type class or instance declaration
236isTypeClassDeclaration :: Declaration -> Bool
237isTypeClassDeclaration TypeClassDeclaration{} = True
238isTypeClassDeclaration TypeInstanceDeclaration{} = True
239isTypeClassDeclaration (PositionedDeclaration _ d) = isTypeClassDeclaration d
240isTypeClassDeclaration _ = False
243-- A guard is just a boolean-valued expression that appears alongside a set of binders
248-- Data type for values
254 = NumericLiteral (Either Integer Double)
258 | StringLiteral String
262 | BooleanLiteral Bool
264 -- A prefix -, will be desugared
268 -- Binary operator application. During the rebracketing phase of desugaring, this data constructor
271 | BinaryNoParens (Qualified Ident) Value Value
273 -- Explicit parentheses. During the rebracketing phase of desugaring, this data constructor
280 | ArrayLiteral [Value]
284 | ObjectLiteral [(String, Value)]
286 -- An record property accessor expression
288 | Accessor String Value
290 -- Partial record update
292 | ObjectUpdate Value [(String, Value)]
294 -- Function introduction
296 | Abs (Either Ident Binder) Value
298 -- Function application
304 | Var (Qualified Ident)
306 -- Conditional (if-then-else expression)
308 | IfThenElse Value Value Value
310 -- A data constructor
312 | Constructor (Qualified ProperName)
314 -- A case expression. During the case expansion phase of desugaring, top-level binders will get
315 -- desugared into case expressions, hence the need for guards and multiple binders per branch here.
317 | Case [Value] [CaseAlternative]
319 -- A value with a type annotation
321 | TypedValue Bool Value Type
325 | Let [Declaration] Value
327 -- A do-notation block
329 | Do [DoNotationElement]
331 -- A placeholder for a type class dictionary to be inserted later. At the end of type checking, these
332 -- placeholders will be replaced with actual expressions representing type classes dictionaries which
333 -- can be evaluated at runtime. The constructor arguments represent (in order): whether or not to look
334 -- at superclass implementations when searching for a dictionary, the type class name and
335 -- instance type, and the type class dictionaries in scope.
337 | TypeClassDictionary Bool (Qualified ProperName, [Type]) [TypeClassDictionaryInScope]
339 -- A placeholder for a superclass dictionary to be turned into a TypeClassDictionary during typechecking
341 | SuperClassDictionary (Qualified ProperName) [Type]
343 -- A value with source position information
345 | PositionedValue SourcePos Value deriving (Show, D.Data, D.Typeable)
348-- An alternative in a case statement
350data CaseAlternative = CaseAlternative
352 -- A collection of binders with which to match the inputs
354 caseAlternativeBinders :: [Binder]
358 , caseAlternativeGuard :: Maybe Guard
360 -- The result expression
362 , caseAlternativeResult :: Value
363 } deriving (Show, D.Data, D.Typeable)
366-- Find the original dictionary which a type class dictionary in scope refers to
368canonicalizeDictionary :: TypeClassDictionaryInScope -> Qualified Ident
369canonicalizeDictionary (TypeClassDictionaryInScope { tcdType = TCDRegular, tcdName = nm }) = nm
370canonicalizeDictionary (TypeClassDictionaryInScope { tcdType = TCDAlias nm }) = nm
373-- A statement in a do-notation block
375data DoNotationElement
377 -- A monadic value without a binder
379 = DoNotationValue Value
381 -- A monadic value with a binder
383 | DoNotationBind Binder Value
385 -- A let statement, i.e. a pure value with a binder
387 | DoNotationLet [Declaration]
389 -- A do notation element with source position information
391 | PositionedDoNotationElement SourcePos DoNotationElement deriving (Show, D.Data, D.Typeable)
394-- Data type for binders
402 -- A binder which matches a boolean literal
406 -- A binder which matches a string literal
408 | StringBinder String
410 -- A binder which matches a numeric literal
412 | NumberBinder (Either Integer Double)
414 -- A binder which binds an identifier
418 -- A binder which matches a data constructor
420 | ConstructorBinder (Qualified ProperName) [Binder]
422 -- A binder which matches a record and binds its properties
424 | ObjectBinder [(String, Binder)]
426 -- A binder which matches an array and binds its elements
428 | ArrayBinder [Binder]
430 -- A binder which matches an array and binds its head and tail
432 | ConsBinder Binder Binder
434 -- A binder which binds its input to an identifier
436 | NamedBinder Ident Binder
438 -- A binder with source position information
440 | PositionedBinder SourcePos Binder deriving (Show, D.Data, D.Typeable)
443-- Collect all names introduced in binders in an expression
445binderNames :: Binder -> [Ident]
448 go ns (VarBinder name) = name : ns
449 go ns (ConstructorBinder _ bs) = foldl go ns bs
450 go ns (ObjectBinder bs) = foldl go ns (map snd bs)
451 go ns (ArrayBinder bs) = foldl go ns bs
452 go ns (ConsBinder b1 b2) = go (go ns b1) b2
453 go ns (NamedBinder name b) = go (name : ns) b
454 go ns (PositionedBinder _ b) = go ns b
461everywhereOnValues :: (Declaration -> Declaration) ->
463 (Binder -> Binder) ->
464 (Declaration -> Declaration, Value -> Value, Binder -> Binder)
465everywhereOnValues f g h = (f', g', h')
467 f' :: Declaration -> Declaration
468 f' (DataBindingGroupDeclaration ds) = f (DataBindingGroupDeclaration (map f' ds))
469 f' (ValueDeclaration name nameKind bs grd val) = f (ValueDeclaration name nameKind (map h' bs) (fmap g' grd) (g' val))
470 f' (BindingGroupDeclaration ds) = f (BindingGroupDeclaration (map (\(name, nameKind, val) -> (name, nameKind, g' val)) ds))
471 f' (TypeClassDeclaration name args implies ds) = f (TypeClassDeclaration name args implies (map f' ds))
472 f' (TypeInstanceDeclaration name cs className args ds) = f (TypeInstanceDeclaration name cs className args (map f' ds))
473 f' (PositionedDeclaration pos d) = f (PositionedDeclaration pos (f' d))
477 g' (UnaryMinus v) = g (UnaryMinus (g' v))
478 g' (BinaryNoParens op v1 v2) = g (BinaryNoParens op (g' v1) (g' v2))
479 g' (Parens v) = g (Parens (g' v))
480 g' (ArrayLiteral vs) = g (ArrayLiteral (map g' vs))
481 g' (ObjectLiteral vs) = g (ObjectLiteral (map (fmap g') vs))
482 g' (Accessor prop v) = g (Accessor prop (g' v))
483 g' (ObjectUpdate obj vs) = g (ObjectUpdate (g' obj) (map (fmap g') vs))
484 g' (Abs name v) = g (Abs name (g' v))
485 g' (App v1 v2) = g (App (g' v1) (g' v2))
486 g' (IfThenElse v1 v2 v3) = g (IfThenElse (g' v1) (g' v2) (g' v3))
487 g' (Case vs alts) = g (Case (map g' vs) (map handleCaseAlternative alts))
488 g' (TypedValue check v ty) = g (TypedValue check (g' v) ty)
489 g' (Let ds v) = g (Let (map f' ds) (g' v))
490 g' (Do es) = g (Do (map handleDoNotationElement es))
491 g' (PositionedValue pos v) = g (PositionedValue pos (g' v))
494 h' :: Binder -> Binder
495 h' (ConstructorBinder ctor bs) = h (ConstructorBinder ctor (map h' bs))
496 h' (ObjectBinder bs) = h (ObjectBinder (map (fmap h') bs))
497 h' (ArrayBinder bs) = h (ArrayBinder (map h' bs))
498 h' (ConsBinder b1 b2) = h (ConsBinder (h' b1) (h' b2))
499 h' (NamedBinder name b) = h (NamedBinder name (h' b))
500 h' (PositionedBinder pos b) = h (PositionedBinder pos (h' b))
503 handleCaseAlternative :: CaseAlternative -> CaseAlternative
504 handleCaseAlternative ca =
505 ca { caseAlternativeBinders = map h' (caseAlternativeBinders ca)
506 , caseAlternativeGuard = fmap g' (caseAlternativeGuard ca)
507 , caseAlternativeResult = g' (caseAlternativeResult ca)
510 handleDoNotationElement :: DoNotationElement -> DoNotationElement
511 handleDoNotationElement (DoNotationValue v) = DoNotationValue (g' v)
512 handleDoNotationElement (DoNotationBind b v) = DoNotationBind (h' b) (g' v)
513 handleDoNotationElement (DoNotationLet ds) = DoNotationLet (map f' ds)
514 handleDoNotationElement (PositionedDoNotationElement pos e) = PositionedDoNotationElement pos (handleDoNotationElement e)
516everythingOnValues :: (r -> r -> r) ->
517 (Declaration -> r) ->
520 (CaseAlternative -> r) ->
521 (DoNotationElement -> r) ->
522 (Declaration -> r, Value -> r, Binder -> r, CaseAlternative -> r, DoNotationElement -> r)
523everythingOnValues (<>) f g h i j = (f', g', h', i', j')
525 f' d@(DataBindingGroupDeclaration ds) = foldl (<>) (f d) (map f' ds)
526 f' d@(ValueDeclaration _ _ bs Nothing val) = foldl (<>) (f d) (map h' bs) <> g' val
527 f' d@(ValueDeclaration _ _ bs (Just grd) val) = foldl (<>) (f d) (map h' bs) <> g' grd <> g' val
528 f' d@(BindingGroupDeclaration ds) = foldl (<>) (f d) (map (\(_, _, val) -> g' val) ds)
529 f' d@(TypeClassDeclaration _ _ _ ds) = foldl (<>) (f d) (map f' ds)
530 f' d@(TypeInstanceDeclaration _ _ _ _ ds) = foldl (<>) (f d) (map f' ds)
531 f' d@(PositionedDeclaration _ d1) = f d <> f' d1
534 g' v@(UnaryMinus v1) = g v <> g' v1
535 g' v@(BinaryNoParens _ v1 v2) = g v <> g' v1 <> g' v2
536 g' v@(Parens v1) = g v <> g' v1
537 g' v@(ArrayLiteral vs) = foldl (<>) (g v) (map g' vs)
538 g' v@(ObjectLiteral vs) = foldl (<>) (g v) (map (g' . snd) vs)
539 g' v@(Accessor _ v1) = g v <> g' v1
540 g' v@(ObjectUpdate obj vs) = foldl (<>) (g v <> g' obj) (map (g' . snd) vs)
541 g' v@(Abs _ v1) = g v <> g' v1
542 g' v@(App v1 v2) = g v <> g' v1 <> g' v2
543 g' v@(IfThenElse v1 v2 v3) = g v <> g' v1 <> g' v2 <> g' v3
544 g' v@(Case vs alts) = foldl (<>) (foldl (<>) (g v) (map g' vs)) (map i' alts)
545 g' v@(TypedValue _ v1 _) = g v <> g' v1
546 g' v@(Let ds v1) = (foldl (<>) (g v) (map f' ds)) <> g' v1
547 g' v@(Do es) = foldl (<>) (g v) (map j' es)
548 g' v@(PositionedValue _ v1) = g v <> g' v1
551 h' b@(ConstructorBinder _ bs) = foldl (<>) (h b) (map h' bs)
552 h' b@(ObjectBinder bs) = foldl (<>) (h b) (map (h' . snd) bs)
553 h' b@(ArrayBinder bs) = foldl (<>) (h b) (map h' bs)
554 h' b@(ConsBinder b1 b2) = h b <> h' b1 <> h' b2
555 h' b@(NamedBinder _ b1) = h b <> h' b1
556 h' b@(PositionedBinder _ b1) = h b <> h' b1
559 i' ca = case caseAlternativeGuard ca of
560 Nothing -> foldl (<>) (i ca) (map h' (caseAlternativeBinders ca)) <> g' (caseAlternativeResult ca)
561 Just grd -> foldl (<>) (i ca) (map h' (caseAlternativeBinders ca)) <> g' grd <> g' (caseAlternativeResult ca)
563 j' e@(DoNotationValue v) = j e <> g' v
564 j' e@(DoNotationBind b v) = j e <> h' b <> g' v
565 j' e@(DoNotationLet ds) = foldl (<>) (j e) (map f' ds)
566 j' e@(PositionedDoNotationElement _ e1) = j e <> j' e1
568accumTypes :: (Monoid r) => (Type -> r) -> (Declaration -> r, Value -> r, Binder -> r, CaseAlternative -> r, DoNotationElement -> r)
569accumTypes f = everythingOnValues mappend forDecls forValues (const mempty) (const mempty) (const mempty)
571 forDecls (DataDeclaration _ _ dctors) = mconcat (concatMap (map f . snd) dctors)
572 forDecls (ExternDeclaration _ _ _ ty) = f ty
573 forDecls (ExternInstanceDeclaration _ cs _ tys) = mconcat (concatMap (map f . snd) cs) `mappend` mconcat (map f tys)
574 forDecls (TypeClassDeclaration _ _ implies _) = mconcat (concatMap (map f . snd) implies)
575 forDecls (TypeInstanceDeclaration _ cs _ tys _) = mconcat (concatMap (map f . snd) cs) `mappend` mconcat (map f tys)
576 forDecls (TypeSynonymDeclaration _ _ ty) = f ty
577 forDecls (TypeDeclaration _ ty) = f ty
580 forValues (TypeClassDictionary _ (_, cs) _) = mconcat (map f cs)
581 forValues (SuperClassDictionary _ tys) = mconcat (map f tys)
582 forValues (TypedValue _ _ ty) = f ty
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list