root/src/Pugs/External/Haskell.hs

Revision 21673, 3.7 kB (checked in by audreyt, 4 months ago)

* Import Pugs 6.2.13.11 from Hackage into our source tree.
* Highlights:

  • Much faster startup time
  • Slightly faster compilation time (mostly due to refactored Pugs.AST.Internals)
  • Portable-to-Win32 readline thanks to Haskeline
  • Property svn:mime-type set to text/plain; charset=UTF-8
  • Property svn:eol-style set to native
Line 
1{-# OPTIONS_GHC -fglasgow-exts -cpp #-}
2
3-- -fth -cpp -package plugins #-}
4
5module Pugs.External.Haskell where
6import Pugs.AST
7
8#undef PUGS_HAVE_TH
9-- #include "../pugs_config.h"
10#if !defined(PUGS_HAVE_TH) || !defined(PUGS_HAVE_HSPLUGINS)
11externalizeHaskell :: String -> String -> IO String
12externalizeHaskell  = error "Template Haskell support not compiled in"
13loadHaskell :: FilePath -> IO [(String, [Val] -> Eval Val)]
14loadHaskell         = error "Template Haskell support not compiled in"
15#else
16
17import Language.Haskell.TH as TH
18import Language.Haskell.Parser
19import Language.Haskell.Syntax
20import System.Plugins
21import Pugs.Config
22import Pugs.Internals
23
24{- ourPackageConfigs :: [PackageConfig]
25ourPackageConfigs = [
26    PackageConfig {
27        hs_libraries = ["Unicode.o"]
28        extra_libraries = ["UnicodeC.o"]
29    }
30] -}
31ourPackageConfigs :: [a]
32ourPackageConfigs = []
33
34loadOrDie
35     :: FilePath                -- ^ object file
36     -> [FilePath]              -- ^ any include paths
37     -> [FilePath]              -- ^ list of package.conf paths
38     -> String                  -- ^ symbol to find
39     -> IO (a)
40loadOrDie obj includes configs symbol = do
41    stat <- load obj includes configs symbol
42    case stat of
43        LoadFailure errs -> error $ unlines $ ["Error loading "++symbol++" from "++obj] ++ errs
44        LoadSuccess _ a  -> return a
45
46loadHaskell :: FilePath -> IO [(String, [Val] -> Eval Val)]
47loadHaskell file = do
48    let coredir   = getConfig "installarchlib" ++ "/CORE/pugs/"
49        objDir    = getConfig "installsitearch"
50        objFile   = (objDir ++ "/" ++ file)
51        loadpaths = [coredir, objDir]
52    -- For Unicode
53    loadRawObject $ coredir++"UnicodeC.o"
54    -- For RRegex
55    loadRawObject $ coredir++"pcre/pcre.o"
56   
57    -- AST has early requirements and late requirements, because of recrusivity. 
58    -- The logic for this should probably be moved to hs-plugins, but do it here
59    -- for now.
60    {-
61    mapM
62        (\n -> load (coredir++n++".o") loadpaths ourPackageConfigs "")
63        ["Compat", "Cont", "Embed", "Embed/Perl5", "Internals", "RRegex", "RRegex/PCRE", "RRegex/Syntax", "Rule/Pos", "UTF8", "Unicode", "AST"]
64    -}
65
66    (extern :: [String]) <- loadOrDie objFile loadpaths ourPackageConfigs "extern__"
67    -- print (">"++(show extern)++"<")
68    (`mapM` extern) $ \name -> do
69        func <- loadOrDie objFile loadpaths ourPackageConfigs ("extern__" ++ name)
70        return (name, func)
71
72externalizeHaskell :: String -> String -> IO String
73#ifndef HADDOCK
74externalizeHaskell mod code = do
75    let names = map snd exports
76    symTable <- runQ [d|
77        extern__ :: [String]
78        extern__ = names
79        |]
80    symDecls <- mapM wrap names
81    return $ unlines $
82        [ "module " ++ mod ++ " where"
83        , "import Internals"
84        , "import GHC.Base"
85        , "import AST"
86        , ""
87        , code
88        , ""
89        , "-- below are automatically generated by Pugs --"
90        , TH.pprint symTable
91        , TH.pprint symDecls
92        ]
93    where
94    exports :: [(HsQualType, String)]
95    exports = concat [ [ (typ, name) | HsIdent name <- names ]
96                     | HsTypeSig _ names typ <- parsed
97                     ]
98    parsed = case parseModule code of
99        ParseOk (HsModule _ _ _ _ decls) -> decls
100        ParseFailed _ err -> error err
101#endif
102
103wrap :: String -> IO Dec
104#ifndef HADDOCK
105wrap fun = do
106    [quoted] <- runQ [d|
107            name :: [Val] -> Eval Val
108            name = \[v] -> do
109                s <- fromVal v
110                return (castV ($(dyn fun) s))
111        |]
112    return $ munge quoted ("extern__" ++ fun)
113#endif
114
115munge :: Dec -> String -> Dec
116munge (ValD _ x y) name = ValD (VarP (mkName name)) x y
117munge _ _ = error "impossible"
118
119
120
121#endif
Note: See TracBrowser for help on using the browser.