@@ -3,103 +3,102 @@ module Type.Constrain.Expression where
33
44import Control.Applicative ((<$>))
55import qualified Control.Monad as Monad
6−import Control.Monad.Error
76import qualified Data.List as List
87import qualified Data.Map as Map
9−import Prelude hiding (and)
10−import qualified Text.PrettyPrint as PP
118
12−import qualified AST.Literal as Lit
13−import AST.Annotation as Ann
14−import AST.Expression.General
9+import qualified AST.Expression.General as E
1510import qualified AST.Expression.Canonical as Canonical
11+import qualified AST.Literal as Lit
1612import qualified AST.Pattern as P
1713import qualified AST.Type as ST
1814import qualified AST.Variable as V
19−import Type.Type hiding (Descriptor(..))
20−import qualified Type.Fragment as Fragment
21−import qualified Type.Environment as Env
15+import qualified Reporting.Annotation as A
2216import qualified Type.Constrain.Literal as Literal
2317import qualified Type.Constrain.Pattern as Pattern
18+import qualified Type.Environment as Env
19+import qualified Type.Fragment as Fragment
20+import Type.Type hiding (Descriptor(..))
2421
2522
2623constrain
2724 :: Env.Environment
2825 -> Canonical.Expr
2926 -> Type
30− -> ErrorT [PP.Doc] IO TypeConstraint
31−constrain env (A region expression) tipe =
27+ -> IO TypeConstraint
28+constrain env (A.A region expression) tipe =
3229 let list t = Env.get env Env.types "List" <| t
33− and = A region . CAnd
34− true = A region CTrue
35− t1 === t2 = A region (CEqual t1 t2)
36− x <? t = A region (CInstance x t)
37− clet schemes c = A region (CLet schemes c)
30+ (===) = CEqual region
31+ (<?) = CInstance region
3832 in
3933 case expression of
40− Literal lit ->
41− liftIO $ Literal.constrain env region lit tipe
34+ E.Literal lit ->
35+ Literal.constrain env region lit tipe
4236
43− GLShader _uid _src gltipe ->
37+ E.GLShader _uid _src gltipe ->
4438 exists $ \attr ->
4539 exists $ \unif ->
4640 let
47− shaderTipe a u v = Env.get env Env.types "WebGL.Shader" <| a <| u <| v
48− glTipe = Env.get env Env.types . Lit.glTipeName
49− makeRec accessor baseRec =
50− let decls = accessor gltipe
51− in if Map.size decls == 0
52− then baseRec
53− else record (Map.map (\t -> [glTipe t]) decls) baseRec
54− attribute = makeRec Lit.attribute attr
55− uniform = makeRec Lit.uniform unif
56− varying = makeRec Lit.varying (termN EmptyRecord1)
41+ shaderTipe a u v =
42+ Env.get env Env.types "WebGL.Shader" <| a <| u <| v
43+
44+ glTipe =
45+ Env.get env Env.types . Lit.glTipeName
46+
47+ makeRec accessor baseRec =
48+ let decls = accessor gltipe
49+ in
50+ if Map.size decls == 0
51+ then baseRec
52+ else record (Map.map (\t -> [glTipe t]) decls) baseRec
53+
54+ attribute = makeRec Lit.attribute attr
55+ uniform = makeRec Lit.uniform unif
56+ varying = makeRec Lit.varying (termN EmptyRecord1)
5757 in
58− return . A region $ CEqual tipe (shaderTipe attribute uniform varying)
58+ return (tipe === shaderTipe attribute uniform varying)
5959
60− Var var
61− | name == saveEnvName -> return (A region CSaveEnv)
62− | otherwise -> return (name <? tipe)
63− where
64− name = V.toString var
60+ E.Var var ->
61+ let name = V.toString var
62+ in
63+ return (if name == E.saveEnvName then CSaveEnv else name <? tipe)
6564
66− Range lo hi ->
65+ E.Range lo hi ->
6766 existsNumber $ \n ->
6867 do clo <- constrain env lo n
6968 chi <- constrain env hi n
70− return $ and [clo, chi, list n === tipe]
69+ return $ CAnd [clo, chi, list n === tipe]
7170
72− ExplicitList exprs ->
71+ E.ExplicitList exprs ->
7372 exists $ \x ->
7473 do constraints <- mapM (\e -> constrain env e x) exprs
75− return . and $ list x === tipe : constraints
74+ return $ CAnd (list x === tipe : constraints)
7675
77− Binop op e1 e2 ->
76+ E.Binop op e1 e2 ->
7877 exists $ \t1 ->
7978 exists $ \t2 ->
8079 do c1 <- constrain env e1 t1
8180 c2 <- constrain env e2 t2
82− return $ and [ c1, c2, V.toString op <? (t1 ==> t2 ==> tipe) ]
81+ return $ CAnd [ c1, c2, V.toString op <? (t1 ==> t2 ==> tipe) ]
8382
84− Lambda p e ->
83+ E.Lambda pattern body ->
8584 exists $ \t1 ->
8685 exists $ \t2 ->
87− do fragment <- try region $ Pattern.constrain env p t1
88− c2 <- constrain env e t2
86+ do fragment <- Pattern.constrain env pattern t1
87+ c2 <- constrain env body t2
8988 let c = ex (Fragment.vars fragment)
90− (clet [monoscheme (Fragment.typeEnv fragment)]
89+ (CLet [monoscheme (Fragment.typeEnv fragment)]
9190 (Fragment.typeConstraint fragment /\ c2)
9291 )
9392 return $ c /\ tipe === (t1 ==> t2)
9493
95− App e1 e2 ->
94+ E.App e1 e2 ->
9695 exists $ \t ->
9796 do c1 <- constrain env e1 (t ==> tipe)
9897 c2 <- constrain env e2 t
9998 return $ c1 /\ c2
10099
101− MultiIf branches ->
102− and <$> mapM constrain' branches
100+ E.MultiIf branches ->
101+ CAnd <$> mapM constrain' branches
103102 where
104103 bool = Env.get env Env.types "Bool"
105104
@@ -108,107 +107,116 @@ constrain env (A region expression) tipe =
108107 ce <- constrain env expr tipe
109108 return (cb /\ ce)
110109
111− Case expr branches ->
110+ E.Case expr branches ->
112111 exists $ \t ->
113− do ce <- constrain env expr t
114− and . (:) ce <$> mapM (branch t) branches
112+ do exprConstraint <- constrain env expr t
113+ branchConstraints <- mapM (branch t) branches
114+ return (CAnd (exprConstraint : branchConstraints))
115115 where
116116 branch t (pattern, branchExpr) =
117− do fragment <- try region $ Pattern.constrain env pattern t
118− clet [Fragment.toScheme fragment] <$> constrain env branchExpr tipe
117+ do fragment <- Pattern.constrain env pattern t
118+ CLet [Fragment.toScheme fragment] <$> constrain env branchExpr tipe
119119
120− Data name exprs ->
121− do vars <- forM exprs $ \_ -> liftIO (variable Flexible)
120+ E.Data name exprs ->
121+ do vars <- Monad.forM exprs $ \_ -> variable Flexible
122122 let pairs = zip exprs (map varN vars)
123− (ctipe, cs) <- Monad.foldM step (tipe,true) (reverse pairs)
123+ (ctipe, cs) <- Monad.foldM step (tipe, CTrue) (reverse pairs)
124124 return $ ex vars (cs /\ name <? ctipe)
125125 where
126126 step (t,c) (e,x) =
127127 do c' <- constrain env e x
128128 return (x ==> t, c /\ c')
129129
130− Access expr label ->
130+ E.Access expr label ->
131131 exists $ \t ->
132132 constrain env expr (record (Map.singleton label [tipe]) t)
133133
134− Remove expr label ->
134+ E.Remove expr label ->
135135 exists $ \t ->
136136 constrain env expr (record (Map.singleton label [t]) tipe)
137137
138− Insert expr label value ->
138+ E.Insert expr label value ->
139139 exists $ \tVal ->
140140 exists $ \tRec ->
141141 do cVal <- constrain env value tVal
142142 cRec <- constrain env expr tRec
143143 let c = tipe === record (Map.singleton label [tVal]) tRec
144− return (and [cVal, cRec, c])
144+ return (CAnd [cVal, cRec, c])
145145
146− Modify expr fields ->
146+ E.Modify expr fields ->
147147 exists $ \t ->
148− do oldVars <- forM fields $ \_ -> liftIO (variable Flexible)
148+ do oldVars <- Monad.forM fields $ \_ -> variable Flexible
149149 let oldFields = ST.fieldMap (zip (map fst fields) (map varN oldVars))
150150 cOld <- ex oldVars <$> constrain env expr (record oldFields t)
151151
152− newVars <- forM fields $ \_ -> liftIO (variable Flexible)
152+ newVars <- Monad.forM fields $ \_ -> variable Flexible
153153 let newFields = ST.fieldMap (zip (map fst fields) (map varN newVars))
154154 let cNew = tipe === record newFields t
155155
156− cs <- zipWithM (constrain env) (map snd fields) (map varN newVars)
156+ cs <- Monad.zipWithM (constrain env) (map snd fields) (map varN newVars)
157157
158− return $ cOld /\ ex newVars (and (cNew : cs))
158+ return $ cOld /\ ex newVars (CAnd (cNew : cs))
159159
160− Record fields ->
161− do vars <- forM fields $ \_ -> liftIO (variable Flexible)
162− cs <- zipWithM (constrain env) (map snd fields) (map varN vars)
160+ E.Record fields ->
161+ do vars <- Monad.forM fields $ \_ -> variable Flexible
162+ cs <- Monad.zipWithM (constrain env) (map snd fields) (map varN vars)
163163 let fields' = ST.fieldMap (zip (map fst fields) (map varN vars))
164164 let recordType = record fields' (termN EmptyRecord1)
165− return . ex vars . and $ tipe === recordType : cs
165+ return . ex vars . CAnd $ tipe === recordType : cs
166166
167− Let defs body ->
167+ E.Let defs body ->
168168 do c <- constrain env body tipe
169169
170170 (Info schemes rqs fqs headers c2 c1) <-
171171 Monad.foldM
172172 (constrainDef env)
173− (Info [] [] [] Map.empty true true)
173+ (Info [] [] [] Map.empty CTrue CTrue)
174174 (concatMap expandPattern defs)
175175
176− let letScheme = [ Scheme rqs fqs (clet [monoscheme headers] c2) headers ]
176+ let letScheme = [ Scheme rqs fqs (CLet [monoscheme headers] c2) headers ]
177177
178− return $ clet schemes (clet letScheme (c1 /\ c))
178+ return $ CLet schemes (CLet letScheme (c1 /\ c))
179179
180− Port impl ->
180+ E.Port impl ->
181181 case impl of
182− In _ _ ->
183− return true
182+ E.In _ _ ->
183+ return CTrue
184184
185− Out _ expr _ ->
185+ E.Out _ expr _ ->
186186 constrain env expr tipe
187187
188− Task _ expr _ ->
188+ E.Task _ expr _ ->
189189 constrain env expr tipe
190190
191191
192192expandPattern :: Canonical.Def -> [Canonical.Def]
193−expandPattern def@(Canonical.Definition pattern lexpr@(A r _) maybeType) =
194− case pattern of
195− P.Var _ ->
196− [def]
197− _ ->
198− Canonical.Definition (P.Var x) lexpr maybeType : map toDef vars
199− where
200− vars = P.boundVarList pattern
201− x = "$" ++ concat vars
202− mkVar = A r . localVar
203− toDef y = Canonical.Definition (P.Var y) (A r $ Case (mkVar x) [(pattern, mkVar y)]) Nothing
193+expandPattern def@(Canonical.Definition lpattern expr maybeType) =
194+ let (A.A patternRegion pattern) = lpattern
195+ in
196+ case pattern of
197+ P.Var _ ->
198+ [def]
199+
200+ _ ->
201+ mainDef : map toDef vars
202+ where
203+ vars = P.boundVarList lpattern
204204
205+ combinedName = "$" ++ concat vars
205206
206−try :: Region -> ErrorT (Region -> PP.Doc) IO a -> ErrorT [PP.Doc] IO a
207−try region computation =
208− do result <- liftIO $ runErrorT computation
209− case result of
210− Left err -> throwError [err region]
211− Right value -> return value
207+ pvar name =
208+ A.A patternRegion (P.Var name)
209+
210+ localVar name =
211+ A.A patternRegion (E.localVar name)
212+
213+ mainDef = Canonical.Definition (pvar combinedName) expr maybeType
214+
215+ toDef name =
216+ let extract =
217+ E.Case (localVar combinedName) [(lpattern, localVar name)]
218+ in
219+ Canonical.Definition (pvar name) (A.A patternRegion extract) Nothing
212220
213221
214222-- CONSTRAIN DEFINITIONS
@@ -223,8 +231,8 @@ data Info = Info
223231 }
224232
225233
226−constrainDef :: Env.Environment -> Info -> Canonical.Def -> ErrorT [PP.Doc] IO Info
227−constrainDef env info (Canonical.Definition pattern expr maybeTipe) =
234+constrainDef :: Env.Environment -> Info -> Canonical.Def -> IO Info
235+constrainDef env info (Canonical.Definition (A.A _ pattern) expr maybeTipe) =
228236 let qs = [] -- should come from the def, but I'm not sure what would live there...
229237 in
230238 case (pattern, maybeTipe) of
@@ -243,13 +251,13 @@ constrainAnnotatedDef
243251 -> [String]
244252 -> String
245253 -> Canonical.Expr
246− -> ST.CanonicalType
247− -> ErrorT [PP.Doc] IO Info
254+ -> ST.Canonical
255+ -> IO Info
248256constrainAnnotatedDef env info qs name expr tipe =
249257 do -- Some mistake may be happening here. Currently, qs is always [].
250− rigidVars <- forM qs (\_ -> liftIO $ variable Rigid)
258+ rigidVars <- Monad.forM qs (\_ -> variable Rigid)
251259
252− flexiVars <- forM qs (\_ -> liftIO $ variable Flexible)
260+ flexiVars <- Monad.forM qs (\_ -> variable Flexible)
253261
254262 let inserts = zipWith (\arg typ -> Map.insert arg (varN typ)) qs flexiVars
255263
@@ -261,7 +269,7 @@ constrainAnnotatedDef env info qs name expr tipe =
261269 Scheme
262270 { rigidQuantifiers = []
263271 , flexibleQuantifiers = flexiVars ++ vars
264− , constraint = Ann.noneNoDocs CTrue
272+ , constraint = CTrue
265273 , header = Map.singleton name typ
266274 }
267275
@@ -279,12 +287,12 @@ constrainUnannotatedDef
279287 -> [String]
280288 -> String
281289 -> Canonical.Expr
282− -> ErrorT [PP.Doc] IO Info
290+ -> IO Info
283291constrainUnannotatedDef env info qs name expr =
284292 do -- Some mistake may be happening here. Currently, qs is always [].
285− rigidVars <- forM qs (\_ -> liftIO $ variable Rigid)
293+ rigidVars <- Monad.forM qs (\_ -> variable Rigid)
286294
287− v <- liftIO $ variable Flexible
295+ v <- variable Flexible
288296
289297 let tipe = varN v
290298