packages feed

caml-parser-0.1.0.0: src/CamlParser/Parser/Type.hs

{-# LANGUAGE OverloadedStrings #-}
module CamlParser.Parser.Type where

import Text.Megaparsec hiding (Token)
import CamlParser.Lexer.Token
import CamlParser.Syntax.Type
import CamlParser.Parser.Combinators

parseType :: Parser TypeExpr
parseType = parseArrowType

parseArrowType :: Parser TypeExpr
parseArrowType = do
  t <- parseTupleType
  (do tok TokMinusGreater
      r <- parseArrowType
      return $ TArrow t r
   ) <|> return t

parseTupleType :: Parser TypeExpr
parseTupleType = do
  ts <- sepBy1 parseAppType (tok TokStar)
  case ts of
    [t] -> return t
    _   -> return $ TTuple ts

parseAppType :: Parser TypeExpr
parseAppType = do
  ts <- some parseAtomicType
  case ts of
    [t] -> return t
    _   -> return $ foldl1 (\acc t2 -> case t2 of
        TConstr s _ -> TConstr s [acc]
        TVar s -> TConstr s [acc]
        _ -> error "invalid type constructor in application") ts

parseAtomicType :: Parser TypeExpr
parseAtomicType = choice
  [ TVar <$> (tok TokQuote >> identP)
  , TConstr <$> identP <*> return []
  , TConstr . show <$> intP <*> return []
  , do tok TokLParen
       t <- parseType
       (do comma
           ts <- sepBy1 parseType comma
           tok TokRParen
           c <- identP
           return $ TConstr c (t : ts)
        ) <|> (tok TokRParen >> return t)
  ]