2013-06-14 02:15:40 +00:00
|
|
|
module Parse.Type where
|
2012-04-19 06:32:10 +00:00
|
|
|
|
2012-06-10 04:21:16 +00:00
|
|
|
import Control.Applicative ((<$>),(<*>))
|
2012-08-01 23:37:37 +00:00
|
|
|
import Control.Monad (liftM,mapM)
|
2013-06-14 02:15:40 +00:00
|
|
|
import Data.Char (isLower)
|
2013-05-22 13:59:47 +00:00
|
|
|
import Data.List (lookup,intercalate)
|
2012-06-10 04:21:16 +00:00
|
|
|
import Text.Parsec
|
2012-11-25 04:49:56 +00:00
|
|
|
import Text.Parsec.Indent
|
2012-06-10 04:21:16 +00:00
|
|
|
|
2013-06-14 01:35:37 +00:00
|
|
|
import SourceSyntax.Location as Located
|
2013-07-07 16:13:40 +00:00
|
|
|
--import SourceSyntax.PrettyPrint
|
|
|
|
import SourceSyntax.Type as T
|
|
|
|
--import qualified SourceSyntax.Expression as Expr
|
|
|
|
--import qualified SourceSyntax.Declaration as Decl
|
2013-06-14 01:35:37 +00:00
|
|
|
import Parse.Helpers
|
2013-06-14 03:25:00 +00:00
|
|
|
import Unique
|
2012-04-28 07:26:46 +00:00
|
|
|
|
2013-07-07 16:13:40 +00:00
|
|
|
tvar :: IParser T.Type
|
|
|
|
tvar = T.Var <$> lowVar <?> "type variable"
|
2013-07-04 09:36:08 +00:00
|
|
|
|
2013-07-07 16:13:40 +00:00
|
|
|
list :: IParser T.Type
|
|
|
|
list = listOf <$> braces expr
|
|
|
|
|
|
|
|
tuple :: IParser T.Type
|
|
|
|
tuple = do ts <- parens (commaSep expr)
|
|
|
|
return $ case ts of
|
|
|
|
[t] -> t
|
|
|
|
_ -> tupleOf ts
|
|
|
|
|
|
|
|
record :: IParser T.Type
|
2013-07-14 12:55:29 +00:00
|
|
|
record =
|
|
|
|
do char '{' ; whitespace
|
|
|
|
ext <- extend
|
|
|
|
fs <- fields
|
|
|
|
dumbWhitespace ; char '}'
|
|
|
|
return (T.Record (fieldMap fs) ext)
|
2013-06-07 17:16:38 +00:00
|
|
|
where
|
2013-07-07 16:13:40 +00:00
|
|
|
extend = option T.EmptyRecord . try $ do
|
|
|
|
t <- tvar
|
|
|
|
whitespace >> string "|" >> whitespace
|
|
|
|
return t
|
|
|
|
fields = commaSep $ do
|
|
|
|
lbl <- rLabel
|
|
|
|
whitespace >> hasType >> whitespace
|
|
|
|
(,) lbl <$> expr
|
|
|
|
|
2013-07-14 12:55:29 +00:00
|
|
|
|
2013-07-07 16:13:40 +00:00
|
|
|
constructor0 :: IParser T.Type
|
|
|
|
constructor0 =
|
|
|
|
do name <- capVar
|
|
|
|
return (T.Data name [])
|
|
|
|
|
|
|
|
term :: IParser T.Type
|
|
|
|
term = list <|> tuple <|> record <|> tvar <|> constructor0
|
|
|
|
|
|
|
|
app :: IParser T.Type
|
|
|
|
app =
|
|
|
|
do name <- capVar <?> "type constructor"
|
|
|
|
args <- spacePrefix term
|
|
|
|
return (T.Data name args)
|
|
|
|
|
|
|
|
expr :: IParser T.Type
|
|
|
|
expr =
|
|
|
|
do t1 <- app <|> term
|
|
|
|
whitespace
|
|
|
|
arr <- optionMaybe arrow
|
|
|
|
whitespace
|
|
|
|
case arr of
|
|
|
|
Just _ -> T.Lambda t1 <$> expr
|
|
|
|
Nothing -> return t1
|
|
|
|
|
|
|
|
constructor :: IParser (String, [T.Type])
|
|
|
|
constructor = (,) <$> (capVar <?> "another type constructor")
|
|
|
|
<*> spacePrefix term
|