diff options
author | Csaba Hruska <csaba.hruska@gmail.com> | 2017-05-29 01:37:38 -0600 |
---|---|---|
committer | Csaba Hruska <csaba.hruska@gmail.com> | 2017-05-29 01:37:38 -0600 |
commit | ae21f6e3b50ce07e31bfde3ff55302aa812c2e7f (patch) | |
tree | 441ff21e2243c56ec814f36acf82b80001b0cf8c | |
parent | 7fd48262bde5664d1c543a45be948e0f22d18bd7 (diff) |
export list and type signatures
-rw-r--r-- | src/LambdaCube/Compiler/Patterns.hs | 76 |
1 files changed, 73 insertions, 3 deletions
diff --git a/src/LambdaCube/Compiler/Patterns.hs b/src/LambdaCube/Compiler/Patterns.hs index df166dd2..a354ccf3 100644 --- a/src/LambdaCube/Compiler/Patterns.hs +++ b/src/LambdaCube/Compiler/Patterns.hs | |||
@@ -13,7 +13,41 @@ | |||
13 | {-# LANGUAGE DeriveFunctor #-} | 13 | {-# LANGUAGE DeriveFunctor #-} |
14 | {-# LANGUAGE ScopedTypeVariables #-} | 14 | {-# LANGUAGE ScopedTypeVariables #-} |
15 | {-# LANGUAGE MultiParamTypeClasses #-} | 15 | {-# LANGUAGE MultiParamTypeClasses #-} |
16 | module LambdaCube.Compiler.Patterns where | 16 | module LambdaCube.Compiler.Patterns |
17 | ( compileGuardTree | ||
18 | , compileGuardTrees | ||
19 | , compileGuardTrees' | ||
20 | , compilePatts | ||
21 | , compileCase | ||
22 | , GuardTrees | ||
23 | , ParPat | ||
24 | , pattern PVarSimp | ||
25 | , noGuards | ||
26 | , ParseCheck(..) | ||
27 | , getPVars | ||
28 | -- statements | ||
29 | , cHCons | ||
30 | , cHNil | ||
31 | -- parser | ||
32 | , ConsInfo | ||
33 | , PatList | ||
34 | , pattern PConSimp | ||
35 | , cSucc | ||
36 | , cZero | ||
37 | , cList | ||
38 | , cCons | ||
39 | , cNil | ||
40 | , cHList | ||
41 | , cTrue | ||
42 | , lLet | ||
43 | , guardNode' | ||
44 | , pattern PParens | ||
45 | , pattern PatTypeSimp | ||
46 | , pattern ParPat | ||
47 | , pattern ViewPatSimp | ||
48 | , pattern PWildcard | ||
49 | , patLam | ||
50 | ) where | ||
17 | 51 | ||
18 | import Data.Monoid | 52 | import Data.Monoid |
19 | import Data.Maybe | 53 | import Data.Maybe |
@@ -53,6 +87,7 @@ type ParPat = ParPat_ ConsInfo | |||
53 | -- parallel patterns like v@(f -> [])@(Just x) | 87 | -- parallel patterns like v@(f -> [])@(Just x) |
54 | data ParPat_ c = ParPat_ SI [Pat_ c] | 88 | data ParPat_ c = ParPat_ SI [Pat_ c] |
55 | 89 | ||
90 | pattern ParPat :: [Pat_ a] -> ParPat_ a | ||
56 | pattern ParPat ps <- ParPat_ _ ps | 91 | pattern ParPat ps <- ParPat_ _ ps |
57 | where ParPat ps = ParPat_ (foldMap sourceInfo ps) ps | 92 | where ParPat ps = ParPat_ (foldMap sourceInfo ps) ps |
58 | 93 | ||
@@ -68,13 +103,18 @@ instance PShow (ParPat_ a) where | |||
68 | ParPat [] -> text "_" | 103 | ParPat [] -> text "_" |
69 | ParPat ps -> foldr1 (DOp "@" (InfixR 11)) $ pShow <$> ps | 104 | ParPat ps -> foldr1 (DOp "@" (InfixR 11)) $ pShow <$> ps |
70 | 105 | ||
71 | 106 | pattern PWildcard :: SI -> ParPat_ a | |
72 | |||
73 | pattern PWildcard si = ParPat_ si [] | 107 | pattern PWildcard si = ParPat_ si [] |
108 | |||
109 | pattern PCon :: (SIName, c) -> [ParPat_ c] -> Pat_ c | ||
74 | pattern PCon n pp <- PCon_ _ n pp | 110 | pattern PCon n pp <- PCon_ _ n pp |
75 | where PCon n pp = PCon_ (sourceInfo (fst n) <> sourceInfo pp) n pp | 111 | where PCon n pp = PCon_ (sourceInfo (fst n) <> sourceInfo pp) n pp |
112 | |||
113 | pattern ViewPat :: SExp -> ParPat_ c -> Pat_ c | ||
76 | pattern ViewPat e pp <- ViewPat_ _ e pp | 114 | pattern ViewPat e pp <- ViewPat_ _ e pp |
77 | where ViewPat e pp = ViewPat_ (sourceInfo e <> sourceInfo pp) e pp | 115 | where ViewPat e pp = ViewPat_ (sourceInfo e <> sourceInfo pp) e pp |
116 | |||
117 | pattern PatType :: ParPat_ c -> SExp -> Pat_ c | ||
78 | pattern PatType pp e <- PatType_ _ pp e | 118 | pattern PatType pp e <- PatType_ _ pp e |
79 | where PatType pp e = PatType_ (sourceInfo e <> sourceInfo pp) pp e | 119 | where PatType pp e = PatType_ (sourceInfo e <> sourceInfo pp) pp e |
80 | --pattern SimpPats ps <- (traverse simpleParPat -> Just ps) | 120 | --pattern SimpPats ps <- (traverse simpleParPat -> Just ps) |
@@ -83,24 +123,38 @@ pattern PatType pp e <- PatType_ _ pp e | |||
83 | --simpleParPat (ParPat [p]) = Just p | 123 | --simpleParPat (ParPat [p]) = Just p |
84 | --simpleParPat _ = Nothing | 124 | --simpleParPat _ = Nothing |
85 | 125 | ||
126 | pattern PVarSimp :: SIName -> ParPat | ||
86 | pattern PVarSimp n = ParPat [PVar n] | 127 | pattern PVarSimp n = ParPat [PVar n] |
128 | |||
129 | pattern PConSimp :: (SIName, c) -> [ParPat_ c] -> ParPat_ c | ||
87 | pattern PConSimp n ps = ParPat [PCon n ps] | 130 | pattern PConSimp n ps = ParPat [PCon n ps] |
88 | --pattern PConSimp n ps = PCon n (SimpPats ps) | 131 | --pattern PConSimp n ps = PCon n (SimpPats ps) |
132 | |||
133 | pattern ViewPatSimp :: SExp -> ParPat -> ParPat | ||
89 | pattern ViewPatSimp e p = ParPat [ViewPat e p] | 134 | pattern ViewPatSimp e p = ParPat [ViewPat e p] |
135 | |||
136 | pattern PatTypeSimp :: ParPat -> SExp -> ParPat | ||
90 | pattern PatTypeSimp p t = ParPat [PatType p t] | 137 | pattern PatTypeSimp p t = ParPat [PatType p t] |
91 | 138 | ||
139 | pBuiltin :: FNameTag -> Either ((SName,Int),[(FNameTag,Int)]) Int -> [ParPat] -> ParPat | ||
92 | pBuiltin n ci ps = PConSimp (Tag n, left (second $ map $ first Tag) ci) ps | 140 | pBuiltin n ci ps = PConSimp (Tag n, left (second $ map $ first Tag) ci) ps |
93 | 141 | ||
142 | cTrue, cZero, cNil, cHNil :: ParPat | ||
94 | cTrue = pBuiltin FTrue (Left ((CaseName "'Bool", 0), [(FFalse, 0), (FTrue, 0)])) [] | 143 | cTrue = pBuiltin FTrue (Left ((CaseName "'Bool", 0), [(FFalse, 0), (FTrue, 0)])) [] |
95 | cZero = pBuiltin FZero (Left ((CaseName "'Nat", 0), [(FZero, 0), (FSucc, 1)])) [] | 144 | cZero = pBuiltin FZero (Left ((CaseName "'Nat", 0), [(FZero, 0), (FSucc, 1)])) [] |
96 | cNil = pBuiltin FNil (Left ((CaseName "'List", 0), [(FNil, 0), (FCons, 2)])) [] | 145 | cNil = pBuiltin FNil (Left ((CaseName "'List", 0), [(FNil, 0), (FCons, 2)])) [] |
97 | cHNil = pBuiltin FHNil (Left (("hlistNilCase", -1), [(FHNil, 0)])) [] | 146 | cHNil = pBuiltin FHNil (Left (("hlistNilCase", -1), [(FHNil, 0)])) [] |
147 | |||
148 | cList, cHList, cSucc :: ParPat -> ParPat | ||
98 | cList a = pBuiltin F'List (Right 1) [a] | 149 | cList a = pBuiltin F'List (Right 1) [a] |
99 | cHList a = pBuiltin F'HList (Right 1) [a] | 150 | cHList a = pBuiltin F'HList (Right 1) [a] |
100 | cSucc a = pBuiltin FSucc (Left ((CaseName "'Nat", 0), [(FZero, 0), (FSucc, 1)])) [a] | 151 | cSucc a = pBuiltin FSucc (Left ((CaseName "'Nat", 0), [(FZero, 0), (FSucc, 1)])) [a] |
152 | |||
153 | cCons, cHCons :: ParPat -> ParPat -> ParPat | ||
101 | cCons a b = pBuiltin FCons (Left ((CaseName "'List", 0), [(FNil, 0), (FCons, 2)])) [a, b] | 154 | cCons a b = pBuiltin FCons (Left ((CaseName "'List", 0), [(FNil, 0), (FCons, 2)])) [a, b] |
102 | cHCons a b = pBuiltin FHCons (Left (("hlistConsCase", -1), [(FHCons, 2)])) [a, b] | 155 | cHCons a b = pBuiltin FHCons (Left (("hlistConsCase", -1), [(FHCons, 2)])) [a, b] |
103 | 156 | ||
157 | pattern PParens :: ParPat -> ParPat | ||
104 | pattern PParens p = ViewPatSimp (SBuiltin Fparens) p | 158 | pattern PParens p = ViewPatSimp (SBuiltin Fparens) p |
105 | 159 | ||
106 | mapP :: (Int -> SExp -> SExp) -> Int -> Pat -> Pat | 160 | mapP :: (Int -> SExp -> SExp) -> Int -> Pat -> Pat |
@@ -110,9 +164,11 @@ mapP f i = \case | |||
110 | ViewPat_ si e p -> ViewPat_ si (f i e) (mapPP f i p) | 164 | ViewPat_ si e p -> ViewPat_ si (f i e) (mapPP f i p) |
111 | PatType_ si p t -> PatType_ si (mapPP f i p) (f i t) | 165 | PatType_ si p t -> PatType_ si (mapPP f i p) (f i t) |
112 | 166 | ||
167 | mapPP :: (Int -> SExp -> SExp) -> Int -> ParPat_ ConsInfo -> ParPat_ ConsInfo | ||
113 | mapPP f i = \case | 168 | mapPP f i = \case |
114 | ParPat_ si ps -> ParPat_ si $ upPats (mapP f) i ps | 169 | ParPat_ si ps -> ParPat_ si $ upPats (mapP f) i ps |
115 | 170 | ||
171 | --upPats :: _ | ||
116 | upPats g k [] = [] | 172 | upPats g k [] = [] |
117 | upPats g k (p: ps) = g k p: upPats g (k + patVars p) ps | 173 | upPats g k (p: ps) = g k p: upPats g (k + patVars p) ps |
118 | 174 | ||
@@ -181,13 +237,16 @@ runPMC si vt m = do | |||
181 | where | 237 | where |
182 | (a, (ps, rs)) = runWriter m | 238 | (a, (ps, rs)) = runWriter m |
183 | 239 | ||
240 | --mkPatt_ :: _ | ||
184 | mkPatt_ ps_ is = (ps, mkGuards 0 ps_) | 241 | mkPatt_ ps_ is = (ps, mkGuards 0 ps_) |
185 | where | 242 | where |
186 | (mconcat -> qs, ps) = unzip $ map (mkPatt 0 ps_) is | 243 | (mconcat -> qs, ps) = unzip $ map (mkPatt 0 ps_) is |
187 | 244 | ||
245 | --mkGuards :: _ | ||
188 | mkGuards k [] = [] | 246 | mkGuards k [] = [] |
189 | mkGuards k ((q, (cn, n, e)): ps) = [(PConSimp (cn, ()) $ replicate n $ PWildcard mempty, e) | q `Set.notMember` qs] ++ mkGuards (k + n) ps | 247 | mkGuards k ((q, (cn, n, e)): ps) = [(PConSimp (cn, ()) $ replicate n $ PWildcard mempty, e) | q `Set.notMember` qs] ++ mkGuards (k + n) ps |
190 | 248 | ||
249 | --mkPatt :: _ | ||
191 | mkPatt k ((q, (cn, n, SVar _ j)): ps) i | j == (i + k) | 250 | mkPatt k ((q, (cn, n, SVar _ j)): ps) i | j == (i + k) |
192 | = (Set.singleton q <>) . mconcat *** PConSimp (cn, ()) $ unzip [mkPatt 0 ps l | l <- [n-1, n-2..0]] | 251 | = (Set.singleton q <>) . mconcat *** PConSimp (cn, ()) $ unzip [mkPatt 0 ps l | l <- [n-1, n-2..0]] |
193 | mkPatt k ((q, (cn, n, _)): ps) i = mkPatt (k + n) ps i | 252 | mkPatt k ((q, (cn, n, _)): ps) i = mkPatt (k + n) ps i |
@@ -199,14 +258,17 @@ data Lets a | |||
199 | | LTypeAnn SExp (Lets a) -- TODO: eliminate if not used | 258 | | LTypeAnn SExp (Lets a) -- TODO: eliminate if not used |
200 | | In a | 259 | | In a |
201 | 260 | ||
261 | lLet :: Rearrange a => SIName -> SExp' Void -> Lets a -> Lets a | ||
202 | lLet sn (SVar sn' i) l = rSubst 0 i l | 262 | lLet sn (SVar sn' i) l = rSubst 0 i l |
203 | lLet sn e l = LLet sn e l | 263 | lLet sn e l = LLet sn e l |
204 | 264 | ||
265 | foldLets :: (a -> b) -> Lets a -> b | ||
205 | foldLets f = \case | 266 | foldLets f = \case |
206 | In e -> f e | 267 | In e -> f e |
207 | LLet sn e x -> foldLets f x | 268 | LLet sn e x -> foldLets f x |
208 | LTypeAnn e x -> foldLets f x | 269 | LTypeAnn e x -> foldLets f x |
209 | 270 | ||
271 | --mapLets :: _ | ||
210 | mapLets f h l = \case | 272 | mapLets f h l = \case |
211 | In e -> In $ h l e | 273 | In e -> In $ h l e |
212 | LLet sn e x -> LLet sn (f l e) $ mapLets f h (l+1) x | 274 | LLet sn e x -> LLet sn (f l e) $ mapLets f h (l+1) x |
@@ -236,6 +298,7 @@ instance Monoid GuardTrees where | |||
236 | In GTFailure `mappend` y = y | 298 | In GTFailure `mappend` y = y |
237 | x@(In GTSuccess{}) `mappend` _ = x | 299 | x@(In GTSuccess{}) `mappend` _ = x |
238 | 300 | ||
301 | noGuards :: SExp -> GuardTrees | ||
239 | noGuards = In . GTSuccess | 302 | noGuards = In . GTSuccess |
240 | 303 | ||
241 | mapGT :: (Int -> ParPat -> ParPat) -> (Int -> SExp -> SExp) -> Int -> GuardTree -> GuardTree | 304 | mapGT :: (Int -> ParPat -> ParPat) -> (Int -> SExp -> SExp) -> Int -> GuardTree -> GuardTree |
@@ -244,6 +307,7 @@ mapGT f h k = \case | |||
244 | GTSuccess e -> GTSuccess $ h k e | 307 | GTSuccess e -> GTSuccess $ h k e |
245 | GTFailure -> GTFailure | 308 | GTFailure -> GTFailure |
246 | 309 | ||
310 | mapGTs :: (Int -> ParPat -> ParPat) -> (Int -> SExp -> SExp) -> Int -> GuardTrees -> GuardTrees | ||
247 | mapGTs f h = mapLets h (mapGT f h) | 311 | mapGTs f h = mapLets h (mapGT f h) |
248 | {- | 312 | {- |
249 | foldGT f = \case | 313 | foldGT f = \case |
@@ -254,6 +318,7 @@ foldGT f = \case | |||
254 | instance Rearrange GuardTree where | 318 | instance Rearrange GuardTree where |
255 | rearrange l f = mapGT (`rearrange` f) (`rearrange` f) l | 319 | rearrange l f = mapGT (`rearrange` f) (`rearrange` f) l |
256 | 320 | ||
321 | pattern Otherwise :: SExp' Void | ||
257 | pattern Otherwise = SBuiltin Fotherwise | 322 | pattern Otherwise = SBuiltin Fotherwise |
258 | 323 | ||
259 | guardNode :: Pat -> SExp -> GuardTrees -> GuardTrees | 324 | guardNode :: Pat -> SExp -> GuardTrees -> GuardTrees |
@@ -266,12 +331,14 @@ guardNode (PCon sn ps) e gt = In $ GuardNode e sn (replicate n $ dummyName "gn") | |||
266 | where | 331 | where |
267 | n = length ps | 332 | n = length ps |
268 | 333 | ||
334 | guardNode' :: ParPat_ ConsInfo -> SExp -> GuardTrees -> GuardTrees | ||
269 | guardNode' (PParens p) e gt = guardNode' p e gt | 335 | guardNode' (PParens p) e gt = guardNode' p e gt |
270 | guardNode' (ParPat_ si ps) e gt = case ps of | 336 | guardNode' (ParPat_ si ps) e gt = case ps of |
271 | [] -> gt | 337 | [] -> gt |
272 | [p] -> guardNode p e gt | 338 | [p] -> guardNode p e gt |
273 | ps -> lLet (SIName si "gtc") e $ buildNode guardNode 1 ps [0..] gt | 339 | ps -> lLet (SIName si "gtc") e $ buildNode guardNode 1 ps [0..] gt |
274 | 340 | ||
341 | --buildNode :: _ | ||
275 | buildNode guardNode n ps is gt | 342 | buildNode guardNode n ps is gt |
276 | = foldr f (rUp n (patVars ps) gt) $ zip3 ps is $ scanl (+) 0 $ map patVars ps | 343 | = foldr f (rUp n (patVars ps) gt) $ zip3 ps is $ scanl (+) 0 $ map patVars ps |
277 | where | 344 | where |
@@ -334,10 +401,13 @@ compileGuardTree ulend lend si vt = fmap (\e -> foldr (uncurry SLam) e vt) . run | |||
334 | su = length ps | 401 | su = length ps |
335 | In x -> In x | 402 | In x -> In x |
336 | 403 | ||
404 | compileGuardTrees :: MonadWriter [ParseCheck] m => (SExp -> SExp) -> Maybe SIName -> [(Visibility, SExp)] -> [GuardTrees] -> m SExp | ||
337 | compileGuardTrees ulend si vt = compileGuardTree ulend SRHS si vt . mconcat | 405 | compileGuardTrees ulend si vt = compileGuardTree ulend SRHS si vt . mconcat |
338 | 406 | ||
407 | compileGuardTrees' :: (Traversable t, MonadWriter [ParseCheck] m) => a -> [(Visibility, SExp)] -> t GuardTrees -> m (SExp' Void) | ||
339 | compileGuardTrees' si vt = fmap (foldr1 $ SAppV2 $ SBuiltin FparEval `SAppV` Wildcard SType) . mapM (compileGuardTrees id Nothing vt . (:[])) | 408 | compileGuardTrees' si vt = fmap (foldr1 $ SAppV2 $ SBuiltin FparEval `SAppV` Wildcard SType) . mapM (compileGuardTrees id Nothing vt . (:[])) |
340 | 409 | ||
410 | compileCase :: MonadWriter [ParseCheck] m => SExp' Void -> [(ParPat, GuardTrees)] -> m (SExp' Void) | ||
341 | compileCase x cs | 411 | compileCase x cs |
342 | = (`SAppV` x) <$> compileGuardTree id id (Just $ SIName (sourceInfo x) "") [(Visible, Wildcard SType)] (mconcat [compilePatts [p] e | (p, e) <- cs]) | 412 | = (`SAppV` x) <$> compileGuardTree id id (Just $ SIName (sourceInfo x) "") [(Visible, Wildcard SType)] (mconcat [compilePatts [p] e | (p, e) <- cs]) |
343 | 413 | ||