on 63243ca help sign in
elk/compiler/Parse/Type.hs
74 lines 1.9 kB history raw
1{-# OPTIONS_GHC -Wall -fno-warn-unused-do-bind #-}
2module Parse.Type where
4import Control.Applicative ((<$>),(<*>),(<*))
5import Data.List (intercalate)
6import Text.Parsec
8import SourceSyntax.Type as T
9import Parse.Helpers
11tvar :: IParser T.Type
12tvar = T.Var <$> lowVar <?> "type variable"
14list :: IParser T.Type
15list = listOf <$> braces expr
17tuple :: IParser T.Type
18tuple = do ts <- parens (commaSep expr)
19 return $ case ts of
20 [t] -> t
21 _ -> tupleOf ts
23record :: IParser T.Type
24record =
25 do char '{' ; whitespace
26 rcrd <- extended <|> normal
27 dumbWhitespace ; char '}'
28 return rcrd
29 where
30 normal = flip T.Record Nothing <$> commaSep field
32 -- extended record types require at least one field
33 extended = do
34 ext <- try (lowVar <* (whitespace >> string "|"))
35 whitespace
36 flip T.Record (Just ext) <$> commaSep1 field
38 field = do
39 lbl <- rLabel
40 whitespace >> hasType >> whitespace
41 (,) lbl <$> expr
43capTypeVar :: IParser String
44capTypeVar = intercalate "." <$> dotSep1 capVar
46constructor0 :: IParser T.Type
47constructor0 =
48 do name <- capTypeVar
49 return (T.Data name [])
51term :: IParser T.Type
52term = list <|> tuple <|> record <|> tvar <|> constructor0
54app :: IParser T.Type
55app =
56 do name <- capTypeVar <|> try tupleCtor <?> "type constructor"
57 args <- spacePrefix term
58 return (T.Data name args)
59 where
60 tupleCtor = do
61 n <- length <$> parens (many (char ','))
62 return $ "_Tuple" ++ show (if n == 0 then 0 else n+1)
64expr :: IParser T.Type
65expr =
66 do t1 <- app <|> term
67 arr <- optionMaybe $ try (whitespace >> arrow)
68 case arr of
69 Just _ -> T.Lambda t1 <$> (whitespace >> expr)
70 Nothing -> return t1
72constructor :: IParser (String, [T.Type])
73constructor = (,) <$> (capTypeVar <?> "another type constructor")
74 <*> spacePrefix term