on master help sign in
Finish parameterizing the AST and properly check errors in let expressions.
commit35981eb42fd34111af4d2eed00d455a45dda1118 authorevancz <info@elm-lang.org> dateFri 14 Jun 2013, 19:23 (13 years ago) parent5e7be20
5 files changed+71−47
Elm.cabal+2 compiler/Compiler.hs+1−1 compiler/Initialize.hs+5−5 compiler/Language/Elm.hs+2 compiler/Types/Alias.hs+61−41
Elm.cabal+2
@@ -81,6 +81,7 @@ Library
8181 template-haskell,
8282 pandoc >= 1.10,
8383 bytestring,
84+ uniplate,
8485 hjsmin,
8586 indents,
8687 filepath,
@@ -136,6 +137,7 @@ Executable elm
136137 cmdargs,
137138 pandoc >= 1.10,
138139 bytestring,
140+ uniplate,
139141 hjsmin,
140142 indents,
141143 filepath,
compiler/Compiler.hs+1−1
@@ -102,7 +102,7 @@ buildFile flags moduleNum numModules filePath =
102102 if takeExtension filePath == ".js" then return ("",source) else
103103 case buildFromSource (no_prelude flags) source of
104104 Left err -> putStrLn err >> exitFailure
105− Right modul -> do exs <- exportInfo modul
105+ Right modul -> do exs <- exportInfo (modul :: Module () String)
106106 return (exs, jsModule modul)
107107 createDirectoryIfMissing True (output_directory flags)
108108 writeFile (elmo flags filePath) obj
compiler/Initialize.hs+5−5
@@ -4,7 +4,7 @@ import Control.Applicative ((<$>))
44import Control.Monad.Error
55import Data.List (lookup,nub)
66import qualified Data.Map as Map
7−
7+import Data.Data
88import SourceSyntax.Everything
99import Data.List (intercalate,partition)
1010import Parse.Parser (parseProgram, parseDependencies)
@@ -17,21 +17,21 @@ import Transform.Optimize
1717import System.Exit
1818import System.FilePath
1919
20−checkMistakes :: Module t v -> Either String (Module t v)
20+checkMistakes :: (Data t, Data v) => Module t v -> Either String (Module t v)
2121checkMistakes modul@(Module name ex im stmts) =
2222 case mistakes stmts of
2323 m:ms -> Left (unlines (m:ms))
2424 [] -> return modul
2525
26−checkTypes :: Module t v -> Either String (Module t v)
26+checkTypes :: (Data t, Data v) => Module t v -> Either String (Module t v)
2727checkTypes modul =
2828 do subs <- unify hints modul
2929 subs `seq` return (optimize (renameModule modul))
3030
31−check :: Module t v -> Either String (Module t v)
31+check :: (Data t, Data v) => Module t v -> Either String (Module t v)
3232check = checkMistakes >=> checkTypes
3333
34−buildFromSource :: Bool -> String -> Either String (Module t v)
34+buildFromSource :: (Data t, Data v) => Bool -> String -> Either String (Module t v)
3535buildFromSource noPrelude src =
3636 let add = if noPrelude then id else Libs.addPrelude in
3737 (check . add) =<< (parseProgram src)
compiler/Language/Elm.hs+2
@@ -18,6 +18,7 @@ import Generate.Html (generateHtml)
1818import Initialize (buildFromSource)
1919import Parse.Helpers
2020import Parse.Module (moduleDef)
21+import SourceSyntax.Module
2122import Text.Blaze.Html (Html)
2223import Text.Parsec (option,optional)
2324import Paths_Elm
@@ -27,6 +28,7 @@ import Paths_Elm
2728compile :: String -> Either String String
2829compile source = fmap jsModule modul
2930 where
31+ modul :: Either String (Module () String)
3032 modul = buildFromSource False source
3133
3234-- |This function extracts the module name of a given source program.
compiler/Types/Alias.hs+61−41
@@ -9,6 +9,7 @@ import qualified Data.Set as Set
99import Types.Substitutions (subst)
1010import Types.Types
1111import Data.Data
12+import Data.Generics.Uniplate.Data
1213
1314builtins :: [(String,([X],Type))]
1415builtins =
@@ -28,13 +29,16 @@ builtins =
2829 ("LineStyle", ([], makeRecord line))
2930 ]
3031
31−get :: [Declaration t v] -> Map.Map String ([X],Type)
32−get stmts = Map.fromList (builtins ++ concatMap getAlias stmts)
33− where getAlias stmt = case stmt of
34− TypeAlias alias xs t -> [(alias, (xs,t))]
35− _ -> []
32+type AliasDict = Map.Map String ([X],Type)
3633
37−dealias :: Map.Map String ([X],Type) -> Type -> Type
34+get :: [Declaration t v] -> AliasDict
35+get decl = Map.fromList (builtins ++ concatMap getAlias decl)
36+ where
37+ getAlias decl = case decl of
38+ TypeAlias alias xs t -> [(alias, (xs,t))]
39+ _ -> []
40+
41+dealias :: AliasDict -> Type -> Type
3842dealias aliases t =
3943 let f = dealias aliases in
4044 case t of
@@ -45,38 +49,54 @@ dealias aliases t =
4549 RecordT r t -> RecordT (Map.map (map f) r) (f t)
4650 _ -> t
4751
48−mistakes :: [Declaration t v] -> [String]
49−mistakes stmts = badKinds stmts ++ dups stmts ++ badOrder stmts
52+--mistakes :: [Def t v] -> [String]
53+mistakes defs = badKinds defs -- ++ dups defs ++ badOrder defs
54+
55+extractDefs :: [Declaration t v] -> [Def t v]
56+extractDefs = concatMap keepDef
57+ where
58+ keepDef decl = case decl of
59+ Definition def -> [def]
60+ _ -> []
5061
51−badKinds :: [Declaration t v] -> [String]
52−badKinds stmts = map msg (concatMap badS stmts)
62+badKinds :: (Data t, Data v) => [Declaration t v] -> [String]
63+badKinds decls = map msg (concatMap bad decls)
5364 where
5465 msg x = "Type Error: Type alias '" ++ x ++
5566 "' was given the wrong number of arguments."
5667
57− badT :: Type -> [String]
58− badT t =
59− case t of
60− ADT name ts ->
61− case Map.lookup name (get stmts) of
62− Just (xs,t) | length xs == length ts -> []
63− | otherwise -> [name]
64− Nothing -> concatMap badT ts
65− LambdaT t u -> badT t ++ badT u
66− RecordT r t -> badT t ++ concatMap badT (concat (Map.elems r))
67− _ -> []
68−
69− badS :: Declaration t v -> [String]
70− badS s =
68+ aliases :: AliasDict
69+ aliases = Map.empty
70+
71+ badType :: Type -> [String]
72+ badType t =
73+ case t of
74+ ADT name ts ->
75+ case Map.lookup name aliases of
76+ Just (xs,t) | length xs == length ts -> []
77+ | otherwise -> [name]
78+ Nothing -> concatMap badType ts
79+ LambdaT t u -> badType t ++ badType u
80+ RecordT r t -> badType t ++ concatMap badType (concat (Map.elems r))
81+ _ -> []
82+
83+ --badDef :: AliasDict -> Def t v -> [String]
84+ badDef def =
85+ case def of
86+ TypeAnnotation _ tipe -> badType tipe
87+ FnDef _ _ expr ->
88+ concatMap badDef $ concat [defList | Let defList _ <- universeBi expr]
89+ OpDef _ _ _ expr ->
90+ concatMap badDef $ concat [defList | Let defList _ <- universeBi expr]
91+
92+ --bad :: Declaration t v -> [String]
93+ bad s =
7194 case s of
72− Datatype _ _ tcs -> concatMap badT (concatMap snd tcs)
73− ExportEvent _ _ tipe -> badT tipe
74− ImportEvent _ _ _ tipe -> badT tipe
75− TypeAlias _ _ tipe -> badT tipe
76− Definition d ->
77− case d of
78− TypeAnnotation _ tipe -> badT tipe
79− _ -> []
95+ Datatype _ _ tcs -> concatMap badType (concatMap snd tcs)
96+ ExportEvent _ _ tipe -> badType tipe
97+ ImportEvent _ _ _ tipe -> badType tipe
98+ TypeAlias _ _ tipe -> badType tipe
99+ Definition d -> badDef d
80100
81101annotation :: Declaration t v -> [String]
82102annotation s =
@@ -97,22 +117,22 @@ defName d =
97117 OpDef n _ _ _ -> n
98118
99119dups :: [Declaration t v] -> [String]
100−dups stmts = map defMsg (dup definition) ++ map annMsg (dup annotation)
120+dups defs = map defMsg (dup definition) ++ map annMsg (dup annotation)
101121 where
102122 --dup :: (Declaration t v -> [String]) -> [String]
103− dup f = map head . filter ((>1) . length) . group . sort $ concatMap f stmts
123+ dup f = map head . filter ((>1) . length) . group . sort $ concatMap f defs
104124
105125 msg = "Syntax Error: There can only be one "
106126 defMsg x = msg ++ "top-level definition of '" ++ x ++ "'."
107127 annMsg x = msg ++ "type annotation for '" ++ x ++ "'."
108128
109−badOrder :: [Declaration t v] -> [String]
110−badOrder stmts = map msg $ missings (sort $ expectedPairs as ds) (sort $ actualPairs stmts)
129+--badOrder :: [Def t v] -> [String]
130+badOrder defs = map msg $ missings (sort $ expectedPairs as ds) (sort $ actualPairs defs)
111131 where
112132 msg x = "Syntax Error: The type annotation for '" ++ x ++
113133 "' must be directly above its definition."
114− as = sort $ concatMap annotation stmts
115− ds = sort $ concatMap definition stmts
134+ as = sort $ concatMap annotation defs
135+ ds = sort $ concatMap definition defs
116136
117137 expectedPairs :: [String] -> [String] -> [String]
118138 expectedPairs as ds =
@@ -123,9 +143,9 @@ badOrder stmts = map msg $ missings (sort $ expectedPairs as ds) (sort $ actualP
123143 GT -> expectedPairs (x:xs) ys
124144 ( _ , _ ) -> []
125145
126− --actualPairs :: [Declaration t v] -> [String]
127− actualPairs stmts =
128− case stmts of
146+ --actualPairs :: [Def t v] -> [String]
147+ actualPairs defs =
148+ case defs of
129149 Definition (TypeAnnotation n _) : Definition d : rest ->
130150 (if n == defName d then [n] else []) ++ actualPairs rest
131151 t:s:rest -> actualPairs (s:rest)