@@ -8,106 +8,69 @@ import Text.Parsec
8import Text.Parsec.Indent
8import Text.Parsec.Indent
10import SourceSyntax.Location as Located
10import SourceSyntax.Location as Located
11+--import SourceSyntax.PrettyPrint
12+import SourceSyntax.Type as T
11−import SourceSyntax.Expression
13+--import qualified SourceSyntax.Expression as Expr
12−import SourceSyntax.Declaration
14+--import qualified SourceSyntax.Declaration as Decl
13import Parse.Helpers
15import Parse.Helpers
14−import Types.Types hiding (parens,string)
15import Unique
16import Unique
17−data ParseType = VarPT String
18+tvar :: IParser T.Type
18− | LambdaPT ParseType ParseType
19+tvar = T.Var <$> lowVar <?> "type variable"
19− | ADTPT String [ParseType]
20− | RecordPT (Maybe ParseType) [(String,ParseType)]
23−listPT t = ADTPT "List" [t]
24−tuplePT ts = ADTPT ("Tuple" ++ show (length ts)) ts
26−typeVar :: IParser ParseType
27−typeVar = VarPT <$> lowVar <?> "type variable"
29−typeList :: IParser ParseType
30−typeList = listPT <$> braces typeExpr
32−typeTuple :: IParser ParseType
33−typeTuple = do ts <- parens (commaSep typeExpr)
34− return $ case ts of { [t] -> t ; _ -> tuplePT ts }
36−typeRecord :: IParser ParseType
37−typeRecord = brackets (RecordPT <$> extend <*> fields)
38− where extend = optionMaybe . try $ do
40− whitespace >> string "|" >> whitespace
42− fields = commaSep $ do
44− whitespace >> hasType >> whitespace
47−typeUnambiguous :: IParser ParseType
48−typeUnambiguous = typeList <|> typeTuple <|> typeRecord
50−typeSimple :: IParser ParseType
51−typeSimple = VarPT <$> var
53−typeApp :: IParser ParseType
54−typeApp = do name <- capVar <?> "type constructor"
55− args <- spacePrefix (typeUnambiguous <|> typeSimple)
56− return $ case args of
60−typeExpr :: IParser ParseType
62− t1 <- typeVar <|> typeApp <|> typeUnambiguous
63− whitespace ; arr <- optionMaybe arrow ; whitespace
65− Just _ -> LambdaPT t1 <$> typeExpr
68−typeConstructor :: IParser (String, [ParseType])
69−typeConstructor = (,) <$> (capVar <?> "another type constructor")
70− <*> spacePrefix (typeSimple <|> typeUnambiguous)
72−typeAlias :: IParser [Declaration t v]
75− reserved "type" <?> "type alias (type Point = {x:Int, y:Int})"
78− args <- spacePrefix lowVar
79− whitespace ; string "=" ; whitespace
83− case toTypeWith alias (zip args [1..n]) tipe of
85− Right t -> return (TypeAlias alias [1..n] t : ctor)
86− where ctor = case tipe of
87− RecordPT extension kvs ->
88− [] --toConstructor start end alias extension kvs]
91−toConstructor start end alias Nothing kvs =
92− Definition (Def alias args (loc (Record rec)))
94− loc = Located.at start end
96− rec = map (\a -> (a, loc (Var a))) args
98−toConstructor start end alias (Just _) kvs =
21+list :: IParser T.Type
99− Definition (Def alias (args++["_ext_"]) (loc rec))
22+list = listOf <$> braces expr
24+tuple :: IParser T.Type
25+tuple = do ts <- parens (commaSep expr)
30+record :: IParser T.Type
31+record = brackets $ do
34+ return (T.Record (fieldMap fs) ext)
101− loc = Located.at start end
36+ extend = option T.EmptyRecord . try $ do
102− args = map fst kvs
37+ t <- tvar
103− rec = foldl insert (Var "_ext_") (zip args (map (loc . Var) args))
38+ whitespace >> string "|" >> whitespace
104− insert e (k,v) = Insert (loc e) k v
39+ return t
105−--}
40+ fields = commaSep $ do
106−annotation :: IParser (Def t v)
41+ lbl <- rLabel
107−annotation = TypeAnnotation <$> try start <*> (toType <$> typeExpr)
108− where start = do v <- lowVar <|> parens symOp
109− whitespace ; hasType ; whitespace ; return v
42+ whitespace >> hasType >> whitespace
45+constructor0 :: IParser T.Type
48+ return (T.Data name [])
50+term :: IParser T.Type
51+term = list <|> tuple <|> record <|> tvar <|> constructor0
55+ do name <- capVar <?> "type constructor"
56+ args <- spacePrefix term
57+ return (T.Data name args)
59+expr :: IParser T.Type
61+ do t1 <- app <|> term
63+ arr <- optionMaybe arrow
66+ Just _ -> T.Lambda t1 <$> expr
69+constructor :: IParser (String, [T.Type])
70+constructor = (,) <$> (capVar <?> "another type constructor")
111datatype :: IParser (Declaration t v)
74datatype :: IParser (Declaration t v)
112datatype = do
75datatype = do
113 reserved "data" <?> "datatype definition (data T = A | B | ...)"
76 reserved "data" <?> "datatype definition (data T = A | B | ...)"
@@ -118,41 +81,41 @@ datatype = do
118 Right dt -> return dt
81 Right dt -> return dt
119 Left msg -> fail msg
82 Left msg -> fail msg
121−beta = liftM VarT guid
84+beta = liftM T.Var guid
123−toType :: ParseType -> Type
86+toType :: T.Type -> Type
124toType pt =
87toType pt =
125− let frees :: ParseType -> [String]
88+ let frees :: T.Type -> [String]
126 frees pt = case pt of
89 frees pt = case pt of
127 LambdaPT a b -> frees a ++ frees b
90 LambdaPT a b -> frees a ++ frees b
128 ADTPT _ ts -> concatMap frees ts
91 ADTPT _ ts -> concatMap frees ts
129 RecordPT t fs -> maybe [] frees t ++ concatMap (frees . snd) fs
92 RecordPT t fs -> maybe [] frees t ++ concatMap (frees . snd) fs
130 VarPT (c:cs) | isLower c -> [c:cs]
93 VarPT (c:cs) | isLower c -> [c:cs]
131 | otherwise -> []
94 | otherwise -> []
132− in case toTypeWith "" (zip (frees pt) [1..]) pt of
95+ in case toTypeWith "" (zip (frees pt) ['a'..]) pt of
133 Right t -> t
96 Right t -> t
134− Left _ -> VarT 0
97+ Left _ -> T.Var 0
136−toTypeWith :: String -> [(String,X)] -> ParseType -> Either String Type
99+toTypeWith :: String -> [(String,String)] -> T.Type -> Either String Type
137toTypeWith name tvarDict pt =
100toTypeWith name tvarDict pt =
138 let msg x = "Type variable '" ++ x ++ "' is unbound in type '" ++ name ++ "'."
101 let msg x = "Type variable '" ++ x ++ "' is unbound in type '" ++ name ++ "'."
139 toT = toTypeWith name tvarDict
102 toT = toTypeWith name tvarDict
140 in case pt of
103 in case pt of
141− LambdaPT t1 t2 -> (==>) <$> toT t1 <*> toT t2
104+ LambdaPT t1 t2 -> T.Lambda <$> toT t1 <*> toT t2
142− ADTPT name args -> ADT name <$> mapM toT args
105+ ADTPT name args -> T.Data name <$> mapM toT args
143 RecordPT t fs -> do fs' <- mapM (\(x,pt) -> (,) x <$> toT pt) fs
106 RecordPT t fs -> do fs' <- mapM (\(x,pt) -> (,) x <$> toT pt) fs
144− ext <- maybe (return EmptyRecord) toT t
107+ ext <- maybe (return T.EmptyRecord) toT t
145− return (RecordT (recordT fs') ext)
108+ return (T.Record (T.record fs') ext)
146 VarPT x@(c:_)
109 VarPT x@(c:_)
147− | not (isLower c) -> return $ ADT x []
110+ | not (isLower c) -> return $ T.Data x []
148− | otherwise -> VarT <$> case lookup x tvarDict of
111+ | otherwise -> T.Var <$> case lookup x tvarDict of
149− Just v -> Right v
112+ Just v -> Right v
150− Nothing -> Left (msg x)
113+ Nothing -> Left (msg x)
153toDatatype name args tcs = Datatype name [1..n] <$> mapM toC tcs
116toDatatype name args tcs = Datatype name [1..n] <$> mapM toC tcs
154 where n = length args
117 where n = length args
155− toType = toTypeWith name (zip args [1..n])
118+ toType = toTypeWith name (zip args (map (:[]) ['a'..]))
156 toC (name,pt) = (,) name <$> mapM toType pt
119 toC (name,pt) = (,) name <$> mapM toType pt
@@ -161,18 +124,19 @@ toForeignType (LambdaPT t1 t2) =
161 "Only simple values can be imported and exported in this release."
124 "Only simple values can be imported and exported in this release."
163toForeignType (ADTPT "JSArray" args) =
126toForeignType (ADTPT "JSArray" args) =
164− ADT "JSArray" <$> mapM toForeignType args
127+ T.Data "JSArray" <$> mapM toForeignType args
166toForeignType (ADTPT name _) =
129toForeignType (ADTPT name _) =
167 Left $ "'" ++ name ++ "' is not an exportable type " ++
130 Left $ "'" ++ name ++ "' is not an exportable type " ++
168 "constructor. Only 'JSArray' is exportable."
131 "constructor. Only 'JSArray' is exportable."
170toForeignType (VarPT x@(c:_))
133toForeignType (VarPT x@(c:_))
171− | x `elem` jsTypes = Right (ADT x [])
134+ | x `elem` jsTypes = Right (T.Data x [])
172 | isLower c =
135 | isLower c =
173 Left $ "All exported types must be concrete types." ++ msg
136 Left $ "All exported types must be concrete types." ++ msg
174 | otherwise =
137 | otherwise =
175 Left $ "'" ++ x ++ "' is not an exportable type." ++ msg
138 Left $ "'" ++ x ++ "' is not an exportable type." ++ msg
177 msg = " The following types are exportable: " ++ intercalate ", " jsTypes
140 msg = " The following types are exportable: " ++ intercalate ", " jsTypes
178− jsTypes = ["JSString","JSNumber","JSDomNode","JSBool","JSObject"]
141+ jsTypes = ["JSString","JSNumber","JSDomNode","JSBool","JSObject"]