Ivory.hs 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. module Gidl.Backend.Ivory where
  2. import Ivory.Artifact
  3. import Ivory.Artifact.Template
  4. import Data.Char (isSpace)
  5. import Data.List (intercalate, nub)
  6. import qualified Paths_gidl as P
  7. import Gidl.Interface
  8. import Gidl.Schema
  9. import Gidl.Backend.Cabal
  10. import Gidl.Backend.Ivory.Types
  11. import Gidl.Backend.Ivory.Schema
  12. ivoryBackend :: [Interface] -> String -> String -> [Artifact]
  13. ivoryBackend iis pkgname namespace_raw =
  14. [ cabalFileArtifact cf
  15. , makefile
  16. , artifactCabalFile P.getDataDir "Makefile.sandbox"
  17. , depsfile
  18. , artifactPath "tests" $ codegenTest namespace
  19. ] ++ map (artifactPath "src") sources
  20. where
  21. sources = ivorySources iis namespace
  22. namespace = dotwords namespace_raw
  23. cf = (defaultCabalFile pkgname cabalmods cabalDeps) { executables = [ cg_exe ] }
  24. cg_exe = defaultCabalExe (pkgname ++ "-gen") "CodeGen.hs"
  25. (cabalDeps ++ cabalExeDeps ++ [pkgname])
  26. cabalmods = map (filePathToPackage . artifactFileName) sources
  27. (makeDeps, cabalDeps) = unzip ivoryDeps
  28. (makeExeDeps, cabalExeDeps) = unzip ivoryTestDeps
  29. sandwich a b c = a ++ c ++ b
  30. depsfile = artifactString "Makefile.deps" $ unlines $
  31. sandwich ["$(call add-cabal-package-source, \\"] [")"] $
  32. map (sandwich " " " \\") $
  33. makeDeps ++ makeExeDeps
  34. ivoryDeps :: [(String, String)]
  35. ivoryDeps =
  36. [ ("$(IVORY_REPO)/ivory", "ivory")
  37. , ("$(IVORY_REPO)/ivory-serialize", "ivory-serialize")
  38. , ("$(IVORY_REPO)/ivory-stdlib", "ivory-stdlib")
  39. ]
  40. ivoryTestDeps :: [(String, String)]
  41. ivoryTestDeps =
  42. [ ("$(IVORY_REPO)/ivory-backend-c", "ivory-backend-c")
  43. ]
  44. ivorySources :: [Interface] -> [String] -> [Artifact]
  45. ivorySources iis namespace =
  46. tmods ++ concat smods ++ [ typeUmbrella namespace userDefinedTypes
  47. , unpackModule namespace
  48. ]
  49. where
  50. userDefinedTypes = nub [ t | i <- iis, t <- interfaceTypes i, isUserDefined t ]
  51. tmods = [ typeModule (namespace ++ ["Types"]) t
  52. | t <- userDefinedTypes ]
  53. smods = [ [ schemaModule (namespace ++ ["Interface"]) i (producerSchema i)
  54. , schemaModule (namespace ++ ["Interface"]) i (consumerSchema i) ]
  55. | i <- iis ]
  56. dotwords :: String -> [String]
  57. dotwords s = case dropWhile isDot s of
  58. "" -> []
  59. s' -> let (w, s'') = break isDot s' in w : dotwords s''
  60. where
  61. isDot c = (c == '.') || isSpace c
  62. makefile :: Artifact
  63. makefile = artifactCabalFile P.getDataDir "support/ivory/Makefile"
  64. codegenTest :: [String] -> Artifact
  65. codegenTest modulepath =
  66. artifactCabalFileTemplate P.getDataDir fname
  67. [("module_path", intercalate "." modulepath )]
  68. where
  69. fname = "support/ivory/CodeGen.hs.template"
  70. unpackModule :: [String] -> Artifact
  71. unpackModule modulepath =
  72. artifactPath (intercalate "/" modulepath) $
  73. artifactCabalFileTemplate P.getDataDir fname
  74. [("module_path", intercalate "." modulepath )]
  75. where
  76. fname = "support/ivory/Unpack.hs.template"