2module Parse.Patterns (patternTerm, patternExpr, makeLambda, flattenPatterns) where
6import Control.Applicative ((<$>),(<*>))
8import Control.Monad.State
9import Data.Char (isUpper)
11import Text.Parsec hiding (newline,spaces,State)
12import Text.Parsec.Indent
15patternBasic :: IParser Pattern
17 choice [ char '_' >> return PAnything
19 return $ if isUpper c then PData x [] else PVar x
22patternRecord :: IParser Pattern
23patternRecord = PRecord <$> brackets (commaSep1 lowVar)
25patternTuple :: IParser Pattern
26patternTuple = do ps <- parens (commaSep patternExpr)
27 return $ case ps of { [p] -> p; _ -> ptuple ps }
29patternList :: IParser Pattern
30patternList = plist <$> braces (commaSep patternExpr)
32patternTerm :: IParser Pattern
33patternTerm = choice [ patternRecord, patternTuple, patternList, patternBasic ]
36patternConstructor :: IParser Pattern
37patternConstructor = PData <$> capVar <*> spacePrefix patternTerm
39patternExpr :: IParser Pattern
40patternExpr = foldr1 pcons <$> consSep1 (patternConstructor <|> patternTerm) <?> "pattern"
42makeLambda :: [Pattern] -> CExpr -> GuidCounter CExpr
43makeLambda pats body = go (reverse pats) body
44 where go [] body = return body
45 go (p:ps) body@(C t s _) = do
46 (x,e) <- extract p body
47 go ps (C t s $ Lambda x e)
49extract :: Pattern -> CExpr -> GuidCounter (String, CExpr)
50extract pattern body@(C t s _) =
54 PAnything -> return $ fn "_" body
55 PVar x -> return $ fn x body
59 return . fn a . ctx $ Case (ctx (Var a)) [(pattern, body)]
63 toDef f = FnDef f [] (ctx $ Access (ctx $ Var a) f)
64 return . fn a . ctx $ Let (map toDef fs) body
66extracts :: [Pattern] -> CExpr -> GuidCounter ([String], CExpr)
67extracts ps body = go [] (reverse ps) body
68 where go args [] body = return (args, body)
69 go args (p:ps) body = do (x,e) <- extract p body
72flattenPatterns :: [Pattern] -> CExpr -> GuidCounter (IParser [Def])
73flattenPatterns patterns exp@(C t s _) =
77 (as,e) <- extracts args exp
79 if isOp (head f) then let [a,b] = as in [ OpDef f a b e ]
82 [p] -> return `liftM` matchSingle p exp p
84 _ -> return . fail $ "Pattern (" ++ unwords (map show patterns) ++
85 ") cannot be used on the left-hand side of an assign statement."
87matchSingle :: Pattern -> CExpr -> Pattern -> GuidCounter [Def]
88matchSingle pat exp@(C t s _) p =
91 PData _ ps -> do x <- guid
93 dss <- mapM (matchSingle pat . ctx $ Var v) ps
94 return (FnDef v [] exp : concat dss)
97 return [ FnDef x [] (ctx $ Case exp [(pat, ctx $ Var x)]) ]
100 a <- (\x -> '_' : show x) `liftM` guid
101 let toDef f = FnDef f [] (ctx $ Access (ctx $ Var a) f)
102 return (FnDef a [] exp : map toDef fs)
104 PAnything -> return []
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