Add expression accessor for RPNIterExpr

This commit is contained in:
Yann Weber 2023-06-07 12:01:58 +02:00
commit 3097c98237
4 changed files with 68 additions and 10 deletions

View file

@ -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;
}

View file

@ -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...

View file

@ -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);
}

View file

@ -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