module Language.Eiffel.Parser.Typ where
import Control.Applicative ((<$>))
import Data.Text (Text)
import Language.Eiffel.Syntax
import Language.Eiffel.Parser.Lex
import Text.Parsec
likeTyp :: Parser Typ
likeTyp = keyword TokLike >>
Like `fmap` (identifier <|> (keyword TokCurrent >> return "Current"))
classTyp :: Parser Typ
classTyp = do
i <- identifier
let i' = case i of
"INTEGER" -> "INTEGER_32"
"CHARACTER" -> "CHARACTER_8"
"REAL" -> "REAL_32"
"STRING" -> "STRING_8"
x -> x
gs <- option [] (squares (typ `sepBy1` comma))
return (ClassType i' gs)
tupleTyp :: Parser Typ
tupleTyp = do
identifierNamed "TUPLE"
let typeDeclP =
Right <$> concat <$> try (decl `sepBy1` semicolon) <|>
Left <$> (typ `sepBy1` comma)
typeOrDecls <- option (Left []) (squares typeDeclP)
return (TupleType typeOrDecls)
detTyp :: Parser Typ
detTyp = keyword TokDetachable >> (sepTyp <|> likeTyp <|> baseTyp)
attTyp :: Parser Typ
attTyp = keyword TokAttached >> (likeTyp <|> baseTyp)
typ :: Parser Typ
typ = detTyp <|> attTyp <|> likeTyp <|> sepTyp <|> baseTyp
baseTyp :: Parser Typ
baseTyp = tupleTyp <|> classTyp
sepTyp :: Parser Typ
sepTyp = do
keyword TokSeparate
p <- return Nothing
ps <- return []
cn <- identifier
return $ Sep p ps cn
decl :: Parser [Decl]
decl = do
names <- identifier `sepBy1` comma <?> "Declaration identifier"
decl' names
decl' :: [Text] -> Parser [Decl]
decl' varNames = do
colon <?> "Declaration ':'"
typeName <- typ <?> "Declaration type"
return $ map (flip Decl typeName) varNames
argumentList :: Parser [Decl]
argumentList =
option [] (concat `fmap` parens (decl `sepBy` optional semicolon))