git.iko.soy/rowtype-yoga/purescript-native
on ae8cfaa help sign in
272 lines 7.2 kB history raw
1-----------------------------------------------------------------------------
2--
3-- Module : Language.PureScript.Environment
4-- Copyright : (c) 2013-14 Phil Freeman, (c) 2014 Gary Burgess, and other contributors
5-- License : MIT
6--
7-- Maintainer : Phil Freeman <paf31@cantab.net>
8-- Stability : experimental
9-- Portability :
10--
11-- |
12--
13-----------------------------------------------------------------------------
15{-# LANGUAGE DeriveDataTypeable #-}
16{-# LANGUAGE OverloadedStrings #-}
17{-# LANGUAGE TemplateHaskell #-}
19module Language.PureScript.Environment where
21import Data.Data
22import Data.Maybe (fromMaybe)
23import Data.Aeson.TH
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
34-- |
35-- The @Environment@ defines all values and types which are currently in scope:
36--
37data Environment = Environment {
38 -- |
39 -- Value names currently in scope
40 --
41 names :: M.Map (ModuleName, Ident) (Type, NameKind, NameVisibility)
42 -- |
43 -- Type names currently in scope
44 --
45 , types :: M.Map (Qualified ProperName) (Kind, TypeKind)
46 -- |
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])
50 -- |
51 -- Type synonyms currently in scope
52 --
53 , typeSynonyms :: M.Map (Qualified ProperName) ([(String, Maybe Kind)], Type)
54 -- |
55 -- Available type class dictionaries
56 --
57 , typeClassDictionaries :: M.Map (Maybe ModuleName) (M.Map (Qualified ProperName) (M.Map (Qualified Ident) TypeClassDictionaryInScope))
58 -- |
59 -- Type classes
60 --
61 , typeClasses :: M.Map (Qualified ProperName) ([(String, Maybe Kind)], [(Ident, Type)], [Constraint])
62 } deriving (Show, Read)
64-- |
65-- The initial environment with no values and only the default javascript types defined
66--
67initEnvironment :: Environment
68initEnvironment = Environment M.empty primTypes M.empty M.empty M.empty M.empty
70-- |
71-- The visibility of a name in scope
72--
73data NameVisibility
74 -- |
75 -- The name is defined in the current binding group, but is not visible
76 --
77 = Undefined
78 -- |
79 -- The name is defined in the another binding group, or has been made visible by a function binder
80 --
81 | Defined deriving (Show, Read, Eq)
83-- |
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.
86--
87data NameKind
88 -- |
89 -- A private value introduced as an artifact of code generation (class instances, class member
90 -- accessors, etc.)
91 --
92 = Private
93 -- |
94 -- A public value for a module member or foreing import declaration
95 --
96 | Public
97 -- |
98 -- A name for member introduced by foreign import
99 --
100 | External deriving (Show, Read, Eq, Data, Typeable)
102-- |
103-- The kinds of a type
104--
105data TypeKind
106 -- |
107 -- Data type
108 --
109 = DataType [(String, Maybe Kind)] [(ProperName, [Type])]
110 -- |
111 -- Type synonym
112 --
113 | TypeSynonym
114 -- |
115 -- Foreign data
116 --
117 | ExternData
118 -- |
119 -- A local type variable
120 --
121 | LocalTypeVariable
122 -- |
123 -- A scoped type variable
124 --
125 | ScopedTypeVar
126 deriving (Show, Read, Eq, Data, Typeable)
128-- |
129-- The type ('data' or 'newtype') of a data type declaration
130--
131data DataDeclType
132 -- |
133 -- A standard data constructor
134 --
135 = Data
136 -- |
137 -- A newtype constructor
138 --
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 ->
150 case str of
151 "data" -> return Data
152 "newtype" -> return Newtype
153 other -> fail $ "invalid type: '" ++ T.unpack other ++ "'"
155-- |
156-- Construct a ProperName in the Prim module
157--
158primName :: String -> Qualified ProperName
159primName = Qualified (Just $ ModuleName [ProperName C.prim]) . ProperName
161-- |
162-- Construct a type in the Prim module
163--
164primTy :: String -> Type
165primTy = TypeConstructor . primName
167-- |
168-- Type constructor for functions
169--
170tyFunction :: Type
171tyFunction = primTy "Function"
173-- |
174-- Type constructor for strings
175--
176tyString :: Type
177tyString = primTy "String"
179-- |
180-- Type constructor for strings
181--
182tyChar :: Type
183tyChar = primTy "Char"
185-- |
186-- Type constructor for numbers
187--
188tyNumber :: Type
189tyNumber = primTy "Number"
191-- |
192-- Type constructor for integers
193--
194tyInt :: Type
195tyInt = primTy "Int"
197-- |
198-- Type constructor for booleans
199--
200tyBoolean :: Type
201tyBoolean = primTy "Boolean"
203-- |
204-- Type constructor for arrays
205--
206tyArray :: Type
207tyArray = primTy "Array"
209-- |
210-- Type constructor for objects
211--
212tyObject :: Type
213tyObject = primTy "Object"
215-- |
216-- Check whether a type is an object
217--
218isObject :: Type -> Bool
219isObject = isTypeOrApplied tyObject
221-- |
222-- Check whether a type is a function
223--
224isFunction :: Type -> Bool
225isFunction = isTypeOrApplied tyFunction
227isTypeOrApplied :: Type -> Type -> Bool
228isTypeOrApplied t1 (TypeApp t2 _) = t1 == t2
229isTypeOrApplied t1 t2 = t1 == t2
231-- |
232-- Smart constructor for function types
233--
234function :: Type -> Type -> Type
235function t1 = TypeApp (TypeApp tyFunction t1)
237-- |
238-- The primitive types in the external javascript environment with their associated kinds.
239--
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)) ]
250-- |
251-- Finds information about data constructors from the current environment.
252--
253lookupConstructor :: Environment -> Qualified ProperName -> (DataDeclType, ProperName, Type, [Ident])
254lookupConstructor env ctor =
255 fromMaybe (error "Data constructor not found") $ ctor `M.lookup` dataConstructors env
257-- |
258-- Checks whether a data constructor is for a newtype.
259--
260isNewtypeConstructor :: Environment -> Qualified ProperName -> Bool
261isNewtypeConstructor e ctor = case lookupConstructor e ctor of
262 (Newtype, _, _, _) -> True
263 (Data, _, _, _) -> False
265-- |
266-- Finds information about values from the current environment.
267--
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)