{-# OPTIONS_GHC -Wall -fno-warn-unused-do-bind #-} module Compile ( compile , Artifacts(..) ) where import qualified Data.ByteString as BS import qualified Data.Map as Map import qualified Data.Name as Name import qualified AST.Canonical as Can import qualified AST.Optimized as Opt import qualified Canonicalize.Module as Canonicalize import qualified Elm.Interface as I import qualified Elm.ModuleName as ModuleName import qualified Elm.Package as Pkg import qualified Nitpick.PatternMatches as PatternMatches import qualified Optimize.Module as Optimize import qualified Parse.Module as Parse import qualified Reporting.Error as Error import qualified Reporting.Render.Type.Localizer as L import qualified Reporting.Result as Result import qualified Reporting.Warning as Warning import qualified Type.Constrain.Module as Type import qualified Type.Solve as Type import System.IO.Unsafe (unsafePerformIO) -- COMPILE type Result i a = Result.Result i [Warning.Warning] Error.Error a type ImportDict = Map.Map Name.Name ModuleName.Canonical data Artifacts = Artifacts { _elmi :: I.Interface , _elmo :: Opt.Graph } compile :: Pkg.Name -> ImportDict -> I.Interfaces -> BS.ByteString -> Result i Artifacts compile pkg importDict interfaces source = do valid <- Result.mapError Error.Syntax $ Parse.fromByteString pkg source canonical <- Result.mapError Error.Canonicalize $ Canonicalize.canonicalize pkg importDict interfaces valid let localizer = L.fromModule valid -- TODO should this be strict for GC? annotations <- runTypeInference localizer canonical () <- exhaustivenessCheck canonical graph <- Result.mapError (Error.Main localizer) $ Optimize.optimize annotations canonical Result.ok $ Artifacts { _elmi = I.fromModule annotations canonical , _elmo = graph } -- TYPE INFERENCE runTypeInference :: L.Localizer -> Can.Module -> Result i (Map.Map Name.Name Can.Annotation) runTypeInference localizer canonical = case unsafePerformIO (Type.run =<< Type.constrain canonical) of Right annotations -> Result.ok annotations Left errors -> Result.throw (Error.Type localizer errors) -- EXHAUSTIVENESS CHECK exhaustivenessCheck :: Can.Module -> Result i () exhaustivenessCheck canonical = case PatternMatches.check canonical of Left errors -> Result.throw (Error.Pattern errors) Right () -> Result.ok ()