Compare commits
4 commits
eeac401bb3
...
680b4ee1ff
Author | SHA1 | Date | |
---|---|---|---|
680b4ee1ff | |||
61e74e7ab2 | |||
1e99abf3b8 | |||
8bbee65ff8 |
10 changed files with 400 additions and 57 deletions
5
Makefile
5
Makefile
|
@ -21,7 +21,7 @@ PYTHON_LDFLAGS=-shared -fPIC `$(PYTHON_CONFIG) --libs` `$(PYTHON_CONFIG) --ldfl
|
|||
|
||||
all: .deps pyrpn.so
|
||||
|
||||
pyrpn.so: python_pyrpn.o python_rpnexpr.o rpn_lib.o rpn_jit.o rpn_parse.o rpn_mutation.o rpn_if.o rpn_if_default.o
|
||||
pyrpn.so: python_pyrpn.o python_rpnexpr.o rpn_lib.o rpn_jit.o rpn_parse.o rpn_mutation.o rpn_if.o rpn_if_default.o rpn_ifs.o
|
||||
$(LD) $(LDFLAGS) $(PYTHON_LDFLAGS) -o $@ $^
|
||||
|
||||
python_pyrpn.o: python_pyrpn.c python_rpnexpr.h python_rpnexpr.o rpn_jit.o
|
||||
|
@ -45,6 +45,9 @@ rpn_if.o: rpn_if.c rpn_if.h rpn_jit.o
|
|||
rpn_if_default.o: rpn_if_default.c rpn_if_default.h rpn_if.o
|
||||
$(CC) $(CFLAGS) -c $<
|
||||
|
||||
rpn_ifs.o: rpn_ifs.c rpn_ifs.h rpn_if.o
|
||||
$(CC) $(CFLAGS) -c $<
|
||||
|
||||
rpn_lib.o: rpn_lib.asm rpn_lib.h
|
||||
$(NASM) $(NASMCFLAGS) -o $@ $<
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
|
||||
/**@defgroup python_type RPNExpr Python class
|
||||
* @brief Exposed Python class : RPNExpr
|
||||
* @ingroup python_ext
|
||||
* @ingroup python_module
|
||||
*/
|
||||
|
||||
/**@file python_rpnexpr.h
|
||||
|
|
66
rpn_if.c
66
rpn_if.c
|
@ -18,9 +18,11 @@
|
|||
*/
|
||||
#include "rpn_if.h"
|
||||
|
||||
rpn_if_t* rpn_if_new(const rpn_if_param_t *params, rpn_expr_t *rpn)
|
||||
rpn_if_t* rpn_if_new(const rpn_if_param_t *params, rpn_expr_t *rpn,
|
||||
rpn_value_t *memmap)
|
||||
{
|
||||
rpn_if_t *res;
|
||||
size_t i;
|
||||
int err;
|
||||
|
||||
res = malloc(sizeof(rpn_if_t));
|
||||
|
@ -29,13 +31,23 @@ rpn_if_t* rpn_if_new(const rpn_if_param_t *params, rpn_expr_t *rpn)
|
|||
goto error;
|
||||
}
|
||||
|
||||
memcpy(&res->params, params, sizeof(rpn_if_param_t));
|
||||
//memcpy(&res->params, params, sizeof(rpn_if_param_t));
|
||||
res->params = params;
|
||||
|
||||
res->mem = mmap(NULL, params->mem_sz, PROT_READ|PROT_WRITE, MAP_ANON,
|
||||
-1, 0);
|
||||
if(res->mem == (void*)-1)
|
||||
if(memmap)
|
||||
{
|
||||
goto mmap_err;
|
||||
res->self_mem = 0;
|
||||
res->mem = memmap;
|
||||
}
|
||||
else
|
||||
{
|
||||
res->self_mem = 1;
|
||||
res->mem = mmap(NULL, params->mem_sz, PROT_READ|PROT_WRITE, MAP_ANON,
|
||||
-1, 0);
|
||||
if(res->mem == (void*)-1)
|
||||
{
|
||||
goto mmap_err;
|
||||
}
|
||||
}
|
||||
|
||||
res->rpn_res = malloc(sizeof(rpn_value_t) *
|
||||
|
@ -46,20 +58,38 @@ rpn_if_t* rpn_if_new(const rpn_if_param_t *params, rpn_expr_t *rpn)
|
|||
}
|
||||
res->rpn_args = &(res->rpn_res[params->rpn_sz]);
|
||||
|
||||
res->rpn = malloc(sizeof(rpn_expr_t) * params->rpn_sz);
|
||||
res->rpn = malloc(sizeof(rpn_expr_t*) * params->rpn_sz);
|
||||
if(!res->rpn)
|
||||
{
|
||||
goto rpn_expr_err;
|
||||
}
|
||||
for(i=0; i<params->rpn_sz; i++)
|
||||
{
|
||||
if(rpn_expr_init(&(res->rpn[i]), params->rpn_stack_sz,
|
||||
params->rpn_argc) < 0)
|
||||
{
|
||||
goto rpn_init_error;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
|
||||
rpn_init_error:
|
||||
err = errno;
|
||||
while(i)
|
||||
{
|
||||
rpn_expr_close(&(res->rpn[i]));
|
||||
i--;
|
||||
}
|
||||
rpn_expr_err:
|
||||
err = errno;
|
||||
free(res->rpn_res);
|
||||
rpn_malloc_err:
|
||||
err = errno;
|
||||
munmap(res->mem, params->mem_sz);
|
||||
if(res->self_mem)
|
||||
{
|
||||
munmap(res->mem, params->mem_sz);
|
||||
}
|
||||
mmap_err:
|
||||
err = errno;
|
||||
free(res);
|
||||
|
@ -72,13 +102,16 @@ rpn_if_t* rpn_if_new(const rpn_if_param_t *params, rpn_expr_t *rpn)
|
|||
void rpn_if_free(rpn_if_t* rif)
|
||||
{
|
||||
size_t i;
|
||||
for(i=0; i<rif->params.rpn_sz; i++)
|
||||
for(i=0; i<rif->params->rpn_sz; i++)
|
||||
{
|
||||
rpn_expr_close(&(rif->rpn[i]));
|
||||
}
|
||||
free(rif->rpn);
|
||||
free(rif->rpn_res);
|
||||
munmap(rif->mem, rif->params.mem_sz);
|
||||
if(rif->self_mem)
|
||||
{
|
||||
munmap(rif->mem, rif->params->mem_sz);
|
||||
}
|
||||
free(rif);
|
||||
}
|
||||
|
||||
|
@ -86,18 +119,23 @@ size_t rpn_if_step(rpn_if_t *rif, size_t pos)
|
|||
{
|
||||
size_t i;
|
||||
size_t newpos;
|
||||
rif->params.arg_f(rif, pos, rif->rpn_args);
|
||||
for(i=0; i<rif->params.rpn_sz; i++)
|
||||
rif->params->arg_f(rif, pos, rif->rpn_args);
|
||||
/* WRONG ! rif->rpn_args is in rif structure and do not have to be
|
||||
given as argument... */
|
||||
for(i=0; i<rif->params->rpn_sz; i++)
|
||||
{
|
||||
rif->rpn_res[i] = rpn_expr_eval(&(rif->rpn[i]), rif->rpn_args);
|
||||
}
|
||||
rif->params.res_f(rif, &newpos, rif->rpn_res);
|
||||
//rif->params->res_f(rif, &newpos, rif->rpn_res);
|
||||
/* MEGA WRONG ! rif->rpn_res is in rif structure and do not have to be
|
||||
given as argument... */
|
||||
rif->params->res_f(rif, &newpos, NULL);
|
||||
return newpos;
|
||||
}
|
||||
|
||||
int rpn_if_rpn_upd(rpn_if_t *rif, rpn_tokenized_t *rpns)
|
||||
{
|
||||
return rpn_if_rpn_upd_rng(rif, rpns, rif->params.rpn_sz, 0);
|
||||
return rpn_if_rpn_upd_rng(rif, rpns, rif->params->rpn_sz, 0);
|
||||
}
|
||||
|
||||
int rpn_if_rpn_upd_rng(rpn_if_t *rif, rpn_tokenized_t *rpns, size_t sz,
|
||||
|
|
39
rpn_if.h
39
rpn_if.h
|
@ -24,6 +24,7 @@
|
|||
#include "rpn_jit.h"
|
||||
|
||||
/**@defgroup ifs_if Iterated function
|
||||
* @ingroup ifs
|
||||
* @brief Iterated RPN expression
|
||||
*
|
||||
* A single Iterated Function implemented using an RPN expression.
|
||||
|
@ -51,7 +52,12 @@ struct rpn_if_param_s
|
|||
/**@brief Number of arguments expected by RPN expressions */
|
||||
size_t rpn_argc;
|
||||
|
||||
/**@brief Position to RPN argument transformation */
|
||||
/**@brief Sizeof RPN expression stacks */
|
||||
unsigned char rpn_stack_sz;
|
||||
|
||||
/**@brief Set RPN arguments given a position
|
||||
* @note transform position to arguments and fetch other arguments
|
||||
* from memory map*/
|
||||
int (*arg_f)(rpn_if_t *rif, size_t pos, rpn_value_t *args);
|
||||
/**@brief RPN results to data and position transformation
|
||||
* @note set memory maps with converted data */
|
||||
|
@ -65,7 +71,7 @@ struct rpn_if_param_s
|
|||
struct rpn_if_s
|
||||
{
|
||||
/**@brief IF parameters */
|
||||
rpn_if_param_t params;
|
||||
const rpn_if_param_t *params;
|
||||
/**@brief RPN expression(s) pointer(s) */
|
||||
rpn_expr_t *rpn;
|
||||
/**@brief RPN expression(s) result(s) buffer */
|
||||
|
@ -74,18 +80,28 @@ struct rpn_if_s
|
|||
rpn_value_t *rpn_args;
|
||||
/**@brief Memory map in wich data are fetch & stored */
|
||||
rpn_value_t *mem;
|
||||
/**@brief If 1 the mmap is called at initialization time, munmap
|
||||
* should be called by @ref rpn_if_free */
|
||||
short self_mem;
|
||||
};
|
||||
|
||||
#define rpn_if_getitem(rif, pos) (rif->mem + (rif->params.value_sz * pos))
|
||||
/**@brief Macro fetching a memory pointer given a position
|
||||
* @return rpn_value_t* values
|
||||
*/
|
||||
#define rpn_if_getitem(rif, pos) (rif->mem + ((rif->params->value_sz) * pos))
|
||||
|
||||
/**@brief Alloc a new @ref rpn_if_s from two transformation functions
|
||||
/**@brief Alloc a new @ref rpn_if_s using given parameters
|
||||
* @param params IF parameters
|
||||
* @param rpn list of RPN expresions of params->rpn_sz size
|
||||
* @param memmap A suitable memory map. If NULL given, a new mmap is used
|
||||
* @return A pointer on an allocated @ref rpn_if_s
|
||||
* @todo Delete rpn argument : rpn expressions are initialized and
|
||||
* have to be compiled later
|
||||
*/
|
||||
rpn_if_t* rpn_if_new(const rpn_if_param_t *params, rpn_expr_t *rpn);
|
||||
rpn_if_t* rpn_if_new(const rpn_if_param_t *params, rpn_expr_t *rpn,
|
||||
rpn_value_t *memmap);
|
||||
|
||||
/**@brief Deallocate an @ref rpn_ifs_s and its ressources and close associated
|
||||
/**@brief Deallocate an @ref rpn_if_s and its ressources and close associated
|
||||
* @ref rpn_expr_s
|
||||
* @param rif The IF to deallocate
|
||||
*/
|
||||
|
@ -100,7 +116,7 @@ size_t rpn_if_step(rpn_if_t *rif, size_t pos);
|
|||
|
||||
/**@brief Update all RPN expressions
|
||||
* @param rif The concerned IF
|
||||
* @param rpn A list of tokenized expressions (must be of rif->rpn_sz size)
|
||||
* @param rpns 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);
|
||||
*/
|
||||
|
@ -108,7 +124,7 @@ 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 rpns 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
|
||||
|
@ -118,13 +134,16 @@ int rpn_if_rpn_upd_rng(rpn_if_t *rif, rpn_tokenized_t *rpns, size_t sz,
|
|||
|
||||
/**@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_argc number of arguments taken by @ref rpn_expr_s
|
||||
* @param rpn_count number of @ref rpn_expr_s
|
||||
* @param value_sz the count of rpn_value_t in one memory map value
|
||||
* @return a pointer on the initialized rif
|
||||
*/
|
||||
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
|
||||
/**@page doc_ifs Iterated function system
|
||||
* @brief Iterated function system using RPN
|
||||
*
|
||||
* Iterated functions system are a composed of Iterated function choosed
|
||||
* randomly.
|
||||
|
|
|
@ -7,7 +7,7 @@ int rpn_if_argf_default(rpn_if_t *rif, size_t pos, rpn_value_t *args)
|
|||
rpn_if_default_data_t *data;
|
||||
rpn_value_t *values;
|
||||
|
||||
data = (rpn_if_default_data_t*)rif->params.data;
|
||||
data = (rpn_if_default_data_t*)rif->params->data;
|
||||
|
||||
switch(data->pos_flag)
|
||||
{
|
||||
|
@ -24,7 +24,7 @@ int rpn_if_argf_default(rpn_if_t *rif, size_t pos, rpn_value_t *args)
|
|||
cur_arg = *(data->size_lim);
|
||||
break;
|
||||
}
|
||||
if(cur_arg >= rif->params.rpn_argc)
|
||||
if(cur_arg > rif->params->rpn_argc)
|
||||
{
|
||||
/* Too many arguments for given rif !! */
|
||||
return -1;
|
||||
|
@ -50,23 +50,99 @@ int rpn_if_argf_default(rpn_if_t *rif, size_t pos, rpn_value_t *args)
|
|||
}
|
||||
break;
|
||||
case RPN_IF_RES_XFUN:
|
||||
for(i=0; i < rif->params.rpn_sz - cur_arg; i++)
|
||||
for(i=0; i < rif->params->rpn_sz - cur_arg; i++)
|
||||
{
|
||||
args[cur_arg+i] = values[i];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* LOG ERROR */
|
||||
return -1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int rpn_if_resf_default(rpn_if_t *rif, size_t *pos, rpn_value_t *data);
|
||||
int rpn_if_resf_default(rpn_if_t *rif, size_t *pos, rpn_value_t *res)
|
||||
{
|
||||
rpn_if_default_data_t *data;
|
||||
size_t cur_arg, i, rgb_imax;
|
||||
rpn_value_t *values;
|
||||
|
||||
data = (rpn_if_default_data_t*)rif->params->data;
|
||||
|
||||
switch(data->pos_flag)
|
||||
{
|
||||
case RPN_IF_POSITION_LINEAR:
|
||||
rpn_if_resf_linear(rif, pos, res);
|
||||
cur_arg = 1;
|
||||
break;
|
||||
case RPN_IF_POSITION_XY:
|
||||
rpn_if_resf_xy(rif, pos, res);
|
||||
cur_arg = 2;
|
||||
break;
|
||||
case RPN_IF_POSITION_XDIM:
|
||||
rpn_if_resf_xdim(rif, pos, res);
|
||||
cur_arg = *(data->size_lim);
|
||||
break;
|
||||
}
|
||||
if(cur_arg > rif->params->rpn_argc)
|
||||
{
|
||||
/** LOG ERROR ! should never append... */
|
||||
return -1;
|
||||
}
|
||||
rgb_imax = 3; /* rgba */
|
||||
values = rpn_if_getitem(rif, *pos);
|
||||
/**@todo if(res) set the values in res too ! */
|
||||
switch(data->res_flag)
|
||||
{
|
||||
case RPN_IF_RES_BOOL:
|
||||
*values = 1;
|
||||
break;
|
||||
|
||||
case RPN_IF_RES_CONST:
|
||||
*values = *(data->const_val);
|
||||
break;
|
||||
|
||||
case RPN_IF_RES_COUNT:
|
||||
(*values)++;
|
||||
break;
|
||||
|
||||
case RPN_IF_RES_CONST_RGBA:
|
||||
rgb_imax = 4;
|
||||
//case RPN_IF_RES_CONST_RGB:
|
||||
for(i=0;i<rgb_imax;i++)
|
||||
{
|
||||
values[i] = data->const_val[i];
|
||||
}
|
||||
break;
|
||||
|
||||
case RPN_IF_RES_RGBA:
|
||||
rgb_imax = 4;
|
||||
case RPN_IF_RES_RGB:
|
||||
for(i=0;i<rgb_imax;i++)
|
||||
{
|
||||
values[i] = rif->rpn_res[cur_arg+i];
|
||||
}
|
||||
break;
|
||||
|
||||
case RPN_IF_RES_XFUN:
|
||||
for(i=0; i<rif->params->rpn_sz - cur_arg; i++)
|
||||
{
|
||||
values[i] = rif->rpn_res[cur_arg+i];
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
/* LOG ERROR */
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rpn_if_argf_linear(rpn_if_t *rif, size_t pos, rpn_value_t *args)
|
||||
{
|
||||
rpn_if_default_data_t *data;
|
||||
data = (rpn_if_default_data_t*)rif->params.data;
|
||||
data = (rpn_if_default_data_t*)rif->params->data;
|
||||
if(data->size_lim && pos >= *data->size_lim)
|
||||
{
|
||||
if(data->pos_flag & RPN_IF_POSITION_OF_ERR)
|
||||
|
@ -83,7 +159,7 @@ int rpn_if_resf_linear(rpn_if_t *rif, size_t *pos, rpn_value_t *_data)
|
|||
{
|
||||
rpn_if_default_data_t *data;
|
||||
size_t res;
|
||||
data = (rpn_if_default_data_t*)rif->params.data;
|
||||
data = (rpn_if_default_data_t*)rif->params->data;
|
||||
res = rif->rpn_res[0];
|
||||
if(data->size_lim && res >= *data->size_lim)
|
||||
{
|
||||
|
@ -101,7 +177,7 @@ int rpn_if_argf_xy(rpn_if_t *rif, size_t pos, rpn_value_t *args)
|
|||
{
|
||||
rpn_if_default_data_t *data;
|
||||
|
||||
data = (rpn_if_default_data_t*)rif->params.data;
|
||||
data = (rpn_if_default_data_t*)rif->params->data;
|
||||
if(!data->size_lim)
|
||||
{
|
||||
return -1;
|
||||
|
@ -124,7 +200,7 @@ int rpn_if_resf_xy(rpn_if_t *rif, size_t *pos, rpn_value_t *_data)
|
|||
rpn_if_default_data_t *data;
|
||||
size_t xy[2];
|
||||
|
||||
data = (rpn_if_default_data_t*)rif->params.data;
|
||||
data = (rpn_if_default_data_t*)rif->params->data;
|
||||
|
||||
xy[0] = rif->rpn_res[0];
|
||||
xy[1] = rif->rpn_res[1];
|
||||
|
@ -152,7 +228,7 @@ int rpn_if_argf_xdim(rpn_if_t *rif, size_t pos, rpn_value_t *args)
|
|||
rpn_if_default_data_t *data;
|
||||
size_t i, curdim_sz, curpos;
|
||||
|
||||
data = (rpn_if_default_data_t*)rif->params.data;
|
||||
data = (rpn_if_default_data_t*)rif->params->data;
|
||||
|
||||
if(!data->size_lim)
|
||||
{
|
||||
|
@ -189,7 +265,7 @@ int rpn_if_resf_xdim(rpn_if_t *rif, size_t *pos, rpn_value_t *_data)
|
|||
rpn_if_default_data_t *data;
|
||||
size_t i, res, cur, curlim, prevlim;
|
||||
|
||||
data = (rpn_if_default_data_t*)rif->params.data;
|
||||
data = (rpn_if_default_data_t*)rif->params->data;
|
||||
res = 0;
|
||||
|
||||
if(!data->size_lim)
|
||||
|
|
|
@ -20,10 +20,16 @@
|
|||
#define __rpn_if_default__h__
|
||||
|
||||
/**@file rpn_if_default.h Defines default IF
|
||||
* @ingroup ifs_if_default
|
||||
* @brief Default IF definitions
|
||||
*/
|
||||
|
||||
/**@defgroup ifs_if_default Default functions
|
||||
* @ingroup ifs_if
|
||||
* @brief Simple iterated functions functions
|
||||
*
|
||||
* Defines default @ref rpn_if_param_s.res_f and @ref rpn_if_param_s.arg_f
|
||||
* functions.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
@ -64,7 +70,7 @@ struct rpn_if_default_data_s
|
|||
size_t *size_lim;
|
||||
|
||||
/**@brief Store constant values to set mem giver res_flag
|
||||
* - For @ref RPN_IF_CONST_RGBA const_val points on a single value
|
||||
* - For @ref RPN_IF_RES_CONST_RGBA const_val points on a single value
|
||||
* - For @ref RPN_IF_RES_CONST_RGBA const_val points on 4 values
|
||||
*/
|
||||
rpn_value_t *const_val;
|
||||
|
@ -74,49 +80,49 @@ int rpn_if_argf_default(rpn_if_t *rif, size_t pos, rpn_value_t *args);
|
|||
int rpn_if_resf_default(rpn_if_t *rif, size_t *pos, rpn_value_t *data);
|
||||
|
||||
/**@brief Set the first expression argument from position
|
||||
* @params rif Expressions
|
||||
* @params pos Memory map offset
|
||||
* @params args pointer on expressions arguments
|
||||
* @param rif Expressions
|
||||
* @param pos Memory map offset
|
||||
* @param args pointer on expressions arguments
|
||||
* @note Other arguments are set using the generic @ref rpn_if_argf_default
|
||||
* function
|
||||
*/
|
||||
int rpn_if_argf_linear(rpn_if_t *rif, size_t pos, rpn_value_t *args);
|
||||
/**@brief Transform 1st expression result to position
|
||||
* @params rif Expressions
|
||||
* @params pos Pointer on resulting position in memory map
|
||||
* @params data Pointer on resulting data
|
||||
* @param rif Expressions
|
||||
* @param pos Pointer on resulting position in memory map
|
||||
* @param data Pointer on resulting data
|
||||
* @note Data from position fecth is done by generic @ref rpn_if_resf_default
|
||||
* function
|
||||
*/
|
||||
int rpn_if_resf_linear(rpn_if_t *rif, size_t *pos, rpn_value_t *data);
|
||||
|
||||
/**@brief Set the 1st & 2nd argument from position
|
||||
* @params rif Expressions
|
||||
* @params pos Memory map offset
|
||||
* @params args pointer on expression arguments
|
||||
* @param rif Expressions
|
||||
* @param pos Memory map offset
|
||||
* @param args pointer on expression arguments
|
||||
* @note Other arguments are set using the generic @ref rpn_if_argf_default
|
||||
* function
|
||||
*/
|
||||
int rpn_if_argf_xy(rpn_if_t *rif, size_t pos, rpn_value_t *args);
|
||||
/**@brief Transform 1st and 2nd result into a memory map's offset
|
||||
* @params rif Expressions
|
||||
* @param rif Expressions
|
||||
* @param pos Memory map offset pointer
|
||||
* @params data Pointer on resulting data
|
||||
* @param data Pointer on resulting data
|
||||
* @note Data from position fetch is done by generic @ref rpn_if_resf_default
|
||||
* function
|
||||
*/
|
||||
int rpn_if_resf_xy(rpn_if_t *rif, size_t *pos, rpn_value_t *data);
|
||||
|
||||
/**@brief Set X first arguments from position
|
||||
* @params rif Expressions
|
||||
* @params pos Memory map offset
|
||||
* @params args Pointer on expression arguments
|
||||
* @param rif Expressions
|
||||
* @param pos Memory map offset
|
||||
* @param args Pointer on expression arguments
|
||||
* @note Other arguments are set using the generic @ref rpn_if_argf_default
|
||||
* function
|
||||
*/
|
||||
int rpn_if_argf_xdim(rpn_if_t *rif, size_t pos, rpn_value_t *args);
|
||||
/**@brief Transform X arguments into a memory map's offset
|
||||
* @params rif Expressions
|
||||
* @param rif Expressions
|
||||
* @param pos Memory map offset pointer
|
||||
* @param data Pointer on resulting data
|
||||
* @note Data from position fetch is done by generic @ref rpn_if_resf_default
|
||||
|
|
97
rpn_ifs.c
Normal file
97
rpn_ifs.c
Normal file
|
@ -0,0 +1,97 @@
|
|||
#include "rpn_ifs.h"
|
||||
|
||||
rpn_ifs_t* rpn_ifs_new(rpn_if_param_t *params, rpn_value_t *memmap)
|
||||
{
|
||||
rpn_ifs_t *res;
|
||||
int err;
|
||||
|
||||
if(!(res = malloc(sizeof(rpn_ifs_t))))
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
bzero(res, sizeof(rpn_ifs_t));
|
||||
|
||||
memcpy(&(res->params), params, sizeof(rpn_if_param_t));
|
||||
|
||||
if(memmap)
|
||||
{
|
||||
res->self_mem = 0;
|
||||
res->mem = memmap;
|
||||
}
|
||||
else
|
||||
{
|
||||
res->self_mem = 1;
|
||||
res->mem = mmap(NULL, params->mem_sz, PROT_READ|PROT_WRITE, MAP_ANON,
|
||||
-1, 0);
|
||||
if(res->mem == (void*)-1)
|
||||
{
|
||||
goto mmap_err;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
|
||||
mmap_err:
|
||||
err = errno;
|
||||
free(res);
|
||||
error:
|
||||
err = errno;
|
||||
errno = err;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void rpn_ifs_free(rpn_ifs_t *rifs)
|
||||
{
|
||||
while(rifs->if_sz)
|
||||
{
|
||||
rpn_if_free(rifs->rpn_if[--(rifs->if_sz)]);
|
||||
}
|
||||
if(rifs->self_mem)
|
||||
{
|
||||
munmap(rifs->mem, rifs->params.mem_sz);
|
||||
}
|
||||
if(rifs->rpn_if)
|
||||
{
|
||||
free(rifs->rpn_if);
|
||||
}
|
||||
if(rifs->weight)
|
||||
{
|
||||
free(rifs->weight);
|
||||
}
|
||||
}
|
||||
|
||||
size_t rpn_ifs_add_if(rpn_ifs_t *rifs, rpn_expr_t **exprs, unsigned int weight)
|
||||
{
|
||||
size_t res;
|
||||
void *tmp;
|
||||
|
||||
res = rifs->if_sz + 1;
|
||||
|
||||
if(!(tmp = realloc(rifs->rpn_if, sizeof(rpn_if_t*) * res)))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
rifs->rpn_if = tmp;
|
||||
|
||||
if(!(tmp = realloc(rifs->weight, sizeof(unsigned int) * res)))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
rifs->weight = tmp;
|
||||
|
||||
rifs->weight[rifs->if_sz] = weight;
|
||||
//WRONG expr ARGUMENT !!!
|
||||
rifs->rpn_if[rifs->if_sz] = rpn_if_new(&(rifs->params), *exprs, rifs->mem);
|
||||
if(!rifs->rpn_if[rifs->if_sz])
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
rifs->if_sz++;
|
||||
if(rpn_ifs_weight_update(rifs) < 0)
|
||||
{
|
||||
rpn_ifs_del_if(rifs, res); // don't attempt to ceck for errors..
|
||||
return 0;
|
||||
}
|
||||
return res;
|
||||
}
|
74
rpn_ifs.h
74
rpn_ifs.h
|
@ -22,6 +22,7 @@
|
|||
#include "config.h"
|
||||
|
||||
#include "rpn_jit.h"
|
||||
#include "rpn_if.h"
|
||||
|
||||
/**@defgroup ifs Iterated function system
|
||||
* @brief IFS implementation with RPN expressions
|
||||
|
@ -37,5 +38,78 @@
|
|||
* be able to use both IFS and IF almost tansparently via Python API.
|
||||
*/
|
||||
|
||||
/**@brief struct @ref rpn_ifs_s shortcut */
|
||||
typedef struct rpn_ifs_s rpn_ifs_t;
|
||||
|
||||
/**@brief Stores IFS informations */
|
||||
struct rpn_ifs_s
|
||||
{
|
||||
/**@brief Parameters shared by all IF of the system */
|
||||
rpn_if_param_t params;
|
||||
|
||||
/**@brief Memory map shared by all iterated functions */
|
||||
rpn_value_t *mem;
|
||||
/**@brief If 1 the mem has to be munmap at free time */
|
||||
short self_mem;
|
||||
|
||||
/**@brief Pointers on iterated function structures */
|
||||
rpn_if_t **rpn_if;
|
||||
/**@brief Number of iterated functions in the system */
|
||||
size_t if_sz;
|
||||
|
||||
/**@brief Current position in memory map */
|
||||
size_t pos;
|
||||
|
||||
/**@brief Stores the original chance of choosing corresponding IF */
|
||||
unsigned int *weight;
|
||||
/** @brief Stores an array of 255 pointers on IF allowing fast
|
||||
* random choice */
|
||||
rpn_if_t *if_proba[255];
|
||||
};
|
||||
|
||||
/**@brief Initialize a new IFS struct given params
|
||||
* @param params Individual, but shared, parameters for iteraed functions
|
||||
* in the system
|
||||
* @param memmap A suitable memory map or NULL
|
||||
* @return NULL if error and set errno
|
||||
* @note Initialized system is empty. Use @ref rpn_ifs_add_if to add an iterated
|
||||
* function to the system
|
||||
*/
|
||||
rpn_ifs_t* rpn_ifs_new(rpn_if_param_t *params, rpn_value_t *memmap);
|
||||
|
||||
/**@brief Free ressources of an iterated function system
|
||||
* @param rifs The iterated function system to free
|
||||
*/
|
||||
void rpn_ifs_free(rpn_ifs_t *rifs);
|
||||
|
||||
/**@brief Add a new iterated function to the system
|
||||
* @param rifs The iterated function system
|
||||
* @param exprs Optionnal strings representing RPN expressions for
|
||||
* the new @ref rpn_if_s
|
||||
* @return 0 on error, else returns the new @ref rpn_if_s index
|
||||
* @note if epxrs is NULL empty RPN expressions are used
|
||||
* @todo change the exprs argument when if init will be updated
|
||||
*/
|
||||
size_t rpn_ifs_add_if(rpn_ifs_t *rifs, rpn_expr_t **exprs, unsigned int weight);
|
||||
|
||||
/**@brief Delete an iterated function from the system given its index
|
||||
* @param rifs The iterated function system
|
||||
* @param if_idx The iterated function index in the system
|
||||
* @return -1 if error else 0
|
||||
*/
|
||||
int rpn_ifs_del_if(rpn_ifs_t *rifs, size_t if_idx);
|
||||
|
||||
/**@brief Updates the @ref rpn_ifs_s.if_proba array using
|
||||
* @ref rpn_ifs_s.if_proba values
|
||||
* @param rifs The iterated function system
|
||||
* @return -1 if error else 0
|
||||
*/
|
||||
int rpn_ifs_weight_update(rpn_ifs_t *rifs);
|
||||
|
||||
/**@brief Randomly choose an IF and make a step updating ifs current posisition
|
||||
* @return -1 on error else 0
|
||||
*/
|
||||
int rpn_ifs_step(rpn_ifs_t *rifs);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
35
rpn_jit.c
35
rpn_jit.c
|
@ -58,6 +58,28 @@ int rpn_expr_init(rpn_expr_t* expr, const unsigned char stack_sz,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int rpn_expr_reinit(rpn_expr_t* expr)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
if(!expr)
|
||||
{
|
||||
dprintf(2, "Error, NULL ptr given as expression to rpn_expr_compile");
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
bzero(expr->code_map, expr->code_map_sz);
|
||||
bzero(expr->stack, sizeof(unsigned long) * stack_sz);
|
||||
if(_rpn_expr_init_map(expr) < 0)
|
||||
{
|
||||
snprintf(expr->err_reason, 128,
|
||||
"Unable to re-init code map : %s", strerror(errno));
|
||||
free(expr->expr);
|
||||
expr->state = RPN_ERROR;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int rpn_expr_compile(rpn_expr_t *expr, const char *code)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
|
@ -445,12 +467,15 @@ int _rpn_code_part_cpy(rpn_expr_t *expr, const void *code_part,
|
|||
|
||||
int _rpn_expr_init_map(rpn_expr_t* expr)
|
||||
{
|
||||
expr->code_map_sz = RPN_MAP_CHUNK;
|
||||
expr->code_map = mmap(NULL, expr->code_map_sz, PROT_READ | PROT_WRITE,
|
||||
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||
if(!expr->code_map)
|
||||
if(!expr->code_map_sz)
|
||||
{
|
||||
return -1;
|
||||
expr->code_map_sz = RPN_MAP_CHUNK;
|
||||
expr->code_map = mmap(NULL, expr->code_map_sz, PROT_READ | PROT_WRITE,
|
||||
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||
if(!expr->code_map)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
expr->code_map_ptr = expr->code_map;
|
||||
if(CODE_PART_CPY(expr, rpn_exec))
|
||||
|
|
|
@ -146,6 +146,11 @@ struct rpn_expr_s
|
|||
int rpn_expr_init(rpn_expr_t* expr, const unsigned char stack_sz,
|
||||
const size_t args_count);
|
||||
|
||||
/**@brief Reinit an existing @ref rpn_expr_s
|
||||
* @param expr
|
||||
*/
|
||||
int rpn_expr_reinit(rpn_expr_t* expr);
|
||||
|
||||
/**@brief Starts a new initialized expression from an expression string
|
||||
* @param expr Pointer on an intialized expression ( see @ref rpn_expr_init )
|
||||
* @param code '\0' terminated string representing the RPN expr
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue