File: Interpreter.hs

package info (click to toggle)
missingpy 0.10.0.2
  • links: PTS, VCS
  • area: main
  • in suites: lenny
  • size: 464 kB
  • ctags: 42
  • sloc: haskell: 1,433; makefile: 129; ansic: 107
file content (164 lines) | stat: -rw-r--r-- 6,107 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
{-# OPTIONS -fallow-overlapping-instances #-}
{- arch-tag: Python interpreter module
Copyright (C) 2005 John Goerzen <jgoerzen@complete.org>

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-}

{- |
   Module     : Python.Interpreter
   Copyright  : Copyright (C) 2005 John Goerzen
   License    : GNU GPL, version 2 or above

   Maintainer : John Goerzen,
   Maintainer : jgoerzen\@complete.org
   Stability  : provisional
   Portability: portable

Interface to Python interpreter

Written by John Goerzen, jgoerzen\@complete.org
-}

module Python.Interpreter (
                          py_initialize,
                          -- * Intrepreting Code
                          pyRun_SimpleString,
                          pyRun_String,
                          pyRun_StringHs,
                          StartFrom(..),
                          -- * Calling Code
                          callByName,
                          callByNameHs,
                          noParms,
                          noKwParms,
                          -- * Imports
                          pyImport,
                          pyImport_ImportModule,
                          pyImport_AddModule,
                          pyModule_GetDict,
                          )
where

import Python.Utils
import Python.Objects
import Python.Types
import Python.ForeignImports
import Foreign
import Foreign.C.String
import Foreign.C
import System.IO.Unsafe

{- | Initialize the Python interpreter environment.

MUST BE DONE BEFORE DOING ANYTHING ELSE! -}
py_initialize :: IO ()
py_initialize = do cpy_initialize
                   pyImport "traceback"


pyRun_SimpleString :: String -> IO ()
pyRun_SimpleString x = withCString x (\cs ->
                                          do cpyRun_SimpleString cs >>= checkCInt
                                             return ()
                                     )

-- | Like 'pyRun_String', but take more Haskellish args and results.
pyRun_StringHs :: (ToPyObject b, FromPyObject c) =>
                  String        -- ^ Command to run
               -> StartFrom     -- ^ Start token
--               -> [(String, a)] -- ^ Globals (may be empty)
               -> [(String, b)] -- ^ Locals (may be empty)
               -> IO c
pyRun_StringHs cmd start locals =
    let conv (k, v) = do v1 <- toPyObject v
                         return (k, v1)
        in do
           --rglobals <- mapM conv globals
           rlocals <- mapM conv locals
           pyRun_String cmd start rlocals >>= fromPyObject
    
-- | Run some code in Python.
pyRun_String :: String          -- ^ Command to run
             -> StartFrom       -- ^ Start Token
--             -> [(String, PyObject)] -- ^ Globals (may be empty)
             -> [(String, PyObject)] -- ^ Locals (may be empty)
             -> IO PyObject     -- ^ Result
pyRun_String command startfrom xlocals =
    let cstart = sf2c startfrom
        in do dobj <- getDefaultGlobals
              rlocals <- toPyObject xlocals
              withCString command (\ccommand ->
               withPyObject dobj (\cglobals ->
                withPyObject rlocals (\clocals ->
                 cpyRun_String ccommand cstart cglobals clocals >>= fromCPyObject
                              )))

{- | Call a function or callable object by name. -}
callByName :: String            -- ^ Object\/function name
           -> [PyObject]        -- ^ List of non-keyword parameters
           -> [(String, PyObject)] -- ^ List of keyword parameters
           -> IO PyObject
callByName fname sparms kwparms =
    do func <- pyRun_String fname Py_eval_input []
       pyObject_Call func sparms kwparms

{- | Call a function or callable object by namem using Haskell args
and return values..

You can use 'noParms' and 'noKwParms' if you have no simple or
keyword parameters to pass, respectively. -}
callByNameHs :: (ToPyObject a, ToPyObject b, FromPyObject c) =>
              String            -- ^ Object\/function name
           -> [a]               -- ^ List of non-keyword parameters
           -> [(String, b)]     -- ^ List of keyword parameters
           -> IO c
callByNameHs fname sparms kwparms =
    do func <- pyRun_String fname Py_eval_input []
       pyObject_CallHs func sparms kwparms


{- | Import a module into the current environment in the normal sense
(similar to \"import\" in Python).
-}
pyImport :: String -> IO ()
pyImport x = 
    do pyImport_ImportModule x 
       globals <- getDefaultGlobals
       cdict <- pyImport_GetModuleDict
       py_incref cdict
       pyo2 <- fromCPyObject cdict
       dict <- fromPyObject pyo2
       case lookup x dict of
           Nothing ->  return ()
           Just pyo -> do withPyObject globals (\cglobals ->
                           withPyObject pyo (\cmodule ->
                            withCString x (\cstr ->
                             pyDict_SetItemString cglobals cstr cmodule >>= checkCInt)))
                          return ()

{- | Wrapper around C PyImport_ImportModule, which imports a module.

You may want the higher-level 'pyImport' instead. -}
pyImport_ImportModule :: String -> IO PyObject
pyImport_ImportModule x =
    do globals <- getDefaultGlobals
       fromlist <- toPyObject ['*']
       cr <- withPyObject globals (\cglobals ->
              withPyObject fromlist (\cfromlist ->
               withCString x (\cstr -> 
                cpyImport_ImportModuleEx cstr cglobals cglobals cfromlist)))
       fromCPyObject cr