aboutsummaryrefslogtreecommitdiff
path: root/parser
diff options
context:
space:
mode:
authorTom Smeding <tom.smeding@gmail.com>2020-07-25 21:51:37 +0200
committerTom Smeding <tom.smeding@gmail.com>2020-07-25 21:51:37 +0200
commit0503dcb2998ab9dcd0f39e6f264f482a3d2cc7f7 (patch)
treedeb942a011451b183a1028a2f0f891d9e09e5107 /parser
parentd5ab8f4939a4af51c7a9e1c2cd73c8352f8345b4 (diff)
Support Let
Diffstat (limited to 'parser')
-rw-r--r--parser/CC/Parser.hs42
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