on 267f708 help sign in
elk/src/Parse/Type.hs
105 lines 2.6 kB history raw
1{-# OPTIONS_GHC -Wall -fno-warn-unused-do-bind #-}
2module Parse.Type where
4import Data.List (intercalate)
5import Text.Parsec ((<|>), (<?>), char, choice, many, optionMaybe, string, try)
7import qualified AST.Type as Type
8import qualified AST.Variable as Var
9import Parse.Helpers
10import qualified Reporting.Annotation as A
11import qualified Reporting.Region as R
14tvar :: IParser Type.Raw
15tvar =
16 addLocation
17 (Type.RVar <$> lowVar <?> "a type variable")
20tuple :: IParser Type.Raw
21tuple =
22 do (start, types, end) <- located (parens (commaSep expr))
23 case types of
24 [t] -> return t
25 _ -> return (Type.tuple (R.Region start end) types)
28record :: IParser Type.Raw
29record =
30 addLocation $
31 do char '{'
32 whitespace
33 rcrd <- extended <|> normal
34 dumbWhitespace
35 char '}'
36 return rcrd
37 where
38 normal = flip Type.RRecord Nothing <$> commaSep field
40 -- extended record types require at least one field
41 extended =
42 do ext <- try (addLocation lowVar <* (whitespace >> string "|"))
43 whitespace
44 fields <- commaSep1 field
45 return (Type.RRecord fields (Just (A.map Type.RVar ext)))
47 field =
48 do lbl <- rLabel
49 whitespace >> hasType >> whitespace
50 (,) lbl <$> expr
53capTypeVar :: IParser String
54capTypeVar =
55 intercalate "." <$> dotSep1 capVar
58constructor0 :: IParser Type.Raw
59constructor0 =
60 addLocation $
61 do name <- capTypeVar
62 return (Type.RType (Var.Raw name))
65term :: IParser Type.Raw
66term =
67 choice [ tuple, record, tvar, constructor0 ]
70app :: IParser Type.Raw
71app =
72 do start <- getMyPosition
73 f <- constructor0 <|> try tupleCtor <?> "a type constructor"
74 args <- spacePrefix term
75 end <- getMyPosition
76 case args of
77 [] -> return f
78 _ -> return (A.A (R.Region start end) (Type.RApp f args))
79 where
80 tupleCtor =
81 addLocation $
82 do n <- length <$> parens (many (char ','))
83 let ctor = "_Tuple" ++ show (if n == 0 then 0 else n+1)
84 return (Type.RType (Var.Raw ctor))
87expr :: IParser Type.Raw
88expr =
89 do start <- getMyPosition
90 t1 <- app <|> term
91 arr <- optionMaybe $ try (whitespace >> rightArrow)
92 case arr of
93 Nothing ->
94 return t1
95 Just _ ->
96 do whitespace
97 t2 <- expr
98 end <- getMyPosition
99 return (A.A (R.Region start end) (Type.RLambda t1 t2))
102constructor :: IParser (String, [Type.Raw])
103constructor =
104 (,) <$> (capTypeVar <?> "another type constructor")
105 <*> spacePrefix term