@@ -0,0 +1,137 @@
2+module Types.Alias (dealias, mistakes) where
5+import Control.Arrow (second)
6+import Data.List (group,sort)
7+import qualified Data.Map as Map
8+import qualified Data.Set as Set
9+import Types.Substitutions (subst)
12+builtins :: [(String,([X],Type))]
13+builtins = [ ("String", ([], string)) ]
15+getAliases :: [Statement] -> Map.Map String ([X],Type)
16+getAliases stmts = Map.fromList (builtins ++ concatMap getAlias stmts)
17+ where getAlias stmt = case stmt of
18+ TypeAlias alias xs t -> [(alias, (xs,t))]
22+dealias :: [Statement] -> [Statement]
23+dealias stmts = map dealiasS stmts
25+ dealiasT :: Type -> Type
28+ ADT name ts -> case Map.lookup name (getAliases stmts) of
29+ Just (xs,t) -> dealiasT (subst (zip xs ts) t)
30+ Nothing -> ADT name (map dealiasT ts)
31+ LambdaT t u -> LambdaT (dealiasT t) (dealiasT u)
32+ RecordT r t -> RecordT (Map.map (map dealiasT) r) (dealiasT t)
35+ dealiasS :: Statement -> Statement
38+ Datatype n xs tcs -> Datatype n xs (map (second (map dealiasT)) tcs)
39+ ExportEvent js elm tipe -> ExportEvent js elm (dealiasT tipe)
40+ ImportEvent js e elm tipe -> ImportEvent js e elm (dealiasT tipe)
41+ TypeAnnotation name tipe -> TypeAnnotation name (dealiasT tipe)
42+ TypeAlias alias xs tipe -> TypeAlias alias xs (dealiasT tipe)
45+mistakes :: [Statement] -> [String]
46+mistakes stmts = badKinds stmts ++ dups stmts ++ badOrder stmts
48+badKinds :: [Statement] -> [String]
49+badKinds stmts = map msg (concatMap badS stmts)
51+ msg x = "Type Error: Type alias '" ++ x ++
52+ "' was given the wrong number of arguments."
54+ badT :: Type -> [String]
58+ case Map.lookup name (getAliases stmts) of
59+ Just (xs,t) | length xs == length ts -> []
60+ | otherwise -> [name]
61+ Nothing -> concatMap badT ts
62+ LambdaT t u -> badT t ++ badT u
63+ RecordT r t -> badT t ++ concatMap badT (concat (Map.elems r))
66+ badS :: Statement -> [String]
69+ Datatype _ _ tcs -> concatMap badT (concatMap snd tcs)
70+ ExportEvent _ _ tipe -> badT tipe
71+ ImportEvent _ _ _ tipe -> badT tipe
72+ TypeAnnotation _ tipe -> badT tipe
73+ TypeAlias _ _ tipe -> badT tipe
76+annotation :: Statement -> [String]
79+ TypeAnnotation name _ -> [name]
82+definition :: Statement -> [String]
85+ Definition d -> [defName d]
88+defName :: Def -> String
94+dups :: [Statement] -> [String]
95+dups stmts = map defMsg (dup definition) ++ map annMsg (dup annotation)
97+ dup :: (Statement -> [String]) -> [String]
98+ dup f = map head . filter ((>1) . length) . group . sort $ concatMap f stmts
100+ msg = "Syntax Error: There can only be one "
101+ defMsg x = msg ++ "top-level definition of '" ++ x ++ "'."
102+ annMsg x = msg ++ "type annotation for '" ++ x ++ "'."
104+badOrder :: [Statement] -> [String]
105+badOrder stmts = map msg $ missings (sort $ expectedPairs as ds) (sort $ actualPairs stmts)
107+ msg x = "Syntax Error: The type annotation for '" ++ x ++
108+ "' must be directly above its definition."
109+ as = sort $ concatMap annotation stmts
110+ ds = sort $ concatMap definition stmts
112+ expectedPairs :: [String] -> [String] -> [String]
113+ expectedPairs as ds =
115+ (x:xs, y:ys) -> case compare x y of
116+ LT -> expectedPairs xs (y:ys)
117+ EQ -> x : expectedPairs xs ys
118+ GT -> expectedPairs (x:xs) ys
121+ actualPairs :: [Statement] -> [String]
124+ TypeAnnotation n _ : Definition d : rest ->
125+ if n == defName d then [n] else [] ++ actualPairs rest
126+ t:s:rest -> actualPairs (s:rest)
129+ missings :: [String] -> [String] -> [String]
130+ missings expected actual =
131+ case (expected, actual) of
132+ (e:es, a:as) -> case compare e a of
133+ LT -> e : missings es (a:as)
134+ EQ -> missings es as
135+ GT -> a : missings (e:es) as
136+ ( [] , _ ) -> actual
137+ ( _ , [] ) -> expected