Add expression accessor for RPNIterExpr
This commit is contained in:
parent
d535b5c64c
commit
3097c98237
4 changed files with 68 additions and 10 deletions
15
python_if.c
15
python_if.c
|
|
@ -40,6 +40,8 @@ and the stack state."},
|
|||
};
|
||||
|
||||
PyMemberDef RPNIterExpr_members[] = {
|
||||
{"expressions", T_OBJECT, offsetof(PyRPNIterExpr_t, expr), READONLY,
|
||||
"The tuple of expressions"},
|
||||
{NULL}
|
||||
};
|
||||
|
||||
|
|
@ -279,6 +281,19 @@ with given arguments");
|
|||
// Creating rif with a new memory map
|
||||
expr_self->rif = rpn_if_new(rif_params, NULL);
|
||||
|
||||
// Creating the tuple holding RPNExpr instances of expressions
|
||||
expr_self->expr = PyTuple_New(expr_self->rif->params->rpn_sz);
|
||||
for(size_t i=0; i<expr_self->rif->params->rpn_sz;i++)
|
||||
{
|
||||
rpn_expr_t *expr = &expr_self->rif->rpn[i];
|
||||
PyObject *instance = rpnexpr_init_borrowing(expr);
|
||||
if(!instance)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
PyTuple_SET_ITEM(expr_self->expr, i, instance);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
10
python_if.h
10
python_if.h
|
|
@ -75,6 +75,9 @@ typedef struct
|
|||
/**@brief Pointer on @ref rpn_if_s */
|
||||
rpn_if_t *rif;
|
||||
|
||||
/**@brief Python tuple with instances of RPNExpr */
|
||||
PyObject *expr;
|
||||
|
||||
} PyRPNIterExpr_t;
|
||||
|
||||
/**@brief RpnIterExpr __new__ method
|
||||
|
|
@ -100,12 +103,17 @@ int rpnif_init(PyObject *self, PyObject *args, PyObject *kwds);
|
|||
*/
|
||||
void rpnif_del(PyObject *self);
|
||||
|
||||
|
||||
/**@brief Buffer protocol request handler method */
|
||||
int rpnif_getbuffer(PyObject *self, Py_buffer *view, int flags);
|
||||
/**@brief Buffer protocol request release method */
|
||||
void rpnif_releasebuffer(PyObject *self, Py_buffer *view);
|
||||
|
||||
/**@brief Return a named tuple of custom rif data */
|
||||
PyObject *rpnif_get_params(PyObject *self);
|
||||
|
||||
/**@brief Return the list of expressions */
|
||||
PyObject *rpnif_get_expr(PyObject *self);
|
||||
|
||||
/**@brief RPNIterExpr __getstate__ method for pickling
|
||||
* @param cls RPNIterExpr type object
|
||||
* @param noargs Not an argument...
|
||||
|
|
|
|||
|
|
@ -93,6 +93,7 @@ PyObject* rpnexpr_new(PyTypeObject *subtype, PyObject *args, PyObject* kwds)
|
|||
expr = (PyRPNExpr_t*)ret;
|
||||
expr->rpn = NULL;
|
||||
expr->args = NULL;
|
||||
expr->borrowed_expr = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -115,13 +116,6 @@ int rpnexpr_init(PyObject *self, PyObject *args, PyObject *kwds)
|
|||
return -1;
|
||||
}
|
||||
|
||||
if(strlen(expr) == 0)
|
||||
{
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"RpnExpr.__init__() expect expression argument to be not empty");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(args_count < 0 || args_count > 255)
|
||||
{
|
||||
snprintf(err_str, 128,
|
||||
|
|
@ -176,12 +170,44 @@ int rpnexpr_init(PyObject *self, PyObject *args, PyObject *kwds)
|
|||
return 0;
|
||||
}
|
||||
|
||||
PyObject* rpnexpr_init_borrowing(rpn_expr_t *borrowed)
|
||||
{
|
||||
PyObject *args, *ret;
|
||||
PyRPNExpr_t *instance;
|
||||
|
||||
args = Py_BuildValue("sLL", "", borrowed->args_count,
|
||||
borrowed->stack_sz);
|
||||
if(!args || PyErr_Occurred())
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = PyObject_CallObject(&RPNExprType, args);
|
||||
if(!ret || PyErr_Occurred())
|
||||
{
|
||||
Py_DECREF(args);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Py_DECREF(args);
|
||||
|
||||
instance = (PyRPNExpr_t*)ret;
|
||||
|
||||
rpn_expr_close(instance->rpn);
|
||||
free(instance->rpn);
|
||||
|
||||
instance->borrowed_expr = 1;
|
||||
instance->rpn = borrowed;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void rpnexpr_del(PyObject *self)
|
||||
{
|
||||
PyRPNExpr_t *expr_self;
|
||||
|
||||
expr_self = (PyRPNExpr_t*)self;
|
||||
if(expr_self->rpn)
|
||||
if(expr_self->rpn && !expr_self->borrowed_expr)
|
||||
{
|
||||
rpn_expr_close(expr_self->rpn);
|
||||
free(expr_self->rpn);
|
||||
|
|
@ -506,7 +532,6 @@ PyObject* rpnexpr_eval(PyObject* self, PyObject** argv, Py_ssize_t argc)
|
|||
}
|
||||
|
||||
res = rpn_expr_eval(expr_self->rpn, expr_self->args);
|
||||
//dprintf(2, "[RES=%lu]\n", res);
|
||||
|
||||
return PyLong_FromUnsignedLong(res);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,6 +63,10 @@ typedef struct
|
|||
/**@brief Array storing expression argument
|
||||
* @note As attribute of rpn_expr allowing malloc & free only once */
|
||||
rpn_value_t *args;
|
||||
|
||||
/**@brief If true, someone else will take care of freeing the
|
||||
* rpn expression at deletion */
|
||||
short borrowed_expr;
|
||||
} PyRPNExpr_t;
|
||||
|
||||
/**@brief Organize PyRPNExpr_t state data
|
||||
|
|
@ -76,6 +80,12 @@ typedef struct
|
|||
size_t token_sz;
|
||||
} PyRPNExpr_state_t;
|
||||
|
||||
/**@brief Return a new instance of RPNExpr with a borrowed expression
|
||||
* @note Borrowed expression means that the rpn_expr_t is handled by someone
|
||||
* else and should not be freed when the instance is deleted
|
||||
*/
|
||||
PyObject* rpnexpr_init_borrowing(rpn_expr_t *borrowed);
|
||||
|
||||
/**@brief RpnExpr __new__ method
|
||||
* @param subtype Type of object being created (pyrpn.RPNExpr)
|
||||
* @param args positional arguments for subtype
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue