/* * Copyright (C) 2020 Weber Yann * * This file is part of pyrpn. * * pyrpn is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * pyrpn is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with pyrpn. If not, see . */ #ifndef __rpn_if__h__ #define __rpn_if__h__ #include "config.h" #include "rpn_jit.h" /**@defgroup ifs_if Iterated function * @brief Iterated RPN expression * * A single Iterated Function implemented using an RPN expression. * * @note The goal is to optimize iteration writing the code in C and providing * an high level Python API. * * For more details about IF see dedicated page : @ref doc_ifs_if */ typedef void* rpn_if_arg_t; typedef unsigned long rpn_arg_t; typedef struct rpn_if_s rpn_if_t; typedef struct rpn_if_res_s rpn_if_res_t; typedef struct rpn_if_state_s rpn_if_state_t; typedef struct rpn_if_transfo_s rpn_if_transfo_t; typedef enum rpn_if_transfo_type_e rpn_if_transfo_type_t; /**@brief IF state to RPN arguments transformation */ typedef void (*if2rpn_f)(rpn_if_t *rif, rpn_if_state_t, rpn_arg_t*); /**@brief RPN arguments to IF state transformation */ typedef rpn_if_res_t (*rpn2if_f)(rpn_if_t *rif, rpn_arg_t, rpn_if_state_t); /**@brief IF state * * Will always be something like : * - memory adress/offset/index * - value */ struct rpn_if_state_s { /**@brief Data address */ size_t i; /**@brief Data value(s) */ void *val; }; /**@brief Indicate function type for @ref rpn_if_transfo_s */ enum rpn_if_transfo_type_e { /**@brief No transformation * * Default behavior is to copy data in args directly assuming * argc * sizeof(unsigned long) = data_sz */ RPN_f_null, /**@brief Transform RPN result into data */ RPN_f_rpn2if, /**@brief Transform data into RPN result */ RPN_f_if2rpn }; /**@brief Represent an IF transformation function * * Can transform data into arguments or arguments into data, depending * on function type. */ struct rpn_if_transfo_s { /**@brief Function pointer type * @note optionnal, for type checking */ rpn_if_transfo_type_t type; /**@brief Data size (a @ref rpn_if_s::mem item ) in bytes */ size_t data_sz; /**@brief Memory size in byte */ size_t mem_sz; /**@brief RPN arg/result size * * - if type is RPN_if2rpn argc is the rpn expression argc * - if type is RPN_rpn2if argc is the rpn expression count (results * count) */ size_t argc; union { /**@brief IF state to RPN arguments transformation */ if2rpn_f if2rpn; /**@brief RPN arguments to IF state transformation */ rpn2if_f rpn2if; }; }; /**@brief Generic Iterated function implementation */ struct rpn_if_s { /**@brief Memory map in wich data are fetch & stored */ void *mem; /**@brief Memory map size in bytes */ size_t mem_sz; /**@brief Size of a memory item */ size_t value_sz; /**@brief IF last position + value buffer */ rpn_if_state_t state; /**@brief RPN expression(s) result(s) buffer */ unsigned long *rpn_res; /**@brief Arguments given to RPN expression(s) buffer */ rpn_arg_t *rpn_args; /**@brief Number of arguments expected by RPN expressions */ size_t rpn_argc; /**@brief RPN expression(s) pointer(s) */ rpn_expr_t *rpn; /**@brief RPN expression count */ size_t rpn_sz; /**@brief IF state to RPN arguments transformation */ if2rpn_f if2rpn; /**@brief RPN arguments to IF state transformation */ rpn2if_f rpn2if; }; /**@brief Alloc a new @ref rpn_if_s from two transformation functions * @param if2rpn informations about data to rpn args transformation * @param rpn2if informations about rpn args to data transformation * @param rpn list of RPN expresions ( must be of rpn2if->argc size !!!) * @return A pointer on an allocated @ref rpn_if_s */ rpn_if_t* rpn_if_new(size_t mem_sz, rpn_if_transfo_t *if2rpn, rpn_if_transfo_t *rpn2if, rpn_expr_t *rpn); /**@brief Deallocate an @ref rpn_ifs_s and close associated @ref rpn_expr_s * @param rif The IF to deallocate */ void rpn_if_free(rpn_if_t *rif); /**@brief Update all RPN expressions * @param rif The concerned IF * @param rpn A list of tokenized expressions (must be of rif->rpn_sz size) * @return 0 if no error else -1 * @note Shortcut for @ref rpn_if_rpn_upd_rng(rif, rpns, rif->rpn_sz, 0); */ int rpn_if_rpn_upd(rpn_if_t *rif, rpn_tokenized_t *rpns); /**@brief Update a range of RPN expressions * @param rif The concerned IF * @param rpn A list of tokenized expressions * @param sz Number of rpn expression in rpn argument * @param offset Start updating expressions from this offset * @return 0 if no error else -1 */ int rpn_if_rpn_upd_rng(rpn_if_t *rif, rpn_tokenized_t *rpns, size_t sz, size_t offset); /**@brief New @ref rpn_if_s and partial initialisation * @param mem_sz memory size in bytes * @param argc number of arguments taken by @ref rpn_expr_s * @param rpn_count number of @ref rpn_expr_s */ rpn_if_t* _rpn_if_new(size_t mem_sz, size_t rpn_argc, size_t rpn_count, size_t value_sz); /**@page doc_ifs * * Iterated functions system are a composed of Iterated function choosed * randomly. * * @section doc_ifs_if Iterated function general considerations * * Iterated functions can be seen as transformations in a given space. * Functions takes items as argument and set an item as a result. * * For the moment, the main goal is to interact with a 2 dimension world with * 1 to 3 values per items (an image in grayscale or in RGB). * * A simple approach can be to use a single expression working with a single * number later decomposed in multiple composant using bitmasks (basically * for storage address and stored value). * * This can later be decomposed by assigning one (or multiple) expression * to each composant (one expression for storage address, another one for * the storage value). * * The same consideration can be done on argument number/composition taken * by the expression. * * @subsection doc_ifs_if_io Iterated function generalisation * * A generic implementation can be IF as : * - A generic input transformation system : X arguments transformed in Y * RPNExpression arguments * - A generic output system : N results (from N RPNExpr) transformed in X * results * - A generic transformation system : N expressions, taking Y arguments * * @section doc_ifs_if_api Iterated Function API * * Multiple steps are expected in API development : * - A simple generic API will be defined (something like expecting a * void* fun(void*) transforming X data in Y result using a blackbox optimized * behavior associated with a memory map * - Helper function will be written allowing C and/or Python extensions */ #endif