diff options
Diffstat (limited to 'src/Haskell/SimpleParser.hs')
-rw-r--r-- | src/Haskell/SimpleParser.hs | 27 |
1 files changed, 19 insertions, 8 deletions
diff --git a/src/Haskell/SimpleParser.hs b/src/Haskell/SimpleParser.hs index 26308de..841e41c 100644 --- a/src/Haskell/SimpleParser.hs +++ b/src/Haskell/SimpleParser.hs @@ -22,7 +22,7 @@ pToplevel = TopDef <$> pDef pDef :: Parser Def pDef = do - n <- pNameV + n <- pVariable args <- many pNameV symbolO "=" ex <- pExpr @@ -34,8 +34,8 @@ pDef = do pExpr :: Parser Expr pExpr = pLam <|> pCase <|> pApp where - pSimpleExpr = choice [LitNum <$> pNum - ,Ref <$> (pName <|> try (parens pOperator)) + pSimpleExpr = choice [Num <$> pNum + ,Ref <$> pVariable ,parens (pExpr `sepBy` symbolO ",") >>= \case [ex] -> return ex exs -> return $ Tup exs] @@ -53,10 +53,10 @@ pExpr = pLam <|> pCase <|> pApp pCase = do symbolW "case" - n <- pNameV + e <- pExpr symbolW "of" arms <- braces (pCaseArm `sepBy` symbolO ";") - return $ Case n arms + return $ Case e arms pCaseArm = do pat <- pLargePat @@ -80,18 +80,26 @@ pNum :: Parser Integer pNum = (char '-' >> (negate <$> pPositive)) <|> pPositive where pPositive = read <$> many1 digit +pVariable :: Parser Name +pVariable = pName <|> try (parens pOperator) + pName :: Parser Name -pName = liftM2 (:) (satisfy isAlpha) pNameRest +pName = notReserved $ liftM2 (:) (satisfy isAlpha) pNameRest pNameV :: Parser Name -pNameV = liftM2 (:) (satisfy isLower) pNameRest +pNameV = notReserved $ liftM2 (:) (satisfy isLower) pNameRest pNameT :: Parser Name -pNameT = liftM2 (:) (satisfy isUpper) pNameRest +pNameT = notReserved $ liftM2 (:) (satisfy isUpper) pNameRest pNameRest :: Parser Name pNameRest = many (satisfy $ \d -> isAlphaNum d || d == '_') <* aheadW +notReserved :: Parser Name -> Parser Name +notReserved p = + try $ p >>= \n -> + if n `elem` reservedWords then unexpected "reserved word" else return n + pOperator :: Parser String pOperator = many1 (oneOf ":!#$%&*+./<=>?@\\^|-~") <* aheadO @@ -122,3 +130,6 @@ aheadO = do whitespace :: Parser () whitespace = void $ many space + +reservedWords :: [String] +reservedWords = ["case", "of", "class", "instance", "where", "let", "in"] |