1-----------------------------------------------------------------------------
3-- Module : Language.PureScript.Environment
4-- Copyright : (c) 2013-14 Phil Freeman, (c) 2014 Gary Burgess, and other contributors
7-- Maintainer : Phil Freeman <paf31@cantab.net>
8-- Stability : experimental
13-----------------------------------------------------------------------------
15{-# LANGUAGE DeriveDataTypeable #-}
16{-# LANGUAGE OverloadedStrings #-}
17{-# LANGUAGE TemplateHaskell #-}
19module Language.PureScript.Environment where
22import Data.Maybe (fromMaybe)
24import qualified Data.Map as M
25import qualified Data.Text as T
26import qualified Data.Aeson as A
28import Language.PureScript.Kinds
29import Language.PureScript.Names
30import Language.PureScript.TypeClassDictionaries
31import Language.PureScript.Types
32import qualified Language.PureScript.Constants as C
35-- The @Environment@ defines all values and types which are currently in scope:
37data Environment = Environment {
39 -- Value names currently in scope
41 names :: M.Map (ModuleName, Ident) (Type, NameKind, NameVisibility)
43 -- Type names currently in scope
45 , types :: M.Map (Qualified ProperName) (Kind, TypeKind)
47 -- Data constructors currently in scope, along with their associated type
48 -- constructor name, argument types and return type.
49 , dataConstructors :: M.Map (Qualified ProperName) (DataDeclType, ProperName, Type, [Ident])
51 -- Type synonyms currently in scope
53 , typeSynonyms :: M.Map (Qualified ProperName) ([(String, Maybe Kind)], Type)
55 -- Available type class dictionaries
57 , typeClassDictionaries :: M.Map (Maybe ModuleName) (M.Map (Qualified ProperName) (M.Map (Qualified Ident) TypeClassDictionaryInScope))
61 , typeClasses :: M.Map (Qualified ProperName) ([(String, Maybe Kind)], [(Ident, Type)], [Constraint])
62 } deriving (Show, Read)
65-- The initial environment with no values and only the default javascript types defined
67initEnvironment :: Environment
68initEnvironment = Environment M.empty primTypes M.empty M.empty M.empty M.empty
71-- The visibility of a name in scope
75 -- The name is defined in the current binding group, but is not visible
79 -- The name is defined in the another binding group, or has been made visible by a function binder
81 | Defined deriving (Show, Read, Eq)
84-- A flag for whether a name is for an private or public value - only public values will be
85-- included in a generated externs file.
89 -- A private value introduced as an artifact of code generation (class instances, class member
94 -- A public value for a module member or foreing import declaration
98 -- A name for member introduced by foreign import
100 | External deriving (Show, Read, Eq, Data, Typeable)
103-- The kinds of a type
109 = DataType [(String, Maybe Kind)] [(ProperName, [Type])]
119 -- A local type variable
123 -- A scoped type variable
126 deriving (Show, Read, Eq, Data, Typeable)
129-- The type ('data' or 'newtype') of a data type declaration
133 -- A standard data constructor
137 -- A newtype constructor
139 | Newtype deriving (Show, Read, Eq, Ord, Data, Typeable)
141showDataDeclType :: DataDeclType -> String
142showDataDeclType Data = "data"
143showDataDeclType Newtype = "newtype"
145instance A.ToJSON DataDeclType where
146 toJSON = A.toJSON . showDataDeclType
148instance A.FromJSON DataDeclType where
149 parseJSON = A.withText "DataDeclType" $ \str ->
151 "data" -> return Data
152 "newtype" -> return Newtype
153 other -> fail $ "invalid type: '" ++ T.unpack other ++ "'"
156-- Construct a ProperName in the Prim module
158primName :: String -> Qualified ProperName
159primName = Qualified (Just $ ModuleName [ProperName C.prim]) . ProperName
162-- Construct a type in the Prim module
164primTy :: String -> Type
165primTy = TypeConstructor . primName
168-- Type constructor for functions
171tyFunction = primTy "Function"
174-- Type constructor for strings
177tyString = primTy "String"
180-- Type constructor for strings
183tyChar = primTy "Char"
186-- Type constructor for numbers
189tyNumber = primTy "Number"
192-- Type constructor for integers
198-- Type constructor for booleans
201tyBoolean = primTy "Boolean"
204-- Type constructor for arrays
207tyArray = primTy "Array"
210-- Type constructor for objects
213tyObject = primTy "Object"
216-- Check whether a type is an object
218isObject :: Type -> Bool
219isObject = isTypeOrApplied tyObject
222-- Check whether a type is a function
224isFunction :: Type -> Bool
225isFunction = isTypeOrApplied tyFunction
227isTypeOrApplied :: Type -> Type -> Bool
228isTypeOrApplied t1 (TypeApp t2 _) = t1 == t2
229isTypeOrApplied t1 t2 = t1 == t2
232-- Smart constructor for function types
234function :: Type -> Type -> Type
235function t1 = TypeApp (TypeApp tyFunction t1)
238-- The primitive types in the external javascript environment with their associated kinds.
240primTypes :: M.Map (Qualified ProperName) (Kind, TypeKind)
241primTypes = M.fromList [ (primName "Function" , (FunKind Star (FunKind Star Star), ExternData))
242 , (primName "Array" , (FunKind Star Star, ExternData))
243 , (primName "Object" , (FunKind (Row Star) Star, ExternData))
244 , (primName "String" , (Star, ExternData))
245 , (primName "Char" , (Star, ExternData))
246 , (primName "Number" , (Star, ExternData))
247 , (primName "Int" , (Star, ExternData))
248 , (primName "Boolean" , (Star, ExternData)) ]
251-- Finds information about data constructors from the current environment.
253lookupConstructor :: Environment -> Qualified ProperName -> (DataDeclType, ProperName, Type, [Ident])
254lookupConstructor env ctor =
255 fromMaybe (error "Data constructor not found") $ ctor `M.lookup` dataConstructors env
258-- Checks whether a data constructor is for a newtype.
260isNewtypeConstructor :: Environment -> Qualified ProperName -> Bool
261isNewtypeConstructor e ctor = case lookupConstructor e ctor of
262 (Newtype, _, _, _) -> True
263 (Data, _, _, _) -> False
266-- Finds information about values from the current environment.
268lookupValue :: Environment -> Qualified Ident -> Maybe (Type, NameKind, NameVisibility)
269lookupValue env (Qualified (Just mn) ident) = (mn, ident) `M.lookup` names env
270lookupValue _ _ = Nothing
272$(deriveJSON (defaultOptions { sumEncoding = ObjectWithSingleField }) ''TypeKind)
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