on master help sign in
Add back in checks for duplicate and out-of-order definitions.
commit93a948cd6766f44d87aa3a0ab674053602ff8d4a authorEvan Czaplicki <evan@Evans-MacBook-Air.local> dateMon 15 Jul 2013, 01:06 (13 years ago) parent1fcb01f
4 files changed+96−7
compiler/Initialize.hs+3−3 compiler/SourceSyntax/Expression.hs+4−2 compiler/SourceSyntax/Type.hs+3−2 compiler/Transform/Check.hs+86
compiler/Initialize.hs+3−3
@@ -10,6 +10,7 @@ import Data.List (intercalate,partition)
1010import Parse.Parser (parseProgram, parseDependencies)
1111import qualified Metadata.Libraries as Libs
1212import Transform.Optimize
13+import qualified Transform.Check as Check
1314import System.Exit
1415import System.FilePath
1516
@@ -19,14 +20,13 @@ import Types.Hints (hints)
1920import Types.Unify (unify)
2021import Types.Alias (dealias, mistakes)
2122--}
22−mistakes = undefined
2323unify = undefined
2424hints = undefined
2525
2626
2727checkMistakes :: (Data t, Data v) => Module t v -> Either String (Module t v)
28−checkMistakes modul@(Module name ex im stmts) =
29− case mistakes stmts of
28+checkMistakes modul@(Module name ex im decls) =
29+ case Check.mistakes decls of
3030 m:ms -> Left (unlines (m:ms))
3131 [] -> return modul
3232
compiler/SourceSyntax/Expression.hs+4−2
@@ -1,5 +1,7 @@
1+{-# LANGUAGE DeriveDataTypeable #-}
12module SourceSyntax.Expression where
23
4+import Data.Data
35import Data.List (intercalate)
46import qualified Text.Pandoc as Pandoc
57import SourceSyntax.PrettyPrint
@@ -29,12 +31,12 @@ data Expr t v
2931 | Modify (LExpr t v) [(String, LExpr t v)]
3032 | Record [(String, LExpr t v)]
3133 | Markdown Pandoc.Pandoc
32− deriving (Eq, Show)
34+ deriving (Eq, Show, Data, Typeable)
3335
3436data Def tipe var
3537 = Def Pattern.Pattern (LExpr tipe var)
3638 | TypeAnnotation String Type.Type
37− deriving (Eq, Show)
39+ deriving (Eq, Show, Data, Typeable)
3840
3941tuple es = Data ("_Tuple" ++ show (length es)) es
4042
compiler/SourceSyntax/Type.hs+3−2
@@ -1,6 +1,7 @@
1−
1+{-# LANGUAGE DeriveDataTypeable #-}
22module SourceSyntax.Type where
33
4+import Data.Data
45import qualified Data.Map as Map
56import SourceSyntax.PrettyPrint
67import Text.PrettyPrint as P
@@ -10,7 +11,7 @@ data Type = Lambda Type Type
1011 | Data String [Type]
1112 | EmptyRecord
1213 | Record (Map.Map String [Type]) Type
13− deriving (Eq, Show)
14+ deriving (Eq, Show, Data, Typeable)
1415
1516fieldMap :: [(String,Type)] -> Map.Map String [Type]
1617fieldMap fields =
compiler/Transform/Check.hsnew file+86
@@ -0,0 +1,86 @@
1+module Transform.Check (mistakes) where
2+
3+import Transform.SortDefinitions (boundVars)
4+import SourceSyntax.Everything
5+import qualified SourceSyntax.Type as T
6+import Data.List as List
7+import qualified Data.Map as Map
8+import qualified Data.Set as Set
9+import Data.Data
10+import Data.Generics.Uniplate.Data
11+
12+
13+mistakes :: (Data t, Data v) => [Declaration t v] -> [String]
14+mistakes decls =
15+ concatMap (\defs -> duplicates defs ++ badOrder defs) (getLets decls)
16+
17+
18+getLets :: (Data t, Data v) => [Declaration t v] -> [[Def t v]]
19+getLets decls = defs : concatMap getSubLets defs
20+ where
21+ defs = concatMap (\d -> case d of Definition d -> [d] ; _ -> []) decls
22+
23+ getSubLets def =
24+ case def of
25+ Def pattern expr -> [ defs | Let defs _ <- universeBi expr ]
26+ TypeAnnotation _ _ -> []
27+
28+
29+duplicates :: [Def t v] -> [String]
30+duplicates defs =
31+ map defMsg (dup definition) ++ map annMsg (dup annotation)
32+ where
33+ dup f = map head . filter ((>1) . length) . List.group . List.sort $ concatMap f defs
34+
35+ msg = "Syntax Error: There can only be one "
36+ defMsg x = msg ++ " definition of '" ++ x ++ "'."
37+ annMsg x = msg ++ " type annotation for '" ++ x ++ "'."
38+
39+
40+badOrder :: [Def t v] -> [String]
41+badOrder defs =
42+ map msg $ missings (List.sort $ expectedPairs as ds) (List.sort $ actualPairs defs)
43+ where
44+ msg x = "Syntax Error: The type annotation for '" ++ x ++
45+ "' must be directly above its definition."
46+ as = List.sort $ concatMap annotation defs
47+ ds = List.sort $ concatMap definition defs
48+
49+ expectedPairs :: [String] -> [String] -> [String]
50+ expectedPairs as ds =
51+ case (as,ds) of
52+ (x:xs, y:ys) -> case compare x y of
53+ LT -> expectedPairs xs (y:ys)
54+ EQ -> x : expectedPairs xs ys
55+ GT -> expectedPairs (x:xs) ys
56+ ( _ , _ ) -> []
57+
58+ actualPairs defs =
59+ case defs of
60+ TypeAnnotation name _ : Def (PVar name') _ : rest ->
61+ (if name == name' then [name] else []) ++ actualPairs rest
62+ t:s:rest -> actualPairs (s:rest)
63+ _ -> []
64+
65+ missings :: [String] -> [String] -> [String]
66+ missings expected actual =
67+ case (expected, actual) of
68+ (e:es, a:as) -> case compare e a of
69+ LT -> e : missings es (a:as)
70+ EQ -> missings es as
71+ GT -> a : missings (e:es) as
72+ ( [] , _ ) -> actual
73+ ( _ , [] ) -> expected
74+
75+
76+annotation :: Def t v -> [String]
77+annotation def =
78+ case def of
79+ TypeAnnotation name _ -> [name]
80+ _ -> []
81+
82+definition :: Def t v -> [String]
83+definition def =
84+ case def of
85+ Def pattern _ -> Set.toList (boundVars pattern)
86+ _ -> []