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
|
// Interpreter internals - Python bindings
// Michael Haberler 7/2011
//
#include <boost/python.hpp>
#include <boost/python/suite/indexing/map_indexing_suite.hpp>
#include <map>
namespace bp = boost::python;
extern int _task; // zero in gcodemodule, 1 in milltask
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "rs274ngc.hh"
#include "interp_return.hh"
#include "interp_internal.hh"
#include "rs274ngc_interp.hh"
#include "paramclass.hh"
#define IS_STRING(x) (PyObject_IsInstance(x.ptr(), (PyObject*)&PyString_Type))
#define IS_INT(x) (PyObject_IsInstance(x.ptr(), (PyObject*)&PyInt_Type))
// access to named and numbered parameters via a pseudo-dictionary
// either params["paramname"] or params[5400] is valid
ParamClass::ParamClass(Interp &i) : interp(i) {};
double ParamClass::getitem( bp::object sub)
{
double retval = 0;
if (IS_STRING(sub)) {
char const* varname = bp::extract < char const* > (sub);
int status;
interp.find_named_param(varname, &status, &retval);
if (!status)
throw std::runtime_error("parameter does not exist: "
+ std::string(varname));
} else
if (IS_INT(sub)) {
int index = bp::extract < int > (sub);
retval = interp._setup.parameters[index];
} else {
throw std::runtime_error("params subscript type must be integer or string");
}
return retval;
}
double ParamClass::setitem(bp::object sub, double dvalue)
{
if (IS_STRING(sub)) {
char const* varname = bp::extract < char const* > (sub);
int status = interp.add_named_param(varname, varname[0] == '_' ? PA_GLOBAL :0);
status = interp.store_named_param(&interp._setup,varname, dvalue, 0);
if (status != INTERP_OK)
throw std::runtime_error("cant assign value to parameter: " +
std::string(varname));
} else
if (IS_INT(sub)) {
int index = bp::extract < int > (sub);
if ((index < 0) || (index > RS274NGC_MAX_PARAMETERS -1)) {
std::stringstream sstr;
sstr << "params subscript out of range : "
<< index << " - must be between 0 and "
<< RS274NGC_MAX_PARAMETERS;
throw std::runtime_error(sstr.str());
}
interp._setup.parameters[index] = dvalue;
return dvalue;
} else
throw std::runtime_error("params subscript type must be integer or string");
return dvalue;
}
bp::list ParamClass::namelist(context &c) const {
bp::list result;
for(parameter_map::iterator it = c.named_params.begin();
it != c.named_params.end(); ++it) {
result.append( it->first);
}
return result;
}
bp::list ParamClass::locals() {
return namelist(interp._setup.sub_context[interp._setup.call_level]);
}
bp::list ParamClass::globals() {
return namelist(interp._setup.sub_context[0]);
}
bp::list ParamClass::operator()() const
{
bp::list result = namelist(interp._setup.sub_context[interp._setup.call_level]);
result.extend(namelist(interp._setup.sub_context[0]));
return result;
};
int ParamClass::length() { return RS274NGC_MAX_PARAMETERS;}
void export_ParamClass()
{
using namespace boost::python;
using namespace boost;
class_<ParamClass>("Params","Interpreter parameters",no_init)
.def("__getitem__", &ParamClass::getitem)
.def("__setitem__", &ParamClass::setitem)
.def("__len__", &ParamClass::length)
.def("globals", &ParamClass::globals)
.def("locals", &ParamClass::locals)
.def("__call__", &ParamClass::operator());
;
}
|