--
-- Parser for Hindley-Milner terms and types.
-module HM.Parser
+module HM.Parser
( tRead
, parseTypedTerm
+ , parseVar
) where
import Data.Char (isAsciiLower, isAsciiUpper)
show (App a (NTTerm (App b c))) = show a ++ " " ++ braced ( show (App b c))
show (App t r) = show t ++ " " ++ show r
show (Let x e1 e2) = braced $ "LET " ++ x ++ " = " ++ show e1 ++ " IN " ++ show e2
+ show (Lit (LInt x)) = show x
+ show (Lit (LBool x)) = show x
+ show (Lit (LFunc x)) = show x
instance Show TypedTerm where
show (NTTerm t) = show t
parseTerm :: Parser Term
parseTerm = parseLet <|>
+ parseLambda <|>
parseApp <|>
parseBraces parseTerm <|>
- parseVar <|>
- parseLambda
+ parseLit <|>
+ parseVar
parseTermNoApp :: Parser Term
parseTermNoApp = parseBraces parseTerm <|>
parseLet <|>
parseVar <|>
+ parseLit <|>
parseLambda
parseTypeAndTerm :: Parser Term -> Parser TypedTerm
parseTypedTermNoApp :: Parser TypedTerm
-parseTypedTermNoApp = parseTypeAndTerm parseTermNoApp <|>
- parseBraces parseTypedTerm <|>
+parseTypedTermNoApp = parseBraces parseTypedTerm <|>
+ parseTypeAndTerm parseTermNoApp <|>
(NTTerm <$> parseTermNoApp)
parseTypedTerm :: Parser TypedTerm
parseTypedTerm = parseTypeAndTerm parseTerm <|>
- parseBraces parseTypedTerm <|>
- (NTTerm <$> parseTerm)
+ (NTTerm <$> parseTerm) <|>
+ parseBraces parseTypedTerm
parseType :: Parser Type
-parseType = parseBraces parseType <|>
+parseType = parseType <|>
parseTypeFunction <|>
parsePrimitive <|>
parseTypeVar
parsePrimitive :: Parser Type
parsePrimitive = do
- x <- many1 $ satisfy isAsciiUpper
- return $! Primitive x
+ x <- satisfy isAsciiUpper
+ xs <- many letter
+ return $! Primitive (x:xs)
parseTypeVar :: Parser Type
parseTypeVar = do
x <- many1 $ satisfy isAsciiLower
return $! Var x
+parseLit :: Parser Term
+parseLit = do
+ x <- parseLInt <|> parseLBool <|> parseLFun
+ return $! Lit x
+
+parseLFun :: Parser Literal
+parseLFun =
+ (string "If" >> return (LFunc If))
+
+parseLBool :: Parser Literal
+parseLBool =
+ (string "True" >> return (LBool True)) <|>
+ (string "False" >> return (LBool False))
+
+parseLInt :: Parser Literal
+parseLInt = do
+ x <- decimal
+ return $! LInt x
+
parseLambda :: Parser Term
parseLambda = do
char '\\' <|> char 'λ' <|> char 'L'