163 lines
3.3 KiB
C
163 lines
3.3 KiB
C
/*
|
|
* 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 <http://www.gnu.org/licenses/>.
|
|
*/
|
|
#include "rpn_if.h"
|
|
|
|
rpn_if_t* rpn_if_new(const rpn_if_param_t *params, rpn_value_t *memmap)
|
|
{
|
|
rpn_if_t *res;
|
|
size_t i;
|
|
int err;
|
|
|
|
res = malloc(sizeof(rpn_if_t));
|
|
if(!res)
|
|
{
|
|
#if DEBUG
|
|
err = errno;
|
|
perror("rpn_if_new() struct malloc failed");
|
|
errno = err;
|
|
#endif
|
|
goto error;
|
|
}
|
|
|
|
//memcpy(&res->params, params, sizeof(rpn_if_param_t));
|
|
res->params = params;
|
|
|
|
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 | MAP_PRIVATE, -1, 0);
|
|
if(res->mem == (void*)-1)
|
|
{
|
|
#if DEBUG
|
|
err = errno;
|
|
perror("rpn_if_new() mmap failed");
|
|
errno = err;
|
|
#endif
|
|
goto mmap_err;
|
|
}
|
|
}
|
|
|
|
res->rpn_res = malloc(sizeof(rpn_value_t) *
|
|
(params->rpn_sz + params->rpn_argc));
|
|
if(!res->rpn_res)
|
|
{
|
|
#if DEBUG
|
|
err = errno;
|
|
perror("rpn_if_new() rpn_res malloc failed");
|
|
errno = err;
|
|
#endif
|
|
goto rpn_malloc_err;
|
|
}
|
|
res->rpn_args = &(res->rpn_res[params->rpn_sz]);
|
|
|
|
res->rpn = malloc(sizeof(rpn_expr_t*) * params->rpn_sz);
|
|
if(!res->rpn)
|
|
{
|
|
#if DEBUG
|
|
err = errno;
|
|
perror("rpn_if_new() rpn expr malloc failed");
|
|
errno = err;
|
|
#endif
|
|
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)
|
|
{
|
|
#if DEBUG
|
|
err = errno;
|
|
perror("rpn_if_new() rpn_expr_init() failed");
|
|
errno = err;
|
|
#endif
|
|
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;
|
|
if(res->self_mem)
|
|
{
|
|
munmap(res->mem, params->mem_sz);
|
|
}
|
|
mmap_err:
|
|
err = errno;
|
|
free(res);
|
|
error:
|
|
err = errno;
|
|
errno = err;
|
|
return NULL;
|
|
}
|
|
|
|
void rpn_if_free(rpn_if_t* rif)
|
|
{
|
|
size_t i;
|
|
for(i=0; i<rif->params->rpn_sz; i++)
|
|
{
|
|
rpn_expr_close(&(rif->rpn[i]));
|
|
}
|
|
free(rif->rpn);
|
|
free(rif->rpn_res);
|
|
if(rif->self_mem)
|
|
{
|
|
munmap(rif->mem, rif->params->mem_sz);
|
|
}
|
|
free(rif);
|
|
}
|
|
|
|
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);
|
|
/* 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);
|
|
/* 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;
|
|
}
|
|
|
|
rpn_expr_t **rpn_if_rpn_get(rpn_if_t *rif)
|
|
{
|
|
return &(rif->rpn);
|
|
}
|