fe2364eb529df5c44b24ae95bfd1381a841a5108
[mussa.git] / py / python.cpp
1 #include "py/python.hpp"
2 namespace py = boost::python;
3
4 #include <iostream>
5 #include <string>
6 #include <vector>
7
8 #include <boost/algorithm/string/split.hpp>
9 #include <boost/algorithm/string/classification.hpp>
10 namespace alg = boost::algorithm;
11
12 MussaPython::MussaPython()
13 {
14   try {
15     // add our mussa module to our environment
16     PyImport_AppendInittab("mussa", &initmussa);
17     // go ahead and finish initalizing python
18     Py_Initialize();
19     // get reference to the global namespace
20     py::object main_module(
21         (py::handle<>(py::borrowed(PyImport_AddModule("__main__"))))
22     );
23     main_namespace = main_module.attr("__dict__");
24     // FIXME: this really should be a configuration file?
25     run("import __main__\n"
26         "import mussa\n"
27         "import webbrowser\n");
28   } catch (py::error_already_set e) {
29     PyErr_Print();
30   }
31 }
32
33 void MussaPython::run(std::string code)
34 {
35   try {
36     PyObject *global_ptr = main_namespace.ptr();
37     py::object result( py::handle<>(
38        (PyRun_String(code.c_str(), Py_file_input, global_ptr, global_ptr)
39     )));
40   } catch( py::error_already_set ) {
41     PyErr_Print();
42   }
43 }
44
45 py::object MussaPython::eval(std::string code)
46 {
47   try {
48     PyObject *global_ptr = main_namespace.ptr();
49     py::object result( py::handle<>(
50        (PyRun_String(code.c_str(), Py_eval_input, global_ptr, global_ptr)
51     )));
52     return result;
53   } catch( py::error_already_set ) {
54     PyErr_Print();
55   }
56   py::object result;
57   return  result;
58 }
59
60
61 void MussaPython::interpreter(FILE *fp)
62 {
63   try {
64     PyRun_InteractiveLoop(fp, "mussa");
65   } catch (py::error_already_set e) {
66     PyErr_Print();
67   }
68 }
69
70 py::object MussaPython::operator[](std::string name)
71
72   typedef std::vector< std::string > string_vector;
73   string_vector split_name;
74   alg::split(split_name, name, alg::is_any_of("."));
75   
76   py::object lookup = main_namespace["__main__"];
77   
78   for (string_vector::const_iterator name_i = split_name.begin();
79        name_i != split_name.end();
80        ++name_i)
81   {
82     lookup = lookup.attr("__dict__")[*name_i];
83   }
84   return lookup;
85 }
86
87 //! return a reference to a single mussa python interpreter
88 MussaPython& get_py()
89 {
90   static MussaPython py;
91   return py;
92 }