Fast IFS using RPN notation
python
c
x86-64
nasm
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

python_rpnexpr.h 7.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. /*
  2. * Copyright (C) 2020 Weber Yann
  3. *
  4. * This file is part of pyrpn.
  5. *
  6. * pyrpn is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * any later version.
  10. *
  11. * pyrpn is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with pyrpn. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #ifndef _PYTHON_RPNEXPR_H__
  20. #define _PYTHON_RPNEXPR_H__
  21. #include "config.h"
  22. #include <errno.h>
  23. #include <float.h>
  24. #define PY_SSIZE_T_CLEAN
  25. #include <Python.h>
  26. #include "structmember.h"
  27. #include "rpn_jit.h"
  28. #include "python_rpntoken.h"
  29. #include "python_const.h"
  30. /**@file python_rpnexpr.h
  31. * @brief pyrpn.RPNExpr definition
  32. * @ingroup python_ext
  33. * @ingroup pymod_pyrpn_RPNExpr
  34. *
  35. * This file is the header of the RPNExpr Python class
  36. */
  37. /**@defgroup pymod_pyrpn_RPNExpr pyrpn.RPNExpr
  38. * @brief Exposed Python class : RPNExpr
  39. * @ingroup pymod_pyrpn
  40. */
  41. /**@brief RPNExpr Python class type definition
  42. * @ingroup pymod_pyrpn_RPNExpr */
  43. extern PyTypeObject RPNExprType;
  44. /**@brief Structure holding RPNExpr objects
  45. * @ingroup pymod_pyrpn_RPNExpr */
  46. typedef struct
  47. {
  48. /** Python's type definition */
  49. PyObject_VAR_HEAD;
  50. /**@brief Pointer on @ref rpn_expr_s */
  51. rpn_expr_t *rpn;
  52. /**@brief Array storing expression argument
  53. * @note As attribute of rpn_expr allowing malloc & free only once */
  54. rpn_value_t *args;
  55. /**@brief If true, someone else will take care of freeing the
  56. * rpn expression at deletion */
  57. short borrowed_expr;
  58. } PyRPNExpr_t;
  59. /**@brief Organize PyRPNExpr_t state data
  60. * @see rpnexpr_getstate
  61. * @see rpnexpr_setstate
  62. * @ingroup pymod_pyrpn_RPNExpr */
  63. typedef struct
  64. {
  65. /**@brief The total size of the state */
  66. size_t total_sz;
  67. /**@brief Expression's argument count */
  68. size_t argc;
  69. /**@brief Expression's stack size */
  70. unsigned char stack_sz;
  71. /**@brief Number of tokens in expression */
  72. size_t token_sz;
  73. } PyRPNExpr_state_t;
  74. /**@brief Return a new instance of RPNExpr with a borrowed expression
  75. * @param borrowed An rpn expression to borrow
  76. * @note Borrowed expression means that the rpn_expr_t is handled by someone
  77. * else and should not be freed when the instance is deleted
  78. * @return A new RPNExpr instance
  79. * @ingroup pymod_pyrpn_RPNExpr
  80. */
  81. PyObject* rpnexpr_init_borrowing(rpn_expr_t *borrowed);
  82. /**@brief RpnExpr __new__ method
  83. * @param subtype Type of object being created (pyrpn.RPNExpr)
  84. * @param args positional arguments for subtype
  85. * @param kwds keyword argumenrs for subtype
  86. * @return The new Python RPNExpr object
  87. * @ingroup pymod_pyrpn_RPNExpr
  88. */
  89. PyObject* rpnexpr_new(PyTypeObject *subtype, PyObject *args, PyObject* kwds);
  90. /**@brief RpnExpr constructor
  91. * @param self New RPNExpr instance
  92. * @param args Positional arguments list
  93. * @param kwds Keywords arguments dict
  94. * @return 0 if no error else -1
  95. * @ingroup pymod_pyrpn_RPNExpr
  96. */
  97. int rpnexpr_init(PyObject *self, PyObject *args, PyObject *kwds);
  98. /**@brief RPNExpr __del__ method
  99. * @param self RPNExpr instance
  100. * @ingroup pymod_pyrpn_RPNExpr
  101. */
  102. void rpnexpr_del(PyObject *self);
  103. /**@brief Returns a byte representation of expression (like getstate but
  104. * without the stack informations
  105. * @param self RPNExpr instance
  106. * @param noargs Not an argument...
  107. * @return A bytes Python instance
  108. * @ingroup pymod_pyrpn_RPNExpr
  109. */
  110. PyObject* rpnexpr_getexprstate(PyObject *self, PyObject *noargs);
  111. /**@brief RPNExpr __getstate__ method for pickling
  112. * @param self RPNExpr type object
  113. * @param noargs Not an argument...
  114. * @return A bytes Python instance suitable as argument for
  115. * @ref rpnexpr_setstate
  116. * @ingroup pymod_pyrpn_RPNExpr
  117. */
  118. PyObject* rpnexpr_getstate(PyObject *self, PyObject *noargs);
  119. /**@brief RPNExpr __setstate__ method for pickling
  120. * @param cls RPNExpr type object
  121. * @param state Should by a bytes Python instance returned by @ref
  122. * rpnexpr_getstate
  123. * @return A bytes Python instance suitable as argument for
  124. * @ref rpnexpr_getstate
  125. * @ingroup pymod_pyrpn_RPNExpr
  126. */
  127. PyObject* rpnexpr_setstate(PyObject *cls, PyObject *state);
  128. /**@brief RPNExpr __copy__ method for cloning
  129. * @param cls RPNExpr class
  130. * @param noargs Not an argument...
  131. * @return A new cloned instance
  132. * @ref rpnexpr_setstate
  133. * @ingroup pymod_pyrpn_RPNExpr
  134. */
  135. PyObject* rpnexpr_copy(PyObject *cls, PyObject *noargs);
  136. /**@brief RPNExpr.__len__() method
  137. * @param self RPNExpr instance
  138. * @return A integer with the number of tokens in expression
  139. * @ingroup pymod_pyrpn_RPNExpr
  140. */
  141. Py_ssize_t rpnexpr_len(PyObject *self);
  142. /**@brief Sequence method for __getitem__ token getter
  143. * @param self RPNExpr instance
  144. * @param idx The item index (can be negative)
  145. * @return A @ref RPNTokenType subclass instance
  146. * @ingroup pymod_pyrpn_RPNExpr
  147. */
  148. PyObject* rpnexpr_token_item(PyObject *self, Py_ssize_t idx);
  149. /**@brief Sequence method for __setitem__ token setter
  150. * @param self RPNExpr instance
  151. * @param idx The item index
  152. * @param elt An RPNTokenType subclass token to set
  153. * @return 0 or -1 on error and raise IndexError
  154. * @ingroup pymod_pyrpn_RPNExpr
  155. */
  156. int rpnexpr_token_ass_item(PyObject *self, Py_ssize_t idx, PyObject* elt);
  157. /**@brief Eval an RPN expression given arguments and return the
  158. * value
  159. * @param self RPNExpr instance
  160. * @param argv Array of PyObject* arguments
  161. * @param argc Number of arguments
  162. * @return The value resulting of evaluation
  163. * @ingroup pymod_pyrpn_RPNExpr
  164. */
  165. PyObject* rpnexpr_eval(PyObject* self, PyObject** argv, Py_ssize_t argc);
  166. /**@brief Mutate an RPN expression given arguments and return the value
  167. * @param self RPNExpr instance
  168. * @param args Positionnal arguments
  169. * @param kwds Keyword arguments
  170. * @return Py_None
  171. * @ingroup pymod_pyrpn_RPNExpr
  172. */
  173. PyObject* rpnexpr_mutate(PyObject* self, PyObject *args, PyObject *kwds);
  174. /**@brief Set all stack item to zero
  175. * @param self RPNExpr instance
  176. * @param noargs Dummy argument for METH_NOARG
  177. * @return None
  178. * @ingroup pymod_pyrpn_RPNExpr
  179. */
  180. PyObject* rpnexpr_reset_stack(PyObject *self, PyObject *noargs);
  181. /**@brief RPNExpr.__repr__()
  182. * @param self RPNExpr instance
  183. * @return An str instance representing the exppression
  184. * @ingroup pymod_pyrpn_RPNExpr
  185. */
  186. PyObject* rpnexpr_repr(PyObject *self);
  187. /**@brief RPNExpr.__str__()
  188. * @param self RPNExpr instance
  189. * @return An str instance representing the exppression
  190. * @ingroup pymod_pyrpn_RPNExpr
  191. */
  192. PyObject* rpnexpr_str(PyObject *self);
  193. /**@brief RPNExpr PEP-207 richcompare method
  194. * @param _self RPNExpr instance
  195. * @param other RPNExpr instance to compare to
  196. * @param op The comparison to be done
  197. * @return Py_True or Py_False
  198. * @ingroup pymod_pyrpn_RPNExpr
  199. */
  200. PyObject* rpnexpr_richcompare(PyObject *_self, PyObject *other, int op);
  201. /**@brief Return a new Python str with a random RPN expression
  202. * @param cls pyrpn module object
  203. * @param args Position arguments in Python list
  204. * @param kwds Keywords arguments in Python dict
  205. * @return A str instance
  206. * @ingroup pymod_pyrpn
  207. */
  208. PyObject* rpnexpr_random(PyObject *cls, PyObject *args, PyObject *kwds);
  209. /**@brief Return a new named tuple containing default mutation parameters
  210. * @param cls The class (class method)
  211. * @param argv The arguments (FASTCALL)
  212. * @param argc The number of arguments
  213. * @return The named tuple
  214. * @ingroup pymod_pyrpn_RPNExpr
  215. */
  216. PyObject* rpnexpr_default_mutation_params(PyObject *cls, PyObject **argv, Py_ssize_t argc);
  217. /**@brief Try to convert a python object into a rpn_mutation_params_t
  218. * @param py_params The python object
  219. * @param params A pointer on the parameters to initialize
  220. * @return -1 on failure and raise an exception
  221. * @ingroup pymod_pyrpn_RPNExpr
  222. */
  223. int rpnexpr_pyobj_to_mutation_params(PyObject* py_params, rpn_mutation_params_t *params);
  224. #endif