on 9b0c310 help sign in
elk/src/Parse/Type.hs
106 lines 2.6 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 ((<|>), (<?>), char, many, optionMaybe, string, try)
8import qualified AST.Type as Type
9import qualified AST.Variable as Var
10import Parse.Helpers
11import qualified Reporting.Annotation as A
12import qualified Reporting.Region as R
15tvar :: IParser Type.Raw
16tvar =
17 addLocation
18 (Type.RVar <$> lowVar <?> "type variable")
21tuple :: IParser Type.Raw
22tuple =
23 do (start, types, end) <- located (parens (commaSep expr))
24 case types of
25 [t] -> return t
26 _ -> return (Type.tuple (R.Region start end) types)
29record :: IParser Type.Raw
30record =
31 addLocation $
32 do char '{'
33 whitespace
34 rcrd <- extended <|> normal
35 dumbWhitespace
36 char '}'
37 return rcrd
38 where
39 normal = flip Type.RRecord Nothing <$> commaSep field
41 -- extended record types require at least one field
42 extended =
43 do ext <- try (addLocation lowVar <* (whitespace >> string "|"))
44 whitespace
45 fields <- commaSep1 field
46 return (Type.RRecord fields (Just (A.map Type.RVar ext)))
48 field =
49 do lbl <- rLabel
50 whitespace >> hasType >> whitespace
51 (,) lbl <$> expr
54capTypeVar :: IParser String
55capTypeVar =
56 intercalate "." <$> dotSep1 capVar
59constructor0 :: IParser Type.Raw
60constructor0 =
61 addLocation $
62 do name <- capTypeVar
63 return (Type.RType (Var.Raw name))
66term :: IParser Type.Raw
67term =
68 tuple <|> record <|> tvar <|> constructor0
71app :: IParser Type.Raw
72app =
73 do start <- getMyPosition
74 f <- constructor0 <|> try tupleCtor <?> "type constructor"
75 args <- spacePrefix term
76 end <- getMyPosition
77 case args of
78 [] -> return f
79 _ -> return (A.A (R.Region start end) (Type.RApp f args))
80 where
81 tupleCtor =
82 addLocation $
83 do n <- length <$> parens (many (char ','))
84 let ctor = "_Tuple" ++ show (if n == 0 then 0 else n+1)
85 return (Type.RType (Var.Raw ctor))
88expr :: IParser Type.Raw
89expr =
90 do start <- getMyPosition
91 t1 <- app <|> term
92 arr <- optionMaybe $ try (whitespace >> arrow)
93 case arr of
94 Nothing ->
95 return t1
96 Just _ ->
97 do whitespace
98 t2 <- expr
99 end <- getMyPosition
100 return (A.A (R.Region start end) (Type.RLambda t1 t2))
103constructor :: IParser (String, [Type.Raw])
104constructor =
105 (,) <$> (capTypeVar <?> "another type constructor")
106 <*> spacePrefix term