never executed always true always false
    1 {-# LANGUAGE DataKinds #-}
    2 module Parse.Pattern (term, expr) where
    3 
    4 import Text.Parsec ((<|>), (<?>), char, choice, optionMaybe, try)
    5 
    6 import AST.V0_16
    7 import AST.Structure
    8 import qualified Data.Indexed as I
    9 import ElmVersion
   10 import Parse.Helpers
   11 import qualified Parse.Literal as Literal
   12 import Reporting.Annotation (Located)
   13 import qualified Reporting.Annotation as A
   14 import Parse.IParser
   15 import Parse.Whitespace
   16 
   17 
   18 basic :: ElmVersion -> IParser (ASTNS Located [UppercaseIdentifier] 'PatternNK)
   19 basic elmVersion =
   20   fmap I.Fix $ addLocation $
   21     choice
   22       [ char '_' >> return Anything
   23       , VarPattern <$> lowVar elmVersion
   24       , chunksToPattern <$> dotSep1 (capVar elmVersion)
   25       , LiteralPattern <$> Literal.literal
   26       ]
   27   where
   28     chunksToPattern chunks =
   29         case reverse chunks of
   30           [UppercaseIdentifier "True"] ->
   31               LiteralPattern (Boolean True)
   32 
   33           [UppercaseIdentifier "False"] ->
   34               LiteralPattern (Boolean False)
   35 
   36           (last:rest) ->
   37               DataPattern (reverse rest, last) []
   38 
   39           [] -> error "dotSep1 returned empty list"
   40 
   41 
   42 asPattern :: ElmVersion -> IParser (FixAST Located typeRef ctorRef varRef 'PatternNK) -> IParser (FixAST Located typeRef ctorRef varRef 'PatternNK)
   43 asPattern elmVersion patternParser =
   44   do  (start, pattern, _) <- located patternParser
   45 
   46       maybeAlias <- optionMaybe asAlias
   47 
   48       case maybeAlias of
   49         Just (postPattern, alias) ->
   50             do  end <- getMyPosition
   51                 return $ I.Fix $ A.at start end $ Alias (C postPattern pattern) alias
   52 
   53         Nothing ->
   54             return pattern
   55   where
   56     asAlias =
   57       do  preAs <- try (whitespace <* reserved elmVersion "as")
   58           postAs <- whitespace
   59           var <- lowVar elmVersion
   60           return (preAs, C postAs var)
   61 
   62 
   63 record :: ElmVersion -> IParser (FixAST Located typeRef ctorRef varRef 'PatternNK)
   64 record elmVersion =
   65   fmap I.Fix $ addLocation $
   66   do
   67       result <- surround'' '{' '}' (lowVar elmVersion)
   68       return $
   69           case result of
   70               Left comments ->
   71                   EmptyRecordPattern comments
   72               Right fields ->
   73                   RecordPattern fields
   74 
   75 
   76 tuple :: ElmVersion -> IParser (ASTNS Located [UppercaseIdentifier] 'PatternNK)
   77 tuple elmVersion =
   78   do  (start, patterns, end) <- located $ parens'' (expr elmVersion)
   79 
   80       return $
   81         case patterns of
   82           Left comments ->
   83             I.Fix $ A.at start end $ UnitPattern comments
   84 
   85           Right [] ->
   86             I.Fix $ A.at start end $ UnitPattern []
   87 
   88           Right [C ([], []) pattern] ->
   89             pattern
   90 
   91           Right [pattern] ->
   92             I.Fix $ A.at start end $ PatternParens pattern
   93 
   94           Right patterns ->
   95             I.Fix $ A.at start end $ TuplePattern patterns
   96 
   97 
   98 list :: ElmVersion -> IParser (ASTNS Located [UppercaseIdentifier] 'PatternNK)
   99 list elmVersion =
  100   fmap I.Fix $ addLocation $
  101   do
  102     result <- braces'' (expr elmVersion)
  103     return $
  104       case result of
  105         Left comments ->
  106           EmptyListPattern comments
  107         Right patterns ->
  108           ListPattern patterns
  109 
  110 
  111 term :: ElmVersion -> IParser (ASTNS Located [UppercaseIdentifier] 'PatternNK)
  112 term elmVersion =
  113   choice [ record elmVersion, tuple elmVersion, list elmVersion, basic elmVersion ]
  114     <?> "a pattern"
  115 
  116 
  117 patternConstructor :: ElmVersion -> IParser (ASTNS Located [UppercaseIdentifier] 'PatternNK)
  118 patternConstructor elmVersion =
  119   fmap I.Fix $ addLocation $
  120     do  v <- dotSep1 (capVar elmVersion)
  121         case reverse v of
  122           [UppercaseIdentifier "True"]  -> return $ LiteralPattern (Boolean True)
  123           [UppercaseIdentifier "False"] -> return $ LiteralPattern (Boolean False)
  124           (last:rest) -> DataPattern (reverse rest, last) <$> spacePrefix (term elmVersion)
  125           [] -> error "dotSep1 returned empty list"
  126 
  127 
  128 expr :: ElmVersion -> IParser (ASTNS Located [UppercaseIdentifier] 'PatternNK)
  129 expr elmVersion =
  130     asPattern elmVersion subPattern <?> "a pattern"
  131   where
  132     subPattern =
  133       do
  134         result <- separated cons (patternConstructor elmVersion <|> term elmVersion)
  135         return $
  136           case result of
  137             Left pattern ->
  138               pattern
  139             Right (region, first, rest, _) ->
  140               I.Fix $ A.A region $ ConsPattern first rest