2013-07-14 23:06:00 +00:00
|
|
|
module Transform.Check (mistakes) where
|
|
|
|
|
|
|
|
import Transform.SortDefinitions (boundVars)
|
|
|
|
import SourceSyntax.Everything
|
|
|
|
import qualified SourceSyntax.Type as T
|
|
|
|
import Data.List as List
|
|
|
|
import qualified Data.Map as Map
|
|
|
|
import qualified Data.Set as Set
|
|
|
|
import Data.Data
|
|
|
|
import Data.Generics.Uniplate.Data
|
2013-07-16 12:52:50 +00:00
|
|
|
import Text.PrettyPrint as P
|
2013-07-14 23:06:00 +00:00
|
|
|
|
|
|
|
|
2013-07-16 12:52:50 +00:00
|
|
|
mistakes :: (Data t, Data v) => [Declaration t v] -> [Doc]
|
2013-07-14 23:06:00 +00:00
|
|
|
mistakes decls =
|
2013-07-23 14:15:56 +00:00
|
|
|
map P.text $ concatMap findErrors (getLets decls)
|
2013-07-16 12:52:50 +00:00
|
|
|
where
|
|
|
|
findErrors defs = duplicates defs ++ badOrder defs
|
2013-07-14 23:06:00 +00:00
|
|
|
|
|
|
|
|
|
|
|
getLets :: (Data t, Data v) => [Declaration t v] -> [[Def t v]]
|
|
|
|
getLets decls = defs : concatMap getSubLets defs
|
|
|
|
where
|
|
|
|
defs = concatMap (\d -> case d of Definition d -> [d] ; _ -> []) decls
|
|
|
|
|
|
|
|
getSubLets def =
|
|
|
|
case def of
|
|
|
|
Def pattern expr -> [ defs | Let defs _ <- universeBi expr ]
|
|
|
|
TypeAnnotation _ _ -> []
|
|
|
|
|
|
|
|
|
|
|
|
duplicates :: [Def t v] -> [String]
|
|
|
|
duplicates defs =
|
2013-07-23 14:15:56 +00:00
|
|
|
map defMsg (dups definitions) ++ map annMsg (dups annotations)
|
2013-07-14 23:06:00 +00:00
|
|
|
where
|
2013-07-23 14:15:56 +00:00
|
|
|
annotations = List.sort [ name | TypeAnnotation name _ <- defs ]
|
|
|
|
definitions = List.sort $ concatMap Set.toList [ boundVars pattern | Def pattern _ <- defs ]
|
|
|
|
|
|
|
|
dups = map head . filter ((>1) . length) . List.group
|
2013-07-14 23:06:00 +00:00
|
|
|
|
|
|
|
msg = "Syntax Error: There can only be one "
|
2013-08-09 01:05:21 +00:00
|
|
|
defMsg x = msg ++ "definition of '" ++ x ++ "'."
|
|
|
|
annMsg x = msg ++ "type annotation for '" ++ x ++ "'."
|
2013-07-14 23:06:00 +00:00
|
|
|
|
|
|
|
|
|
|
|
badOrder :: [Def t v] -> [String]
|
2013-07-23 14:15:56 +00:00
|
|
|
badOrder defs = go defs
|
2013-07-14 23:06:00 +00:00
|
|
|
where
|
|
|
|
msg x = "Syntax Error: The type annotation for '" ++ x ++
|
|
|
|
"' must be directly above its definition."
|
2013-07-23 14:15:56 +00:00
|
|
|
|
|
|
|
go defs =
|
2013-07-14 23:06:00 +00:00
|
|
|
case defs of
|
2013-07-23 14:15:56 +00:00
|
|
|
TypeAnnotation name _ : Def (PVar name') _ : rest
|
|
|
|
| name == name' -> go rest
|
|
|
|
|
|
|
|
TypeAnnotation name _ : rest -> [msg name] ++ go rest
|
|
|
|
|
|
|
|
_ : rest -> go rest
|
|
|
|
|
2013-07-14 23:06:00 +00:00
|
|
|
_ -> []
|
|
|
|
|
2013-07-23 14:15:56 +00:00
|
|
|
|