@@ -1,13 +1,16 @@
1−
1+{-# LANGUAGE PatternGuards #-}
2module Types.Alias (dealias, get, mistakes) where
2module Types.Alias (dealias, get, mistakes) where
5import Control.Arrow (second)
6import Control.Arrow (second)
6import Data.List (group,sort)
7import Data.List (group,sort)
8+import Data.Maybe (mapMaybe)
7import qualified Data.Map as Map
9import qualified Data.Map as Map
8import qualified Data.Set as Set
10import qualified Data.Set as Set
9import Types.Substitutions (subst)
11import Types.Substitutions (subst)
10import Types.Types
12import Types.Types
13+import Data.Generics.Uniplate.Data
12builtins :: [(String,([X],Type))]
15builtins :: [(String,([X],Type))]
@@ -48,68 +51,59 @@ mistakes :: [Statement] -> [String]
48mistakes stmts = badKinds stmts ++ dups stmts ++ badOrder stmts
51mistakes stmts = badKinds stmts ++ dups stmts ++ badOrder stmts
50badKinds :: [Statement] -> [String]
53badKinds :: [Statement] -> [String]
51−badKinds stmts = map msg (concatMap badS stmts)
54+badKinds stmts = [msg tname | t <- universeBi stmts, tname <- badT t]
53 msg x = "Type Error: Type alias '" ++ x ++
56 msg x = "Type Error: Type alias '" ++ x ++
54 "' was given the wrong number of arguments."
57 "' was given the wrong number of arguments."
56 badT :: Type -> [String]
59 badT :: Type -> [String]
59− ADT name ts ->
60+ badT (ADT name ts)
60− case Map.lookup name (get stmts) of
61+ | Just (xs, _) <- Map.lookup name (get stmts),
61− Just (xs,t) | length xs == length ts -> []
62+ length xs /= length ts = [name]
62− | otherwise -> [name]
63+ badT _ = []
63− Nothing -> concatMap badT ts
64+
64− LambdaT t u -> badT t ++ badT u
65− RecordT r t -> badT t ++ concatMap badT (concat (Map.elems r))
68− badS :: Statement -> [String]
71− Datatype _ _ tcs -> concatMap badT (concatMap snd tcs)
72− ExportEvent _ _ tipe -> badT tipe
73− ImportEvent _ _ _ tipe -> badT tipe
74− TypeAnnotation _ tipe -> badT tipe
75− TypeAlias _ _ tipe -> badT tipe
78−annotation :: Statement -> [String]
65+annotation :: Def -> Maybe String
79annotation s =
66annotation s =
81− TypeAnnotation name _ -> [name]
68+ TypeAnnotation name _ -> Just name
82− _ -> []
69+ _ -> Nothing
84−definition :: Statement -> [String]
71+definition :: Def -> Maybe String
85definition s =
72definition s =
87− Definition d -> [defName d]
90−defName :: Def -> String
93− FnDef n _ _ -> n
74+ FnDef name _ _ -> Just name
94− OpDef n _ _ _ -> n
75+ OpDef name _ _ _ -> Just name
78+checkTopLevelAndLets :: [Statement] -> (String -> [Def] -> [a]) -> [a]
79+checkTopLevelAndLets stmts fcheck =
80+ fcheck "at top-level" topLevelDefs ++
81+ concatMap (fcheck "in let binding") allLetDefs
83+ topLevelDefs = mapMaybe maybeDef stmts
84+ maybeDef (Definition d) = Just d
86+ allLetDefs = [defList | Let defList _ <- universeBi stmts]
96dups :: [Statement] -> [String]
88dups :: [Statement] -> [String]
97−dups stmts = map defMsg (dup definition) ++ map annMsg (dup annotation)
89+dups stmts = checkTopLevelAndLets stmts $ \ctxt defs ->
99− dup :: (Statement -> [String]) -> [String]
91+ dup :: (Def -> Maybe String) -> [String]
100− dup f = map head . filter ((>1) . length) . group . sort $ concatMap f stmts
92+ dup f = map head . filter ((>1) . length) . group . sort $ mapMaybe f defs
102 msg = "Syntax Error: There can only be one "
94 msg = "Syntax Error: There can only be one "
103− defMsg x = msg ++ "top-level definition of '" ++ x ++ "'."
95+ defMsg x = msg ++ "definition of '" ++ x ++ "' " ++ ctxt ++ "."
104− annMsg x = msg ++ "type annotation for '" ++ x ++ "'."
96+ annMsg x = msg ++ "type annotation for '" ++ x ++ "'" ++ ctxt ++ "."
98+ map defMsg (dup definition) ++ map annMsg (dup annotation)
106badOrder :: [Statement] -> [String]
100badOrder :: [Statement] -> [String]
107−badOrder stmts = map msg $ missings (sort $ expectedPairs as ds) (sort $ actualPairs stmts)
101+badOrder stmts = checkTopLevelAndLets stmts $ \ctxt defs ->
109 msg x = "Syntax Error: The type annotation for '" ++ x ++
103 msg x = "Syntax Error: The type annotation for '" ++ x ++
110− "' must be directly above its definition."
104+ "' must be directly above its definition in " ++ ctxt ++ "."
111− as = sort $ concatMap annotation stmts
105+ as = sort $ mapMaybe annotation defs
112− ds = sort $ concatMap definition stmts
106+ ds = sort $ mapMaybe definition defs
114 expectedPairs :: [String] -> [String] -> [String]
108 expectedPairs :: [String] -> [String] -> [String]
115 expectedPairs as ds =
109 expectedPairs as ds =
@@ -120,11 +114,14 @@ badOrder stmts = map msg $ missings (sort $ expectedPairs as ds) (sort $ actualP
120 GT -> expectedPairs (x:xs) ys
114 GT -> expectedPairs (x:xs) ys
121 ( _ , _ ) -> []
115 ( _ , _ ) -> []
123− actualPairs :: [Statement] -> [String]
117+ actualPairs :: [Def] -> [String]
124 actualPairs stmts =
118 actualPairs stmts =
125 case stmts of
119 case stmts of
126− TypeAnnotation n _ : Definition d : rest ->
120+ TypeAnnotation n _ : rest@(d : _) ->
121+ (if Just n == definition d
127− (if n == defName d then [n] else []) ++ actualPairs rest
124+ ) ++ actualPairs rest
128 t:s:rest -> actualPairs (s:rest)
125 t:s:rest -> actualPairs (s:rest)
@@ -136,4 +133,6 @@ badOrder stmts = map msg $ missings (sort $ expectedPairs as ds) (sort $ actualP
136 EQ -> missings es as
133 EQ -> missings es as
137 GT -> a : missings (e:es) as
134 GT -> a : missings (e:es) as
138 ( [] , _ ) -> actual
135 ( [] , _ ) -> actual
139− ( _ , [] ) -> expected
136+ ( _ , [] ) -> expected
138+ map msg $ missings (sort $ expectedPairs as ds) (sort $ actualPairs defs)