PageRenderTime 46ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/Dedukti/Driver/Compile.hs

https://github.com/polux/dedukti
Haskell | 78 lines | 55 code | 8 blank | 15 comment | 0 complexity | 8bc66a0e5c0f79dc6837e04a3381b986 MD5 | raw file
Possible License(s): GPL-3.0
  1. -- |
  2. -- Copyright : © 2009 CNRS - École Polytechnique - INRIA
  3. -- License : GPL
  4. --
  5. -- Compile one file to Haskell source code.
  6. module Dedukti.Driver.Compile (compile, compileAST) where
  7. import Dedukti.Module
  8. import Dedukti.Parser
  9. import qualified Dedukti.Parser.Interface as Interface
  10. import Dedukti.DkM
  11. import Dedukti.Core
  12. import Dedukti.Analysis.Dependency
  13. import Dedukti.Analysis.Scope
  14. import Control.Applicative
  15. import qualified Dedukti.CodeGen.Exts as CG
  16. import qualified Dedukti.Rule as Rule
  17. import qualified Dedukti.Analysis.Rule as Rule
  18. import qualified Data.ByteString.Lazy.Char8 as B
  19. import qualified Data.Set as Set
  20. -- | Qualify all occurrences of identifiers defined in current module.
  21. selfQualify :: MName -> [Pa RuleSet] -> [Pa RuleSet]
  22. selfQualify mod rsets = let defs = Set.fromList (map rs_name rsets)
  23. in map (descend (f defs))
  24. (map (\RS{..} -> RS{rs_name = qualify mod rs_name, ..}) rsets)
  25. where f defs (Var x a) | Nothing <- provenance x
  26. , x `Set.member` defs = Var (qualify mod x) a
  27. f defs (Lam (x ::: ty) t a) =
  28. Lam (x ::: f defs ty) (f (Set.delete x defs) t) a
  29. f defs (Pi (x ::: ty) t a) =
  30. Pi (x ::: f defs ty) (f (Set.delete x defs) t) a
  31. f defs t = descend (f defs) (t :: Pa Expr)
  32. -- | Read the interface file of each module name to collect the declarations
  33. -- exported by the module.
  34. populateInitialEnvironment :: [MName] -> DkM Context
  35. populateInitialEnvironment deps =
  36. initContext . concat <$>
  37. mapM (\dep -> let path = ifacePathFromModule dep
  38. in map (qualify dep) . Interface.parse path <$>
  39. io (B.readFile path)) deps
  40. -- | Generate the content of an interface file.
  41. interface :: Pa Module -> B.ByteString
  42. interface (decls, _) = B.unlines (map (fromAtom . qid_stem . bind_name) decls)
  43. -- | Emit Haskell code for one module.
  44. compile :: MName -> DkM ()
  45. compile mod = do
  46. say Verbose $ text "Parsing" <+> text (show mod) <+> text "..."
  47. let path = srcPathFromModule mod
  48. config <- configuration
  49. compileAST mod =<< return (parse config path) `ap` io (B.readFile path)
  50. -- | Emit Haskell code for one module, starting from the AST.
  51. compileAST :: MName -> Pa Module -> DkM ()
  52. compileAST mod src@(decls, rules) = do
  53. let deps = collectDependencies src
  54. -- For the purposes of scope checking it is necessary to load in the
  55. -- environment all those declarations from immediate dependencies. For this
  56. -- we read an interface file, much faster to parse than the actual
  57. -- dependencies themselves.
  58. say Verbose $ text "Populating environment for" <+> text (show mod) <+> text "..."
  59. extdecls <- populateInitialEnvironment deps
  60. say Verbose $ text "Checking" <+> text (show mod) <+> text "..."
  61. checkUniqueness src
  62. checkScopes extdecls src
  63. Rule.checkOrdering rules
  64. say Verbose $ text "Checking well formation of rule heads ..."
  65. mapM_ Rule.checkHead rules
  66. say Debug $ pretty $ Rule.ruleSets decls rules
  67. say Verbose $ text "Compiling" <+> text (show mod) <+> text "..."
  68. let code = map CG.emit (selfQualify mod (Rule.ruleSets decls rules)) :: [CG.Code]
  69. io $ B.writeFile (objPathFromModule mod) $ CG.serialize mod deps $ CG.coalesce code
  70. io $ B.writeFile (ifacePathFromModule mod) $ interface src