on 727d708 help sign in
elk/compiler/Parse/Type.hs
81 lines 2.0 kB history raw
1module Parse.Type where
3import Control.Applicative ((<$>),(<*>))
4import Control.Monad (liftM,mapM)
5import Data.Char (isLower)
6import Data.List (lookup,intercalate)
7import Text.Parsec
8import Text.Parsec.Indent
10import SourceSyntax.Type as T
11import Parse.Helpers
12import Unique
14tvar :: IParser T.Type
15tvar = T.Var <$> lowVar <?> "type variable"
17list :: IParser T.Type
18list = listOf <$> braces expr
20tuple :: IParser T.Type
21tuple = do ts <- parens (commaSep expr)
22 return $ case ts of
23 [t] -> t
24 _ -> tupleOf ts
26record :: IParser T.Type
27record =
28 do char '{' ; whitespace
29 ext <- extend
30 fs <- fields
31 dumbWhitespace ; char '}'
32 return (T.Record (fieldMap fs) ext)
33 where
34 extend = option T.EmptyRecord . try $ do
35 t <- tvar
36 whitespace >> string "|" >> whitespace
37 return t
38 fields = commaSep $ do
39 lbl <- rLabel
40 whitespace >> hasType >> whitespace
41 (,) lbl <$> expr
43capTypeVar = intercalate "." <$> dotSep1 capVar
45constructor0 :: IParser T.Type
46constructor0 =
47 do name <- capTypeVar
48 return (T.Data name [])
50term :: IParser T.Type
51term = list <|> tuple <|> record <|> tvar <|> constructor0
53app :: IParser T.Type
54app =
55 do name <- capTypeVar <|> try tupleCtor <?> "type constructor"
56 args <- spacePrefix term
57 return (T.Data name args)
58 where
59 tupleCtor = do
60 n <- length <$> parens (many (char ','))
61 return $ "_Tuple" ++ show (if n == 0 then 0 else n+1)
63expr :: IParser T.Type
64expr =
65 do t1 <- app <|> term
66 whitespace
67 arr <- optionMaybe arrow
68 whitespace
69 case arr of
70 Just _ -> T.Lambda t1 <$> expr
71 Nothing -> return t1
73constructor :: IParser (String, [T.Type])
74constructor = (,) <$> (capTypeVar <?> "another type constructor")
75 <*> spacePrefix term
77readType :: String -> Type
78readType str =
79 case iParse expr "" str of
80 Left err -> error (show err)
81 Right tipe -> tipe