| 1 | {-# OPTIONS_GHC -fglasgow-exts #-} |
|---|
| 2 | |
|---|
| 3 | {-| |
|---|
| 4 | Code generation interface. |
|---|
| 5 | |
|---|
| 6 | > I sit beside the fire and think |
|---|
| 7 | > of all that I have seen, |
|---|
| 8 | > of meadow-flowers and butterflies |
|---|
| 9 | > in summers that have been... |
|---|
| 10 | -} |
|---|
| 11 | |
|---|
| 12 | module Pugs.CodeGen (codeGen, backends) where |
|---|
| 13 | import Pugs.AST |
|---|
| 14 | import Pugs.Pretty |
|---|
| 15 | import Pugs.Internals |
|---|
| 16 | import Pugs.CodeGen.PIL1 (genPIL1) |
|---|
| 17 | -- import Pugs.CodeGen.PIL2 (genPIL2, genPIL2Perl5, genPIL2JSON, genPIL2YAML) |
|---|
| 18 | import Pugs.CodeGen.PIR (genPIR, genPIR_YAML) |
|---|
| 19 | import Pugs.CodeGen.Perl5 (genPerl5) |
|---|
| 20 | import Pugs.CodeGen.YAML (genParseYAML, genParseHsYAML, genYAML) |
|---|
| 21 | import Pugs.CodeGen.Binary (genParseBinary) |
|---|
| 22 | import Pugs.CodeGen.JSON (genJSON) |
|---|
| 23 | import Pugs.CodeGen.M0ld (genM0ld) |
|---|
| 24 | import Pugs.Compile.Pugs (genPugs) |
|---|
| 25 | -- import Pugs.Compile.Haskell (genGHC) |
|---|
| 26 | -- import Pugs.CodeGen.XML (genXML) |
|---|
| 27 | import qualified Data.Map as Map |
|---|
| 28 | |
|---|
| 29 | type Generator = FilePath -> Eval Val |
|---|
| 30 | |
|---|
| 31 | generators :: Map String Generator |
|---|
| 32 | generators = Map.fromList $ |
|---|
| 33 | [ ("PIR", genPIR) |
|---|
| 34 | , ("PIR-YAML", genPIR_YAML) |
|---|
| 35 | , ("PIL1", genPIL1) |
|---|
| 36 | , ("PIL1-Perl5", genPerl5) |
|---|
| 37 | , ("PIL1-JSON", genJSON) |
|---|
| 38 | , ("PIL1-YAML", genYAML) |
|---|
| 39 | , ("PIL1-M0ld", genM0ld) |
|---|
| 40 | -- , ("PIL2", genPIL2) |
|---|
| 41 | -- , ("PIL2-Perl5", genPIL2Perl5) |
|---|
| 42 | -- , ("PIL2-JSON", genPIL2JSON) |
|---|
| 43 | -- , ("PIL2-YAML", genPIL2YAML) |
|---|
| 44 | -- , ("GHC", genGHC) |
|---|
| 45 | , ("Pugs", genPugs) |
|---|
| 46 | , ("Parse-YAML", genParseYAML) |
|---|
| 47 | , ("Parse-HsYAML",genParseHsYAML) |
|---|
| 48 | , ("Parse-Pretty",const $ fmap (VStr . (++"\n") . pretty) (asks envBody)) |
|---|
| 49 | , ("Parse-Binary",genParseBinary) |
|---|
| 50 | -- , ("XML", genXML) |
|---|
| 51 | ] |
|---|
| 52 | |
|---|
| 53 | backends :: [String] |
|---|
| 54 | backends = Map.keys generators |
|---|
| 55 | |
|---|
| 56 | norm :: String -> String |
|---|
| 57 | norm = norm' . map toLower . filter isAlphaNum |
|---|
| 58 | where |
|---|
| 59 | norm' "ghc" = "GHC" |
|---|
| 60 | norm' "parrot" = "!PIR" |
|---|
| 61 | norm' "pir" = "PIR" |
|---|
| 62 | norm' "piryaml"= "PIR-YAML" |
|---|
| 63 | norm' "pil" = "!PIL1" |
|---|
| 64 | norm' "pil1" = "PIL1" |
|---|
| 65 | -- norm' "pil2" = "PIL2" |
|---|
| 66 | norm' "perl5" = "!PIL1-Perl5" |
|---|
| 67 | norm' "m0ld" = "PIL1-M0ld" |
|---|
| 68 | norm' "json" = "!PIL1-JSON" |
|---|
| 69 | norm' "yaml" = "!PIL1-YAML" |
|---|
| 70 | norm' "pil1perl5" = "PIL1-Perl5" |
|---|
| 71 | norm' "pil1json" = "PIL1-JSON" |
|---|
| 72 | norm' "pil1yaml" = "PIL1-YAML" |
|---|
| 73 | -- norm' "pil2perl5" = "PIL2-Perl5" |
|---|
| 74 | -- norm' "pil2json" = "PIL2-JSON" |
|---|
| 75 | -- norm' "pil2yaml" = "PIL2-YAML" |
|---|
| 76 | norm' "parseyaml" = "Parse-YAML" |
|---|
| 77 | norm' "parsehsyaml"= "Parse-HsYAML" |
|---|
| 78 | norm' "parsepretty"= "Parse-Pretty" |
|---|
| 79 | norm' "parsebinary" = "Parse-Binary" |
|---|
| 80 | norm' "pugs" = "Pugs" |
|---|
| 81 | -- norm' "xml" = "XML" |
|---|
| 82 | norm' x = x |
|---|
| 83 | |
|---|
| 84 | doLookup :: String -> IO Generator |
|---|
| 85 | doLookup s = do |
|---|
| 86 | case norm s of |
|---|
| 87 | ('!':key) -> do |
|---|
| 88 | hPutStrLn stderr $ "*** The backend '" ++ s ++ "' is deprecated." |
|---|
| 89 | hPutStrLn stderr $ " Please use '" ++ key ++ "' instead." |
|---|
| 90 | Map.lookup key generators |
|---|
| 91 | key -> Map.lookup key generators |
|---|
| 92 | |
|---|
| 93 | codeGen :: String -> FilePath -> Env -> IO String |
|---|
| 94 | codeGen s file env = do |
|---|
| 95 | gen <- catchIO (doLookup s) . const $ do |
|---|
| 96 | fail $ "Cannot generate code for " ++ s ++ ": " ++ file |
|---|
| 97 | rv <- runEvalIO env (gen file) |
|---|
| 98 | case rv of |
|---|
| 99 | VStr str -> return str |
|---|
| 100 | _ -> fail (show rv) |
|---|