2013-12-15 07:29:39 +00:00
|
|
|
module Build.Source (build) where
|
2013-12-15 05:46:15 +00:00
|
|
|
|
|
|
|
import Data.Data
|
|
|
|
import Control.Monad.State
|
|
|
|
import qualified Data.Graph as Graph
|
|
|
|
import qualified Data.List as List
|
|
|
|
import qualified Data.Map as Map
|
|
|
|
import qualified Data.Set as Set
|
|
|
|
import System.Directory
|
|
|
|
import System.Exit
|
|
|
|
import System.FilePath as FP
|
|
|
|
import Text.PrettyPrint (Doc)
|
|
|
|
|
2013-12-22 23:18:16 +00:00
|
|
|
import SourceSyntax.Declaration
|
|
|
|
import SourceSyntax.Module
|
|
|
|
import qualified SourceSyntax.Expression as Expr
|
2013-12-15 05:46:15 +00:00
|
|
|
import qualified SourceSyntax.Type as Type
|
|
|
|
import qualified Parse.Parse as Parse
|
|
|
|
import qualified Metadata.Prelude as Prelude
|
|
|
|
import qualified Transform.Check as Check
|
|
|
|
import qualified Transform.SortDefinitions as SD
|
|
|
|
import qualified Type.Inference as TI
|
|
|
|
import qualified Type.Constrain.Declaration as TcDecl
|
|
|
|
import qualified Transform.Canonicalize as Canonical
|
|
|
|
|
|
|
|
build :: Bool -> Interfaces -> String -> Either [Doc] (MetadataModule () ())
|
|
|
|
build noPrelude interfaces source =
|
|
|
|
do let add = if noPrelude then id else Prelude.add
|
|
|
|
infixes = Map.fromList . map (\(assoc,lvl,op) -> (op,(lvl,assoc)))
|
|
|
|
. concatMap iFixities $ Map.elems interfaces
|
|
|
|
|
|
|
|
modul@(Module _ _ _ decls') <- add `fmap` Parse.program infixes source
|
|
|
|
|
|
|
|
-- check for structural errors
|
|
|
|
Module names exs ims decls <-
|
|
|
|
case Check.mistakes decls' of
|
|
|
|
[] -> return modul
|
|
|
|
ms -> Left ms
|
|
|
|
|
|
|
|
let exports'
|
|
|
|
| null exs =
|
|
|
|
let get = Set.toList . SD.boundVars in
|
2013-12-22 23:18:16 +00:00
|
|
|
concat [ get pattern | Definition (Expr.Def pattern _) <- decls ] ++
|
2013-12-15 05:46:15 +00:00
|
|
|
concat [ map fst ctors | Datatype _ _ ctors <- decls ] ++
|
|
|
|
[ name | TypeAlias name _ (Type.Record _ _) <- decls ]
|
|
|
|
| otherwise = exs
|
|
|
|
|
|
|
|
metaModule <- Canonical.metadataModule interfaces $ MetadataModule {
|
|
|
|
names = names,
|
|
|
|
path = FP.joinPath names,
|
|
|
|
exports = exports',
|
|
|
|
imports = ims,
|
|
|
|
-- reorder AST into strongly connected components
|
2013-12-22 23:18:16 +00:00
|
|
|
program = SD.sortDefs . Expr.dummyLet $ TcDecl.toExpr decls,
|
2013-12-15 05:46:15 +00:00
|
|
|
types = Map.empty,
|
|
|
|
datatypes = [ (name,vars,ctors) | Datatype name vars ctors <- decls ],
|
|
|
|
fixities = [ (assoc,level,op) | Fixity assoc level op <- decls ],
|
|
|
|
aliases = [ (name,tvs,tipe) | TypeAlias name tvs tipe <- decls ],
|
|
|
|
foreignImports = [ (evt,v,name,typ) | ImportEvent evt v name typ <- decls ],
|
|
|
|
foreignExports = [ (evt,name,typ) | ExportEvent evt name typ <- decls ]
|
|
|
|
}
|
|
|
|
|
|
|
|
types <- TI.infer interfaces metaModule
|
|
|
|
|
|
|
|
return $ metaModule { types = types }
|