<commit_before>module Parse.Types where

import Ast
import Control.Applicative ((<$>),(<*>))
import Control.Monad (liftM,mapM)
import Data.Char (isUpper,isLower)
import Data.Maybe (fromMaybe)
import Data.List (lookup)
import Text.Parsec
import Text.Parsec.Indent

import Parse.Library
import Types.Types hiding (string,parens)
import Guid

data ParseType = VarPT String
               | LambdaPT ParseType ParseType
               | ADTPT String [ParseType]
               | RecordPT [(String,ParseType)]

listPT t = ADTPT "List" [t]
tuplePT ts = ADTPT ("Tuple" ++ show (length ts)) ts

typeVar :: IParser ParseType
typeVar = VarPT <$> lowVar <?> "type variable"

typeList :: IParser ParseType
typeList  = listPT <$> braces typeExpr

typeTuple :: IParser ParseType
typeTuple = do ts <- parens (commaSep typeExpr)
               return $ case ts of { [t] -> t ; _ -> tuplePT ts }

typeRecord :: IParser ParseType
typeRecord = fmap RecordPT . brackets . commaSep $ do
               lbl <- rLabel
               whitespace >> hasType >> whitespace
               (,) lbl <$> typeExpr

typeUnambiguous :: IParser ParseType
typeUnambiguous = typeList <|> typeTuple <|> typeRecord

typeSimple :: IParser ParseType
typeSimple = dealias <$> var
    where dealias "String" = listPT (VarPT "Char")
          dealias "Time" = VarPT "Float"
          dealias v = VarPT v

typeApp :: IParser ParseType
typeApp = do name <- capVar <?> "type constructor"
             args <- spacePrefix (typeUnambiguous <|> typeSimple)
             return $ case args of
                        [] -> VarPT name
                        _  -> ADTPT name args

typeExpr :: IParser ParseType
typeExpr = do
  t1 <- typeVar <|> typeApp <|> typeUnambiguous
  whitespace ; arr <- optionMaybe arrow ; whitespace
  case arr of Just _  -> LambdaPT t1 <$> typeExpr
              Nothing -> return t1

typeConstructor :: IParser (String, [ParseType])
typeConstructor = (,) <$> (capVar <?> "another type constructor")
                      <*> spacePrefix (typeSimple <|> typeUnambiguous)

typeAlias :: IParser Statement
typeAlias = do
  reserved "type" <?> "type alias (type Point = {x:Int, y:Int})"
  alias <- capVar
  whitespace ; string "=" ; whitespace
  TypeAlias alias <$> toType <$> typeExpr

typeAnnotation :: IParser Statement
typeAnnotation =
  let start = do v <- lowVar ; whitespace ; hasType ; whitespace ; return v
  in  TypeAnnotation <$> try start <*> (toType <$> typeExpr)

datatype :: IParser Statement<commit_msg>Allow type annotations for infix operators.<commit_after>module Parse.Types where

import Ast
import Control.Applicative ((<$>),(<*>))
import Control.Monad (liftM,mapM)
import Data.Char (isUpper,isLower)
import Data.Maybe (fromMaybe)
import Data.List (lookup)
import Text.Parsec
import Text.Parsec.Indent

import Parse.Library
import Types.Types hiding (string,parens)
import Guid

data ParseType = VarPT String
               | LambdaPT ParseType ParseType
               | ADTPT String [ParseType]
               | RecordPT [(String,ParseType)]

listPT t = ADTPT "List" [t]
tuplePT ts = ADTPT ("Tuple" ++ show (length ts)) ts

typeVar :: IParser ParseType
typeVar = VarPT <$> lowVar <?> "type variable"

typeList :: IParser ParseType
typeList  = listPT <$> braces typeExpr

typeTuple :: IParser ParseType
typeTuple = do ts <- parens (commaSep typeExpr)
               return $ case ts of { [t] -> t ; _ -> tuplePT ts }

typeRecord :: IParser ParseType
typeRecord = fmap RecordPT . brackets . commaSep $ do
               lbl <- rLabel
               whitespace >> hasType >> whitespace
               (,) lbl <$> typeExpr

typeUnambiguous :: IParser ParseType
typeUnambiguous = typeList <|> typeTuple <|> typeRecord

typeSimple :: IParser ParseType
typeSimple = dealias <$> var
    where dealias "String" = listPT (VarPT "Char")
          dealias "Time" = VarPT "Float"
          dealias v = VarPT v

typeApp :: IParser ParseType
typeApp = do name <- capVar <?> "type constructor"
             args <- spacePrefix (typeUnambiguous <|> typeSimple)
             return $ case args of
                        [] -> VarPT name
                        _  -> ADTPT name args

typeExpr :: IParser ParseType
typeExpr = do
  t1 <- typeVar <|> typeApp <|> typeUnambiguous
  whitespace ; arr <- optionMaybe arrow ; whitespace
  case arr of Just _  -> LambdaPT t1 <$> typeExpr
              Nothing -> return t1

typeConstructor :: IParser (String, [ParseType])
typeConstructor = (,) <$> (capVar <?> "another type constructor")
                      <*> spacePrefix (typeSimple <|> typeUnambiguous)

typeAlias :: IParser Statement
typeAlias = do
  reserved "type" <?> "type alias (type Point = {x:Int, y:Int})"
  alias <- capVar
  whitespace ; string "=" ; whitespace
  TypeAlias alias <$> toType <$> typeExpr

typeAnnotation :: IParser Statement
typeAnnotation = TypeAnnotation <$> try start <*> (toType <$> typeExpr)
    where start = do v <- lowVar <|> parens symOp
                     whitespace ; hasType ; whitespace ; return v

datatype :: IParser Statement
{'fraction_non_alphanumeric': 0.10919540229885058, 'fraction_numerical': 0.0011890606420927466, 'mean_word_length': 2.89429012345679, 'pattern_counts': {'":': 0, '<': 68, '<?xml version=': 0, '>': 72, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3476921', 'n_tokens_mistral': 1531, 'n_tokens_neox': 1480, 'n_words': 473}