1 |
|
/* This is a component of LinuxCNC |
2 |
|
* Copyright 2013 Michael Haberler <git@mah.priv.at> |
3 |
|
* |
4 |
|
* This program is free software; you can redistribute it and/or modify |
5 |
|
* it under the terms of the GNU General Public License as published by |
6 |
|
* the Free Software Foundation; either version 2 of the License, or |
7 |
|
* (at your option) any later version. |
8 |
|
* |
9 |
|
* This program is distributed in the hope that it will be useful, |
10 |
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 |
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 |
|
* GNU General Public License for more details. |
13 |
|
* |
14 |
|
* You should have received a copy of the GNU General Public License |
15 |
|
* along with this program; if not, write to the Free Software |
16 |
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
17 |
|
*/ |
18 |
|
// Interpreter internals - Python bindings |
19 |
|
// Michael Haberler 7/2011 |
20 |
|
// |
21 |
|
|
22 |
|
#include <boost/python/extract.hpp> |
23 |
|
#include <boost/python/suite/indexing/map_indexing_suite.hpp> |
24 |
|
#include <map> |
25 |
|
|
26 |
|
namespace bp = boost::python; |
27 |
|
extern int _task; // zero in gcodemodule, 1 in milltask |
28 |
|
|
29 |
|
#include <stdio.h> |
30 |
|
#include <string.h> |
31 |
|
#include <assert.h> |
32 |
|
|
33 |
|
#include "rs274ngc.hh" |
34 |
|
#include "interp_return.hh" |
35 |
|
#include "interp_internal.hh" |
36 |
|
#include "rs274ngc_interp.hh" |
37 |
|
#include "paramclass.hh" |
38 |
|
|
39 |
|
#define IS_STRING(x) (PyObject_IsInstance(x.ptr(), (PyObject*)&PyString_Type)) |
40 |
|
#define IS_INT(x) (PyObject_IsInstance(x.ptr(), (PyObject*)&PyInt_Type)) |
41 |
|
|
42 |
|
// access to named and numbered parameters via a pseudo-dictionary |
43 |
|
// either params["paramname"] or params[5400] is valid |
44 |
|
|
45 |
3 |
ParamClass::ParamClass(Interp &i) : interp(i) {}; |
46 |
|
|
47 |
3 |
double ParamClass::getitem( bp::object sub) |
48 |
|
{ |
49 |
3 |
double retval = 0; |
50 |
6 |
if (IS_STRING(sub)) { |
51 |
6 |
char const* varname = bp::extract < char const* > (sub); |
52 |
|
int status; |
53 |
3 |
interp.find_named_param(varname, &status, &retval); |
54 |
3 |
if (!status) |
55 |
|
throw std::runtime_error("parameter does not exist: " |
56 |
|
+ std::string(varname)); |
57 |
|
} else |
58 |
|
if (IS_INT(sub)) { |
59 |
|
int index = bp::extract < int > (sub); |
60 |
|
retval = interp._setup.parameters[index]; |
61 |
|
} else { |
62 |
|
throw std::runtime_error("params subscript type must be integer or string"); |
63 |
|
} |
64 |
3 |
return retval; |
65 |
|
} |
66 |
|
|
67 |
|
double ParamClass::setitem(bp::object sub, double dvalue) |
68 |
|
{ |
69 |
|
if (IS_STRING(sub)) { |
70 |
|
char const* varname = bp::extract < char const* > (sub); |
71 |
|
int status = interp.add_named_param(varname, varname[0] == '_' ? PA_GLOBAL :0); |
72 |
|
status = interp.store_named_param(&interp._setup,varname, dvalue, 0); |
73 |
|
if (status != INTERP_OK) |
74 |
|
throw std::runtime_error("cant assign value to parameter: " + |
75 |
|
std::string(varname)); |
76 |
|
|
77 |
|
} else |
78 |
|
if (IS_INT(sub)) { |
79 |
|
int index = bp::extract < int > (sub); |
80 |
|
if ((index < 0) || (index > RS274NGC_MAX_PARAMETERS -1)) { |
81 |
|
std::stringstream sstr; |
82 |
|
sstr << "params subscript out of range : " |
83 |
|
<< index << " - must be between 0 and " |
84 |
|
<< RS274NGC_MAX_PARAMETERS; |
85 |
|
throw std::runtime_error(sstr.str()); |
86 |
|
} |
87 |
|
interp._setup.parameters[index] = dvalue; |
88 |
|
return dvalue; |
89 |
|
} else |
90 |
|
throw std::runtime_error("params subscript type must be integer or string"); |
91 |
|
return dvalue; |
92 |
|
} |
93 |
|
|
94 |
|
bp::list ParamClass::namelist(context &c) const { |
95 |
|
bp::list result; |
96 |
|
for(parameter_map::iterator it = c.named_params.begin(); |
97 |
|
it != c.named_params.end(); ++it) { |
98 |
|
result.append( it->first); |
99 |
|
} |
100 |
|
return result; |
101 |
|
} |
102 |
|
|
103 |
|
bp::list ParamClass::locals() { |
104 |
|
return namelist(interp._setup.sub_context[interp._setup.call_level]); |
105 |
|
} |
106 |
|
|
107 |
|
bp::list ParamClass::globals() { |
108 |
|
return namelist(interp._setup.sub_context[0]); |
109 |
|
} |
110 |
|
|
111 |
|
bp::list ParamClass::operator()() const |
112 |
|
{ |
113 |
|
bp::list result = namelist(interp._setup.sub_context[interp._setup.call_level]); |
114 |
|
result.extend(namelist(interp._setup.sub_context[0])); |
115 |
|
return result; |
116 |
|
}; |
117 |
|
|
118 |
|
int ParamClass::length() { return RS274NGC_MAX_PARAMETERS;} |
119 |
|
|
120 |
68 |
void export_ParamClass() |
121 |
|
{ |
122 |
|
using namespace boost::python; |
123 |
|
using namespace boost; |
124 |
|
|
125 |
|
class_<ParamClass>("Params","Interpreter parameters",no_init) |
126 |
136 |
.def("__getitem__", &ParamClass::getitem) |
127 |
136 |
.def("__setitem__", &ParamClass::setitem) |
128 |
136 |
.def("__len__", &ParamClass::length) |
129 |
136 |
.def("globals", &ParamClass::globals) |
130 |
136 |
.def("locals", &ParamClass::locals) |
131 |
136 |
.def("__call__", &ParamClass::operator()); |
132 |
|
; |
133 |
413 |
} |