aboutsummaryrefslogtreecommitdiff
path: root/parser/CC
diff options
context:
space:
mode:
authorTom Smeding <tom.smeding@gmail.com>2020-07-23 20:16:39 +0200
committerTom Smeding <tom.smeding@gmail.com>2020-07-23 20:16:39 +0200
commita9134688a2132c8f9abfff206f6e30614bb9aeff (patch)
tree7f5366329beb1857aa0a1d58781e830fd13ed7a8 /parser/CC
parent39ea4ac3a4b7663882a83f2ada43c8238f087d9b (diff)
WIP lambdas
Diffstat (limited to 'parser/CC')
-rw-r--r--parser/CC/Parser.hs31
1 files changed, 25 insertions, 6 deletions
diff --git a/parser/CC/Parser.hs b/parser/CC/Parser.hs
index d6c2239..d9e5b40 100644
--- a/parser/CC/Parser.hs
+++ b/parser/CC/Parser.hs
@@ -54,9 +54,31 @@ pTypeAtom :: Parser Type
pTypeAtom = (wordToken "Int" >> return TInt) <|> between (token "(") (token ")") pType
pExpr :: Parser Expr
-pExpr = lab "expression" $ do
- atoms <- many1 pExprAtom
- return (foldl1 (\a b -> Call (mergeRange (range a) (range b)) a b) atoms)
+pExpr = label (pCall <|> pLam) "expression"
+ where
+ pCall = do
+ atoms <- many1 pExprAtom
+ annot <- optionMaybe (do symbol "::"
+ p1 <- getPosition
+ ty <- pType
+ p2 <- getPosition
+ return (ty, SourceRange p1 p2))
+ let call = foldl1 (\a b -> Call (mergeRange (range a) (range b)) a b) atoms
+ case annot of
+ Just (ty, sr) -> return (Annot (mergeRange (range call) sr) call ty)
+ Nothing -> return call
+
+ pLam = do
+ p1 <- try $ do
+ whitespace
+ p <- getPosition
+ void (char '\\')
+ return p
+ names <- many1 pName
+ symbol "->"
+ body <- pExpr
+ p2 <- getPosition
+ return (Lam (SourceRange p1 p2) names body)
pExprAtom :: Parser Expr
pExprAtom =
@@ -106,9 +128,6 @@ emptyLines = (try (whitespace >> newline) >> emptyLines) <|> try (whitespace >>
whitespace :: Parser ()
whitespace = void (many (char ' '))
-lab :: String -> Parser a -> Parser a
-lab = flip label
-
getPosition :: Parser SourcePos
getPosition = do
pos <- Text.Parsec.getPosition