diff options
Diffstat (limited to 'parser')
-rw-r--r-- | parser/CC/Parser.hs | 31 |
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 |