diff options
author | Tom Smeding <tom.smeding@gmail.com> | 2020-07-25 21:51:37 +0200 |
---|---|---|
committer | Tom Smeding <tom.smeding@gmail.com> | 2020-07-25 21:51:37 +0200 |
commit | 0503dcb2998ab9dcd0f39e6f264f482a3d2cc7f7 (patch) | |
tree | deb942a011451b183a1028a2f0f891d9e09e5107 /parser | |
parent | d5ab8f4939a4af51c7a9e1c2cd73c8352f8345b4 (diff) |
Support Let
Diffstat (limited to 'parser')
-rw-r--r-- | parser/CC/Parser.hs | 42 |
1 files changed, 36 insertions, 6 deletions
diff --git a/parser/CC/Parser.hs b/parser/CC/Parser.hs index bbabe3c..2d2c4b7 100644 --- a/parser/CC/Parser.hs +++ b/parser/CC/Parser.hs @@ -64,7 +64,7 @@ pParenType = do _ -> return (TTup tys) pExpr :: Parser Expr -pExpr = label (pCall <|> pLam) "expression" +pExpr = label (pLam <|> pLet <|> pCall) "expression" where pCall = do atoms <- many1 pExprAtom @@ -90,6 +90,31 @@ pExpr = label (pCall <|> pLam) "expression" p2 <- getPosition return (Lam (SourceRange p1 p2) names body) + pLet = do + p1 <- try $ do + whitespace + p <- getPosition + void (string "let") + return p + afterKeyword p1 + where + afterKeyword p1 = do + whitespace1 + lhs <- pName0 + symbol "=" + rhs <- pExpr + let fullRange rest = mergeRange (SourceRange p1 p1) (range rest) + choice [ do p1' <- try $ do + whitespace + p1' <- getPosition + void (string "let") + return p1' + rest <- afterKeyword p1' + return (Let (fullRange rest) lhs rhs rest) + , do symbol "in" + body <- pExpr + return (Let (fullRange body) lhs rhs body) ] + pExprAtom :: Parser Expr pExprAtom = choice [ uncurry (flip Int) <$> pInt @@ -119,11 +144,15 @@ pInt = try (whitespace >> pInt0) pName0 :: Parser (Name, SourceRange) pName0 = do p1 <- getPosition - c <- pWordFirstChar - cs <- many pWordMidChar + s <- try $ do + c <- pWordFirstChar + cs <- many pWordMidChar + let s = c : cs + guard (s `notElem` ["let", "in"]) + return s p2 <- getPosition notFollowedBy pWordMidChar - return (c : cs, SourceRange p1 p2) + return (s, SourceRange p1 p2) pWordFirstChar :: Parser Char pWordFirstChar = letter <|> oneOf "_$#!" @@ -146,8 +175,9 @@ token s = try (whitespace >> void (string s)) emptyLines :: Parser () emptyLines = (try (whitespace >> newline) >> emptyLines) <|> try (whitespace >> eof) <|> return () -whitespace :: Parser () -whitespace = void (many (void (char ' ') <|> void (try (string "\n ")))) +whitespace, whitespace1 :: Parser () +whitespace = void (many (void (char ' ') <|> void (try (string "\n ")))) +whitespace1 = void (many1 (void (char ' ') <|> void (try (string "\n ")))) getPosition :: Parser SourcePos getPosition = do |