on master help sign in
Revamp compilation process

The old code went directly from a ByteString to the compile artifacts. This had the downsides of: 1. Parsing had to happen along with the rest of the process. So we had to parse the header to crawl, and then parse the header again when compiling. 2. It always constructed the interface for the file. This is necessary for any `elm make` call, but it is not needed for `elm repl`. In the REPL, it actually makes things a bit trickier since all you really want is the objects and the type of the most recently evaluated expression. So the new approach has you give a Src.Module and gives a less processed set of artifacts. The code has also been cleaned up a bit.

commitefe80bc2d1c51400caaa26294570a69790572380 authorEvan Czaplicki <evancz@users.noreply.github.com> dateFri 22 Feb 2019, 11:43 (8 years ago) parentca9ed29
1 file changed+36−55
compiler/src/Compile.hs+36−55
compiler/src/Compile.hs+36−55
@@ -1,15 +1,16 @@
11{-# OPTIONS_GHC -Wall -fno-warn-unused-do-bind #-}
22module Compile
3− ( compile
4− , Artifacts(..)
3+ ( Artifacts(..)
4+ , compile
55 )
66 where
77
88
9−import qualified Data.ByteString as BS
109import qualified Data.Map as Map
1110import qualified Data.Name as Name
11+import qualified Data.OneOrMore as OneOrMore
1212
13+import qualified AST.Source as Src
1314import qualified AST.Canonical as Can
1415import qualified AST.Optimized as Opt
1516import qualified Canonicalize.Module as Canonicalize
@@ -18,11 +19,9 @@ import qualified Elm.ModuleName as ModuleName
1819import qualified Elm.Package as Pkg
1920import qualified Nitpick.PatternMatches as PatternMatches
2021import qualified Optimize.Module as Optimize
21−import qualified Parse.Module as Parse
22−import qualified Reporting.Error as Error
23−import qualified Reporting.Render.Type.Localizer as L
24−import qualified Reporting.Result as Result
25−import qualified Reporting.Warning as Warning
22+import qualified Reporting.Error as E
23+import qualified Reporting.Result as R
24+import qualified Reporting.Warning as W
2625import qualified Type.Constrain.Module as Type
2726import qualified Type.Solve as Type
2827
@@ -33,71 +32,53 @@ import System.IO.Unsafe (unsafePerformIO)
3332-- COMPILE
3433
3534
36−type Result i a =
37− Result.Result i [Warning.Warning] Error.Error a
38−
39−
40−type ImportDict =
41− Map.Map Name.Name ModuleName.Canonical
42−
43−
4435data Artifacts =
4536 Artifacts
46− { _elmi :: I.Interface
47− , _elmo :: Opt.Graph
37+ { _modul :: Can.Module
38+ , _types :: Map.Map Name.Name Can.Annotation
39+ , _graph :: Opt.Graph
4840 }
4941
5042
51−compile :: Pkg.Name -> ImportDict -> I.Interfaces -> BS.ByteString -> Result i Artifacts
52−compile pkg importDict interfaces source =
53− do
54− valid <- Result.mapError Error.Syntax $
55− Parse.fromByteString pkg source
56−
57− canonical <- Result.mapError Error.Canonicalize $
58− Canonicalize.canonicalize pkg importDict interfaces valid
59−
60− let localizer = L.fromModule valid -- TODO should this be strict for GC?
61−
62− annotations <-
63− runTypeInference localizer canonical
64−
65− () <-
66− exhaustivenessCheck canonical
43+compile :: Pkg.Name -> Map.Map ModuleName.Raw I.Interface -> Src.Module -> ([W.Warning], Either (OneOrMore.OneOrMore E.Error) Artifacts)
44+compile pkg ifaces modul =
45+ R.run $
46+ do canonical <- canonicalize pkg ifaces modul
47+ annotations <- typeCheck canonical
48+ () <- nitpick canonical
49+ objects <- optimize annotations canonical
50+ return (Artifacts canonical annotations objects)
6751
68− graph <- Result.mapError (Error.Main localizer) $
69− Optimize.optimize annotations canonical
7052
71− Result.ok $
72− Artifacts
73− { _elmi = I.fromModule annotations canonical
74− , _elmo = graph
75− }
7653
54+-- PHASES
7755
7856
79−-- TYPE INFERENCE
57+canonicalize :: Pkg.Name -> Map.Map ModuleName.Raw I.Interface -> Src.Module -> R.Result i [W.Warning] E.Error Can.Module
58+canonicalize pkg ifaces modul =
59+ R.mapError E.Canonicalize $ Canonicalize.canonicalize pkg ifaces modul
8060
8161
82−runTypeInference :: L.Localizer -> Can.Module -> Result i (Map.Map Name.Name Can.Annotation)
83−runTypeInference localizer canonical =
62+typeCheck :: Can.Module -> R.Result i w E.Error (Map.Map Name.Name Can.Annotation)
63+typeCheck canonical =
8464 case unsafePerformIO (Type.run =<< Type.constrain canonical) of
8565 Right annotations ->
86− Result.ok annotations
66+ R.ok annotations
8767
8868 Left errors ->
89− Result.throw (Error.Type localizer errors)
69+ R.throw (E.Type errors)
9070
9171
92−
93−-- EXHAUSTIVENESS CHECK
94−
95−
96−exhaustivenessCheck :: Can.Module -> Result i ()
97−exhaustivenessCheck canonical =
72+nitpick :: Can.Module -> R.Result i w E.Error ()
73+nitpick canonical =
9874 case PatternMatches.check canonical of
75+ Right () ->
76+ R.ok ()
77+
9978 Left errors ->
100− Result.throw (Error.Pattern errors)
79+ R.throw (E.Pattern errors)
10180
102− Right () ->
103− Result.ok ()
81+
82+optimize :: Map.Map Name.Name Can.Annotation -> Can.Module -> R.Result i [W.Warning] E.Error Opt.Graph
83+optimize annotations canonical =
84+ R.mapError E.Main $ Optimize.optimize annotations canonical