miller/c/mapping/rxval_expr_evaluators.c
2016-11-25 10:50:18 -05:00

530 lines
20 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <ctype.h> // for tolower(), toupper()
#include "lib/mlr_globals.h"
#include "lib/mlrutil.h"
#include "lib/mlrregex.h"
#include "lib/mtrand.h"
#include "mapping/mapper.h"
#include "mapping/rval_evaluators.h"
#include "mapping/function_manager.h"
#include "mapping/mlr_dsl_cst.h" // xxx only for allocate_keylist_evaluators_from_ast_node -- xxx move
#include "mapping/context_flags.h"
// ================================================================
// See comments in rval_evaluators.h
// ================================================================
// ----------------------------------------------------------------
rxval_evaluator_t* rxval_evaluator_alloc_from_ast(mlr_dsl_ast_node_t* pnode, fmgr_t* pfmgr,
int type_inferencing, int context_flags)
{
switch(pnode->type) {
case MD_AST_NODE_TYPE_NONINDEXED_LOCAL_VARIABLE:
return rxval_evaluator_alloc_from_nonindexed_local_variable(
pnode, pfmgr, type_inferencing, context_flags);
return NULL;
break;
case MD_AST_NODE_TYPE_INDEXED_LOCAL_VARIABLE:
return rxval_evaluator_alloc_from_indexed_local_variable(
pnode, pfmgr, type_inferencing, context_flags);
break;
case MD_AST_NODE_TYPE_OOSVAR_KEYLIST:
return rxval_evaluator_alloc_from_oosvar_keylist(
pnode, pfmgr, type_inferencing, context_flags);
break;
case MD_AST_NODE_TYPE_FULL_OOSVAR:
return rxval_evaluator_alloc_from_full_oosvar(
pnode, pfmgr, type_inferencing, context_flags);
return NULL;
break;
case MD_AST_NODE_TYPE_FULL_SREC:
return rxval_evaluator_alloc_from_full_srec(
pnode, pfmgr, type_inferencing, context_flags);
return NULL;
break;
case MD_AST_NODE_TYPE_FUNCTION_CALLSITE:
// xxx XXX to do
//return rxval_evaluator_alloc_from_function_callsite(
//pnode, pfmgr, type_inferencing, context_flags);
return rxval_evaluator_alloc_wrapping_rval(pnode, pfmgr, type_inferencing, context_flags);
break;
case MD_AST_NODE_TYPE_MAP_LITERAL:
return rxval_evaluator_alloc_from_map_literal(
pnode, pfmgr, type_inferencing, context_flags);
return NULL;
break;
default:
return rxval_evaluator_alloc_wrapping_rval(pnode, pfmgr, type_inferencing, context_flags);
return NULL;
break;
}
}
// ================================================================
// Map-literal input:
//
// {
// "a" : 1,
// "b" : {
// "x" : 7,
// "y" : 8,
// },
// "c" : 3,
// }
//
// Map-literal AST:
//
// $ mlr --from s put -v -q 'm={"a":NR,"b":{"x":999},"c":3};dump m'
// text="block", type=STATEMENT_BLOCK:
// text="=", type=NONINDEXED_LOCAL_ASSIGNMENT:
// text="m", type=NONINDEXED_LOCAL_VARIABLE.
// text="map_literal", type=MAP_LITERAL:
// text="mappair", type=MAP_LITERAL_PAIR:
// text="mapkey", type=MAP_LITERAL:
// text="a", type=STRING_LITERAL.
// text="mapval", type=MAP_LITERAL:
// text="NR", type=CONTEXT_VARIABLE.
// text="mappair", type=MAP_LITERAL_PAIR:
// text="mapkey", type=MAP_LITERAL:
// text="b", type=STRING_LITERAL.
// text="mapval", type=MAP_LITERAL:
// text="map_literal", type=MAP_LITERAL:
// text="mappair", type=MAP_LITERAL_PAIR:
// text="mapkey", type=MAP_LITERAL:
// text="x", type=STRING_LITERAL.
// text="mapval", type=MAP_LITERAL:
// text="999", type=NUMERIC_LITERAL.
// text="mappair", type=MAP_LITERAL_PAIR:
// text="mapkey", type=MAP_LITERAL:
// text="c", type=STRING_LITERAL.
// text="mapval", type=MAP_LITERAL:
// text="3", type=NUMERIC_LITERAL.
// text="dump", type=DUMP:
// text=">", type=FILE_WRITE:
// text="stdout", type=STDOUT:
// text="m", type=NONINDEXED_LOCAL_VARIABLE.
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
typedef struct _map_literal_list_evaluator_t {
sllv_t* pkvpair_evaluators;
} map_literal_list_evaluator_t;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
typedef struct _map_literal_kvpair_evaluator_t {
rval_evaluator_t* pkey_evaluator;
int is_terminal;
rxval_evaluator_t* pxval_evaluator;
map_literal_list_evaluator_t* plist_evaluator;
} map_literal_kvpair_evaluator_t;
// ----------------------------------------------------------------
static map_literal_list_evaluator_t* allocate_map_literal_evaluator_from_ast(
mlr_dsl_ast_node_t* pnode, fmgr_t* pfmgr, int type_inferencing, int context_flags)
{
map_literal_list_evaluator_t* plist_evaluator = mlr_malloc_or_die(sizeof(map_literal_list_evaluator_t));
plist_evaluator->pkvpair_evaluators = sllv_alloc();
MLR_INTERNAL_CODING_ERROR_IF(pnode->type != MD_AST_NODE_TYPE_MAP_LITERAL);
for (sllve_t* pe = pnode->pchildren->phead; pe != NULL; pe = pe->pnext) {
map_literal_kvpair_evaluator_t* pkvpair = mlr_malloc_or_die(sizeof(map_literal_kvpair_evaluator_t));
*pkvpair = (map_literal_kvpair_evaluator_t) {
.pkey_evaluator = NULL,
.is_terminal = TRUE,
.pxval_evaluator = NULL,
.plist_evaluator = NULL,
};
mlr_dsl_ast_node_t* pchild = pe->pvvalue;
MLR_INTERNAL_CODING_ERROR_IF(pchild->type != MD_AST_NODE_TYPE_MAP_LITERAL_PAIR);
mlr_dsl_ast_node_t* pleft = pchild->pchildren->phead->pvvalue;
MLR_INTERNAL_CODING_ERROR_IF(pleft->type != MD_AST_NODE_TYPE_MAP_LITERAL_KEY);
mlr_dsl_ast_node_t* pkeynode = pleft->pchildren->phead->pvvalue;
pkvpair->pkey_evaluator = rval_evaluator_alloc_from_ast(pkeynode, pfmgr, type_inferencing, context_flags);
mlr_dsl_ast_node_t* pright = pchild->pchildren->phead->pnext->pvvalue;
mlr_dsl_ast_node_t* pvalnode = pright->pchildren->phead->pvvalue;
if (pright->type == MD_AST_NODE_TYPE_MAP_LITERAL_VALUE) {
pkvpair->pxval_evaluator = rxval_evaluator_alloc_from_ast(pvalnode, pfmgr, type_inferencing, context_flags);
} else if (pright->type == MD_AST_NODE_TYPE_MAP_LITERAL) {
pkvpair->is_terminal = FALSE;
pkvpair->plist_evaluator = allocate_map_literal_evaluator_from_ast(
pvalnode, pfmgr, type_inferencing, context_flags);
} else {
MLR_INTERNAL_CODING_ERROR();
}
sllv_append(plist_evaluator->pkvpair_evaluators, pkvpair);
}
return plist_evaluator;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
typedef struct _rxval_evaluator_from_map_literal_state_t {
map_literal_list_evaluator_t* proot_list_evaluator;
} rxval_evaluator_from_map_literal_state_t;
static void rxval_evaluator_from_map_literal_aux(
rxval_evaluator_from_map_literal_state_t* pstate,
map_literal_list_evaluator_t* plist_evaluator,
mlhmmv_level_t* plevel,
variables_t* pvars)
{
for (sllve_t* pe = plist_evaluator->pkvpair_evaluators->phead; pe != NULL; pe = pe->pnext) {
map_literal_kvpair_evaluator_t* pkvpair = pe->pvvalue;
// mlhmmv_level_put_terminal will copy keys and values
mv_t mvkey = pkvpair->pkey_evaluator->pprocess_func(pkvpair->pkey_evaluator->pvstate, pvars);
if (pkvpair->is_terminal) {
sllmve_t e = { .value = mvkey, .free_flags = 0, .pnext = NULL };
boxed_xval_t boxed_xval = pkvpair->pxval_evaluator->pprocess_func(pkvpair->pxval_evaluator->pvstate, pvars);
if (!boxed_xval.xval.is_terminal && !boxed_xval.is_ephemeral) {
mlhmmv_xvalue_t copy_xval = mlhmmv_xvalue_copy(&boxed_xval.xval);
mlhmmv_level_put_xvalue(plevel, &e, &copy_xval);
} else {
mlhmmv_level_put_xvalue(plevel, &e, &boxed_xval.xval);
}
} else {
sllmve_t e = { .value = mvkey, .free_flags = 0, .pnext = NULL };
mlhmmv_level_t* pnext_level = mlhmmv_level_put_empty_map(plevel, &e);
rxval_evaluator_from_map_literal_aux(pstate, pkvpair->plist_evaluator, pnext_level, pvars);
}
}
}
static boxed_xval_t rxval_evaluator_from_map_literal_func(void* pvstate, variables_t* pvars) {
rxval_evaluator_from_map_literal_state_t* pstate = pvstate;
mlhmmv_xvalue_t xval = mlhmmv_xvalue_alloc_empty_map();
rxval_evaluator_from_map_literal_aux(pstate, pstate->proot_list_evaluator, xval.pnext_level, pvars);
return (boxed_xval_t) {
.xval = xval,
.is_ephemeral = TRUE,
};
}
static void rxval_evaluator_from_map_literal_free_aux(map_literal_list_evaluator_t* plist_evaluator) {
for (sllve_t* pe = plist_evaluator->pkvpair_evaluators->phead; pe != NULL; pe = pe->pnext) {
map_literal_kvpair_evaluator_t* pkvpair_evaluator = pe->pvvalue;
if (pkvpair_evaluator->pkey_evaluator != NULL) {
pkvpair_evaluator->pkey_evaluator->pfree_func(pkvpair_evaluator->pkey_evaluator);
}
if (pkvpair_evaluator->pxval_evaluator != NULL) {
pkvpair_evaluator->pxval_evaluator->pfree_func(pkvpair_evaluator->pxval_evaluator);
}
if (pkvpair_evaluator->plist_evaluator != NULL) {
rxval_evaluator_from_map_literal_free_aux(pkvpair_evaluator->plist_evaluator);
}
free(pkvpair_evaluator);
}
sllv_free(plist_evaluator->pkvpair_evaluators);
free(plist_evaluator);
}
static void rxval_evaluator_from_map_literal_free(rxval_evaluator_t* prxval_evaluator) {
rxval_evaluator_from_map_literal_state_t* pstate = prxval_evaluator->pvstate;
rxval_evaluator_from_map_literal_free_aux(pstate->proot_list_evaluator);
free(pstate);
free(prxval_evaluator);
}
rxval_evaluator_t* rxval_evaluator_alloc_from_map_literal(mlr_dsl_ast_node_t* pnode, fmgr_t* pfmgr,
int type_inferencing, int context_flags)
{
rxval_evaluator_from_map_literal_state_t* pstate = mlr_malloc_or_die(
sizeof(rxval_evaluator_from_map_literal_state_t));
pstate->proot_list_evaluator = allocate_map_literal_evaluator_from_ast(
pnode, pfmgr, type_inferencing, context_flags);
rxval_evaluator_t* prxval_evaluator = mlr_malloc_or_die(sizeof(rxval_evaluator_t));
prxval_evaluator->pvstate = pstate;
prxval_evaluator->pprocess_func = rxval_evaluator_from_map_literal_func;
prxval_evaluator->pfree_func = rxval_evaluator_from_map_literal_free;
return prxval_evaluator;
}
// ================================================================
typedef struct _rxval_evaluator_from_nonindexed_local_variable_state_t {
int vardef_frame_relative_index;
} rxval_evaluator_from_nonindexed_local_variable_state_t;
static boxed_xval_t rxval_evaluator_from_nonindexed_local_variable_func(void* pvstate, variables_t* pvars) {
rxval_evaluator_from_nonindexed_local_variable_state_t* pstate = pvstate;
local_stack_frame_t* pframe = local_stack_get_top_frame(pvars->plocal_stack);
mlhmmv_xvalue_t* pxval = local_stack_frame_ref_extended_from_indexed(
pframe, pstate->vardef_frame_relative_index, NULL);
if (pxval == NULL) {
return (boxed_xval_t) {
.xval = mlhmmv_xvalue_wrap_terminal(mv_absent()),
.is_ephemeral = FALSE,
};
} else {
return (boxed_xval_t) {
.xval = *pxval,
.is_ephemeral = FALSE,
};
}
}
static void rxval_evaluator_from_nonindexed_local_variable_free(rxval_evaluator_t* prxval_evaluator) {
rxval_evaluator_from_nonindexed_local_variable_state_t* pstate = prxval_evaluator->pvstate;
free(pstate);
free(prxval_evaluator);
}
rxval_evaluator_t* rxval_evaluator_alloc_from_nonindexed_local_variable(
mlr_dsl_ast_node_t* pnode, fmgr_t* pfmgr, int type_inferencing, int context_flags)
{
rxval_evaluator_from_nonindexed_local_variable_state_t* pstate = mlr_malloc_or_die(
sizeof(rxval_evaluator_from_nonindexed_local_variable_state_t));
MLR_INTERNAL_CODING_ERROR_IF(pnode->vardef_frame_relative_index == MD_UNUSED_INDEX);
pstate->vardef_frame_relative_index = pnode->vardef_frame_relative_index;
rxval_evaluator_t* prxval_evaluator = mlr_malloc_or_die(sizeof(rxval_evaluator_t));
prxval_evaluator->pvstate = pstate;
prxval_evaluator->pprocess_func = rxval_evaluator_from_nonindexed_local_variable_func;
prxval_evaluator->pfree_func = rxval_evaluator_from_nonindexed_local_variable_free;
return prxval_evaluator;
}
// ================================================================
typedef struct _rxval_evaluator_from_indexed_local_variable_state_t {
int vardef_frame_relative_index;
sllv_t* pkeylist_evaluators;
} rxval_evaluator_from_indexed_local_variable_state_t;
static boxed_xval_t rxval_evaluator_from_indexed_local_variable_func(void* pvstate, variables_t* pvars) {
rxval_evaluator_from_indexed_local_variable_state_t* pstate = pvstate;
int all_non_null_or_error = TRUE;
sllmv_t* pmvkeys = evaluate_list(pstate->pkeylist_evaluators, pvars, &all_non_null_or_error);
if (all_non_null_or_error) {
local_stack_frame_t* pframe = local_stack_get_top_frame(pvars->plocal_stack);
mlhmmv_xvalue_t* pxval = local_stack_frame_ref_extended_from_indexed(pframe, pstate->vardef_frame_relative_index,
pmvkeys);
sllmv_free(pmvkeys);
if (pxval == NULL) {
return (boxed_xval_t) {
.xval = mlhmmv_xvalue_wrap_terminal(mv_absent()),
.is_ephemeral = FALSE,
};
} else {
return (boxed_xval_t) {
.xval = *pxval,
.is_ephemeral = FALSE,
};
}
} else {
sllmv_free(pmvkeys);
return (boxed_xval_t) {
.xval = mlhmmv_xvalue_wrap_terminal(mv_absent()),
.is_ephemeral = TRUE,
};
}
}
static void rxval_evaluator_from_indexed_local_variable_free(rxval_evaluator_t* prxval_evaluator) {
rxval_evaluator_from_indexed_local_variable_state_t* pstate = prxval_evaluator->pvstate;
for (sllve_t* pe = pstate->pkeylist_evaluators->phead; pe != NULL; pe = pe->pnext) {
rval_evaluator_t* prval_evaluator = pe->pvvalue;
prval_evaluator->pfree_func(prval_evaluator);
}
sllv_free(pstate->pkeylist_evaluators);
free(pstate);
free(prxval_evaluator);
}
rxval_evaluator_t* rxval_evaluator_alloc_from_indexed_local_variable(
mlr_dsl_ast_node_t* pnode, fmgr_t* pfmgr, int type_inferencing, int context_flags)
{
rxval_evaluator_from_indexed_local_variable_state_t* pstate = mlr_malloc_or_die(
sizeof(rxval_evaluator_from_indexed_local_variable_state_t));
MLR_INTERNAL_CODING_ERROR_IF(pnode->vardef_frame_relative_index == MD_UNUSED_INDEX);
pstate->vardef_frame_relative_index = pnode->vardef_frame_relative_index;
pstate->pkeylist_evaluators = allocate_keylist_evaluators_from_ast_node(
pnode, pfmgr, type_inferencing, context_flags);
rxval_evaluator_t* prxval_evaluator = mlr_malloc_or_die(sizeof(rxval_evaluator_t));
prxval_evaluator->pvstate = pstate;
prxval_evaluator->pprocess_func = rxval_evaluator_from_indexed_local_variable_func;
prxval_evaluator->pfree_func = rxval_evaluator_from_indexed_local_variable_free;
return prxval_evaluator;
}
// ================================================================
typedef struct _rxval_evaluator_from_oosvar_keylist_state_t {
sllv_t* pkeylist_evaluators;
} rxval_evaluator_from_oosvar_keylist_state_t;
static boxed_xval_t rxval_evaluator_from_oosvar_keylist_func(void* pvstate, variables_t* pvars) {
rxval_evaluator_from_oosvar_keylist_state_t* pstate = pvstate;
int all_non_null_or_error = TRUE;
sllmv_t* pmvkeys = evaluate_list(pstate->pkeylist_evaluators, pvars, &all_non_null_or_error);
if (all_non_null_or_error) {
int lookup_error = FALSE;
mlhmmv_xvalue_t* pxval = mlhmmv_level_look_up_and_ref_xvalue(pvars->poosvars->proot_level,
pmvkeys, &lookup_error);
sllmv_free(pmvkeys);
if (pxval != NULL) {
return (boxed_xval_t) {
.xval = *pxval,
.is_ephemeral = FALSE,
};
} else {
return (boxed_xval_t) {
.xval = mlhmmv_xvalue_wrap_terminal(mv_absent()),
.is_ephemeral = TRUE,
};
}
} else {
sllmv_free(pmvkeys);
return (boxed_xval_t) {
.xval = mlhmmv_xvalue_wrap_terminal(mv_absent()),
.is_ephemeral = TRUE,
};
}
}
static void rxval_evaluator_from_oosvar_keylist_free(rxval_evaluator_t* prxval_evaluator) {
rxval_evaluator_from_oosvar_keylist_state_t* pstate = prxval_evaluator->pvstate;
for (sllve_t* pe = pstate->pkeylist_evaluators->phead; pe != NULL; pe = pe->pnext) {
rval_evaluator_t* prval_evaluator = pe->pvvalue;
prval_evaluator->pfree_func(prval_evaluator);
}
sllv_free(pstate->pkeylist_evaluators);
free(pstate);
free(prxval_evaluator);
}
rxval_evaluator_t* rxval_evaluator_alloc_from_oosvar_keylist(
mlr_dsl_ast_node_t* pnode, fmgr_t* pfmgr, int type_inferencing, int context_flags)
{
rxval_evaluator_from_oosvar_keylist_state_t* pstate = mlr_malloc_or_die(
sizeof(rxval_evaluator_from_oosvar_keylist_state_t));
pstate->pkeylist_evaluators = allocate_keylist_evaluators_from_ast_node(
pnode, pfmgr, type_inferencing, context_flags);
rxval_evaluator_t* prxval_evaluator = mlr_malloc_or_die(sizeof(rxval_evaluator_t));
prxval_evaluator->pvstate = pstate;
prxval_evaluator->pprocess_func = rxval_evaluator_from_oosvar_keylist_func;
prxval_evaluator->pfree_func = rxval_evaluator_from_oosvar_keylist_free;
return prxval_evaluator;
}
// ================================================================
static boxed_xval_t rxval_evaluator_from_full_oosvar_func(void* pvstate, variables_t* pvars) {
return (boxed_xval_t) {
.is_ephemeral = FALSE,
.xval = (mlhmmv_xvalue_t) {
.is_terminal = FALSE,
.pnext_level = pvars->poosvars->proot_level,
},
};
}
static void rxval_evaluator_from_full_oosvar_free(rxval_evaluator_t* prxval_evaluator) {
free(prxval_evaluator);
}
rxval_evaluator_t* rxval_evaluator_alloc_from_full_oosvar(
mlr_dsl_ast_node_t* pnode, fmgr_t* pfmgr, int type_inferencing, int context_flags)
{
rxval_evaluator_t* prxval_evaluator = mlr_malloc_or_die(sizeof(rxval_evaluator_t));
prxval_evaluator->pprocess_func = rxval_evaluator_from_full_oosvar_func;
prxval_evaluator->pfree_func = rxval_evaluator_from_full_oosvar_free;
return prxval_evaluator;
}
// ================================================================
static boxed_xval_t rxval_evaluator_from_full_srec_func(void* pvstate, variables_t* pvars) {
boxed_xval_t boxed_xval;
boxed_xval.is_ephemeral = TRUE;
boxed_xval.xval = mlhmmv_xvalue_alloc_empty_map();
for (lrece_t* pe = pvars->pinrec->phead; pe != NULL; pe = pe->pnext) {
// mlhmmv_level_put_terminal will copy mv keys and values so we needn't (and shouldn't)
// duplicate them here.
mv_t k = mv_from_string(pe->key, NO_FREE);
sllmve_t e = { .value = k, .free_flags = 0, .pnext = NULL };
mv_t* pomv = lhmsmv_get(pvars->ptyped_overlay, pe->key);
if (pomv != NULL) {
mlhmmv_level_put_terminal(boxed_xval.xval.pnext_level, &e, pomv); // xxx make a simpler 1-level API call
} else {
mv_t v = mv_from_string(pe->value, NO_FREE); // mlhmmv_level_put_terminal will copy
mlhmmv_level_put_terminal(boxed_xval.xval.pnext_level, &e, &v);
}
}
return boxed_xval;
}
static void rxval_evaluator_from_full_srec_free(rxval_evaluator_t* prxval_evaluator) {
free(prxval_evaluator);
}
rxval_evaluator_t* rxval_evaluator_alloc_from_full_srec(
mlr_dsl_ast_node_t* pnode, fmgr_t* pfmgr, int type_inferencing, int context_flags)
{
rxval_evaluator_t* prxval_evaluator = mlr_malloc_or_die(sizeof(rxval_evaluator_t));
prxval_evaluator->pprocess_func = rxval_evaluator_from_full_srec_func;
prxval_evaluator->pfree_func = rxval_evaluator_from_full_srec_free;
return prxval_evaluator;
}
// ================================================================
typedef struct _rxval_evaluator_wrapping_rval_state_t {
rval_evaluator_t* prval_evaluator;
} rxval_evaluator_wrapping_rval_state_t;
static boxed_xval_t rxval_evaluator_wrapping_rval_func(void* pvstate, variables_t* pvars) {
rxval_evaluator_wrapping_rval_state_t* pstate = pvstate;
rval_evaluator_t* prval_evaluator = pstate->prval_evaluator;
mv_t val = prval_evaluator->pprocess_func(prval_evaluator->pvstate, pvars);
return (boxed_xval_t) {
.xval = mlhmmv_xvalue_wrap_terminal(val),
.is_ephemeral = FALSE, // verify reference semantics for RHS evaluators!
};
}
static void rxval_evaluator_wrapping_rval_free(rxval_evaluator_t* prxval_evaluator) {
rxval_evaluator_wrapping_rval_state_t* pstate = prxval_evaluator->pvstate;
pstate->prval_evaluator->pfree_func(pstate->prval_evaluator);
free(pstate);
free(prxval_evaluator);
}
rxval_evaluator_t* rxval_evaluator_alloc_wrapping_rval(mlr_dsl_ast_node_t* pnode, fmgr_t* pfmgr,
int type_inferencing, int context_flags)
{
rxval_evaluator_wrapping_rval_state_t* pstate = mlr_malloc_or_die(
sizeof(rxval_evaluator_wrapping_rval_state_t));
pstate->prval_evaluator = rval_evaluator_alloc_from_ast(pnode, pfmgr, type_inferencing, context_flags);
rxval_evaluator_t* prxval_evaluator = mlr_malloc_or_die(sizeof(rxval_evaluator_t));
prxval_evaluator->pvstate = pstate;
prxval_evaluator->pprocess_func = rxval_evaluator_wrapping_rval_func;
prxval_evaluator->pfree_func = rxval_evaluator_wrapping_rval_free;
return prxval_evaluator;
}