2module Parse.Patterns (patternTerm, patternExpr, makeLambda, flattenPatterns) where
6import Control.Applicative ((<$>),(<*>),(*>),pure)
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
22asPattern :: IParser Pattern -> IParser Pattern
25 var <- optionMaybe (try (whitespace >> reserved "as" >> whitespace >> lowVar))
30patternRecord :: IParser Pattern
31patternRecord = PRecord <$> brackets (commaSep1 lowVar)
33patternTuple :: IParser Pattern
34patternTuple = do ps <- parens (commaSep patternExpr)
35 return $ case ps of { [p] -> p; _ -> ptuple ps }
37patternList :: IParser Pattern
38patternList = plist <$> braces (commaSep patternExpr)
40patternTerm :: IParser Pattern
41patternTerm = (choice [ patternRecord, patternTuple, patternList,
45patternConstructor :: IParser Pattern
46patternConstructor = PData <$> capVar <*> spacePrefix patternTerm
48patternExpr :: IParser Pattern
50 asPattern (foldr1 pcons <$> consSep1 (patternConstructor <|> patternTerm))
53makeLambda :: [Pattern] -> CExpr -> GuidCounter CExpr
54makeLambda pats body = go (reverse pats) body
55 where go [] body = return body
56 go (p:ps) body@(L t s _) = do
57 (x,e) <- extract p body
58 go ps (L t s $ Lambda x e)
60extract :: Pattern -> CExpr -> GuidCounter (String, CExpr)
61extract pattern body@(L t s _) =
65 PAnything -> return $ fn "_" body
66 PVar x -> return $ fn x body
67 PAsVar x PAnything -> return $ fn x body
69 (x', body') <- extract p body
70 return $ fn x (loc $ Let [FnDef x' [] (loc $ Var x)] body')
74 return . fn a . loc $ Case (loc (Var a)) [(pattern, body)]
78 toDef f = FnDef f [] (loc $ Access (loc $ Var a) f)
79 return . fn a . loc $ Let (map toDef fs) body
81extracts :: [Pattern] -> CExpr -> GuidCounter ([String], CExpr)
82extracts ps body = go [] (reverse ps) body
83 where go args [] body = return (args, body)
84 go args (p:ps) body = do (x,e) <- extract p body
87flattenPatterns :: [Pattern] -> CExpr -> GuidCounter (IParser [Def])
88flattenPatterns patterns exp@(L t s _) =
92 (as,e) <- extracts args exp
94 if isOp (head f) then let [a,b] = as in [ OpDef f a b e ]
97 [p] -> return `liftM` matchSingle p exp p
99 _ -> return . fail $ "Pattern (" ++ unwords (map show patterns) ++
100 ") cannot be used on the left-hand side of an assign statement."
102matchSingle :: Pattern -> CExpr -> Pattern -> GuidCounter [Def]
103matchSingle pat exp@(L t s _) p =
109 dss <- mapM (matchSingle pat . loc $ Var v) ps
110 return (FnDef v [] exp : concat dss)
113 return [ FnDef x [] (loc $ Case exp [(pat, loc $ Var x)]) ]
116 subPat <- matchSingle p' (loc $ Var x) p'
117 return $ (FnDef x [] (loc $ Case exp [(pat, loc $ Var x)])):subPat
120 a <- (\x -> '_' : show x) `liftM` guid
121 let toDef f = FnDef f [] (loc $ Access (loc $ Var a) f)
122 return (FnDef a [] exp : map toDef fs)
124 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