xvfuncs iterate: depth, splits, joins

This commit is contained in:
John Kerl 2016-12-06 13:07:58 -05:00
parent 689f14455b
commit 96c003111f
6 changed files with 205 additions and 14 deletions

View file

@ -1,7 +1,7 @@
#include "../containers/xvfuncs.h"
// ----------------------------------------------------------------
boxed_xval_t b_x_haskey_xfunc(boxed_xval_t* pmapval, boxed_xval_t* pkeyval) {
boxed_xval_t b_xx_haskey_xfunc(boxed_xval_t* pmapval, boxed_xval_t* pkeyval) {
if (pmapval->xval.is_terminal) {
return box_ephemeral_val(mv_from_bool(FALSE));
} else if (!pkeyval->xval.is_terminal) {
@ -31,12 +31,28 @@ boxed_xval_t i_x_length_xfunc(boxed_xval_t* pxval1) {
}
// ----------------------------------------------------------------
static int depth_aux(mlhmmv_xvalue_t* pxval) {
if (pxval->is_terminal) {
return 0;
} else {
int max = 0;
for (mlhmmv_level_entry_t* pe = pxval->pnext_level->phead; pe != NULL; pe = pe->pnext) {
int curr = depth_aux(&pe->level_xvalue);
max = (curr > max) ? curr : max;
}
return 1 + max;
}
}
boxed_xval_t i_x_depth_xfunc(boxed_xval_t* pbxval1) {
return box_ephemeral_val(
mv_from_int(777) // xxx stub
mv_from_int(
depth_aux(&pbxval1->xval)
)
);
}
// ----------------------------------------------------------------
static int leafcount_aux(mlhmmv_xvalue_t* pxval) {
if (pxval->is_terminal) {
return 1;
@ -48,6 +64,7 @@ static int leafcount_aux(mlhmmv_xvalue_t* pxval) {
return sum;
}
}
// xxx memmgt
boxed_xval_t i_x_leafcount_xfunc(boxed_xval_t* pbxval1) {
return box_ephemeral_val(
@ -107,3 +124,28 @@ boxed_xval_t variadic_mapdiff_xfunc(boxed_xval_t* pbxvals, int nxvals) {
return box_ephemeral_xval(diff);
}
// ----------------------------------------------------------------
boxed_xval_t m_ss_splitnv_xfunc(boxed_xval_t* pmapval, boxed_xval_t* psepval) {
return box_ephemeral_val(mv_absent()); // xxx stub
}
// ----------------------------------------------------------------
boxed_xval_t m_ss_splitkv_xfunc(boxed_xval_t* pmapval, boxed_xval_t* psepval) {
return box_ephemeral_val(mv_absent()); // xxx stub
}
// ----------------------------------------------------------------
boxed_xval_t s_ms_joink_xfunc(boxed_xval_t* pmapval, boxed_xval_t* psepval) {
return box_ephemeral_val(mv_absent()); // xxx stub
}
// ----------------------------------------------------------------
boxed_xval_t s_ms_joinv_xfunc(boxed_xval_t* pmapval, boxed_xval_t* psepval) {
return box_ephemeral_val(mv_absent()); // xxx stub
}
// ----------------------------------------------------------------
boxed_xval_t s_mss_joinkv_xfunc(boxed_xval_t* pmapval, boxed_xval_t* ppairsepval, boxed_xval_t* plistsepval) {
return box_ephemeral_val(mv_absent()); // xxx stub
}

View file

@ -26,6 +26,11 @@ typedef boxed_xval_t xv_binary_func_t(
boxed_xval_t* pbxval1,
boxed_xval_t* pbxval2);
typedef boxed_xval_t xv_ternary_func_t(
boxed_xval_t* pbxval1,
boxed_xval_t* pbxval2,
boxed_xval_t* pbxval3);
// ----------------------------------------------------------------
// xxx hook all into fmgr
@ -158,7 +163,7 @@ static inline boxed_xval_t s_x_typeof_xfunc(boxed_xval_t* pbxval1) {
}
// ----------------------------------------------------------------
boxed_xval_t b_x_haskey_xfunc(boxed_xval_t* pmapval, boxed_xval_t* pkeyval);
boxed_xval_t b_xx_haskey_xfunc(boxed_xval_t* pmapval, boxed_xval_t* pkeyval);
boxed_xval_t i_x_length_xfunc(boxed_xval_t* pbxval1);
boxed_xval_t i_x_depth_xfunc(boxed_xval_t* pbxval1);
@ -168,10 +173,11 @@ boxed_xval_t variadic_mapsum_xfunc(boxed_xval_t* pbxvals, int nxvals);
boxed_xval_t variadic_mapdiff_xfunc(boxed_xval_t* pbxvals, int nxvals);
// xxx to do (non-inline):
//boxed_xval_t i_m_depth_xfunc(boxed_xval_t* pbxval1);
//boxed_xval_t i_m_deepcount_xfunc(boxed_xval_t* pbxval1);
//boxed_xval_t m_ss_split_xfunc(boxed_xval_t* pbxval1, boxed_xval_t* pbxval2);
//boxed_xval_t s_ms_join_xfunc(boxed_xval_t* pbxval1, boxed_xval_t* pbxval2);
boxed_xval_t m_ss_splitnv_xfunc(boxed_xval_t* pmapval, boxed_xval_t* psepval);
boxed_xval_t m_ss_splitkv_xfunc(boxed_xval_t* pmapval, boxed_xval_t* psepval);
boxed_xval_t s_ms_joink_xfunc(boxed_xval_t* pmapval, boxed_xval_t* psepval);
boxed_xval_t s_ms_joinv_xfunc(boxed_xval_t* pmapval, boxed_xval_t* psepval);
boxed_xval_t s_mss_joinkv_xfunc(boxed_xval_t* pmapval, boxed_xval_t* ppairsepval, boxed_xval_t* plistsepval);
#endif // XVFUNCS_H

View file

@ -63,6 +63,8 @@ static rxval_evaluator_t* fmgr_alloc_xevaluator_from_variadic_func_name(char* fu
static rxval_evaluator_t* fmgr_alloc_xevaluator_from_unary_func_name(char* fnnm, rxval_evaluator_t* parg1);
static rxval_evaluator_t* fmgr_alloc_xevaluator_from_binary_func_name(char* fnnm, rxval_evaluator_t* parg1,
rxval_evaluator_t* pargs2);
static rxval_evaluator_t* fmgr_alloc_xevaluator_from_ternary_func_name(char* fnnm, rxval_evaluator_t* parg1,
rxval_evaluator_t* pargs2, rxval_evaluator_t* pargs3);
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
static void resolve_func_callsite(fmgr_t* pfmgr, rval_evaluator_t* pev);
@ -313,6 +315,11 @@ static function_lookup_t FUNCTION_LOOKUP_TABLE[] = {
{FUNC_CLASS_MAPS, "leafcount", 1,0, "xxx temp."},
{FUNC_CLASS_MAPS, "mapsum", 0,1, "xxx temp."},
{FUNC_CLASS_MAPS, "mapdiff", 0,1, "xxx temp."},
{FUNC_CLASS_MAPS, "splitnv", 2,0, "xxx temp."},
{FUNC_CLASS_MAPS, "splitkv", 2,0, "xxx temp."},
{FUNC_CLASS_MAPS, "joink", 2,0, "xxx temp."},
{FUNC_CLASS_MAPS, "joinv", 2,0, "xxx temp."},
{FUNC_CLASS_MAPS, "joinkv", 2,0, "xxx temp."},
{0, NULL, -1 , -1, NULL}, // table terminator
};
@ -1173,6 +1180,15 @@ static rxval_evaluator_t* construct_builtin_function_callsite_xevaluator(
rxval_evaluator_t* parg2 = rxval_evaluator_alloc_from_ast(parg2_node, pfmgr, type_inferencing, context_flags);
pxevaluator = fmgr_alloc_xevaluator_from_binary_func_name(function_name, parg1, parg2);
} else if (user_provided_arity == 3) {
mlr_dsl_ast_node_t* parg1_node = pnode->pchildren->phead->pvvalue;
mlr_dsl_ast_node_t* parg2_node = pnode->pchildren->phead->pnext->pvvalue;
mlr_dsl_ast_node_t* parg3_node = pnode->pchildren->phead->pnext->pnext->pvvalue;
rxval_evaluator_t* parg1 = rxval_evaluator_alloc_from_ast(parg1_node, pfmgr, type_inferencing, context_flags);
rxval_evaluator_t* parg2 = rxval_evaluator_alloc_from_ast(parg2_node, pfmgr, type_inferencing, context_flags);
rxval_evaluator_t* parg3 = rxval_evaluator_alloc_from_ast(parg3_node, pfmgr, type_inferencing, context_flags);
pxevaluator = fmgr_alloc_xevaluator_from_ternary_func_name(function_name, parg1, parg2, parg3);
}
// xxx arity check ...
@ -1251,7 +1267,26 @@ static rxval_evaluator_t* fmgr_alloc_xevaluator_from_binary_func_name(char* fnnm
rxval_evaluator_t* parg2)
{
if (streq(fnnm, "haskey")) {
return rxval_evaluator_alloc_from_x_mx_func(b_x_haskey_xfunc, parg1, parg2);
return rxval_evaluator_alloc_from_x_mx_func(b_xx_haskey_xfunc, parg1, parg2);
} else if (streq(fnnm, "splitnv")) {
return rxval_evaluator_alloc_from_x_ms_func(m_ss_splitnv_xfunc, parg1, parg2);
} else if (streq(fnnm, "splitkv")) {
return rxval_evaluator_alloc_from_x_ms_func(m_ss_splitkv_xfunc, parg1, parg2);
} else if (streq(fnnm, "joink")) {
return rxval_evaluator_alloc_from_x_ms_func(s_ms_joink_xfunc, parg1, parg2);
} else if (streq(fnnm, "joinv")) {
return rxval_evaluator_alloc_from_x_ms_func(s_ms_joinv_xfunc, parg1, parg2);
} else {
return NULL;
}
}
// ----------------------------------------------------------------
static rxval_evaluator_t* fmgr_alloc_xevaluator_from_ternary_func_name(char* fnnm, rxval_evaluator_t* parg1,
rxval_evaluator_t* parg2, rxval_evaluator_t* parg3)
{
if (streq(fnnm, "joinkv")) {
return rxval_evaluator_alloc_from_x_mss_func(s_mss_joinkv_xfunc, parg1, parg2, parg3);
} else {
return NULL;
}

View file

@ -197,5 +197,9 @@ rxval_evaluator_t* rxval_evaluator_alloc_from_x_x_func(xv_unary_func_t* pfunc, r
rxval_evaluator_t* rxval_evaluator_alloc_from_x_m_func(xv_unary_func_t* pfunc, rxval_evaluator_t* parg1);
rxval_evaluator_t* rxval_evaluator_alloc_from_x_mx_func(xv_binary_func_t* pfunc, rxval_evaluator_t* parg1,
rxval_evaluator_t* parg2);
rxval_evaluator_t* rxval_evaluator_alloc_from_x_ms_func(xv_binary_func_t* pfunc, rxval_evaluator_t* parg1,
rxval_evaluator_t* parg2);
rxval_evaluator_t* rxval_evaluator_alloc_from_x_mss_func(xv_ternary_func_t* pfunc, rxval_evaluator_t* parg1,
rxval_evaluator_t* parg2, rxval_evaluator_t* parg3);
#endif // LREC_FEVALUATORS_H

View file

@ -183,3 +183,109 @@ rxval_evaluator_t* rxval_evaluator_alloc_from_x_mx_func(xv_binary_func_t* pfunc,
return pxevaluator;
}
// ----------------------------------------------------------------
typedef struct _rxval_evaluator_x_ms_state_t {
xv_binary_func_t* pfunc;
rxval_evaluator_t* parg1;
rxval_evaluator_t* parg2;
} rxval_evaluator_x_ms_state_t;
static boxed_xval_t rxval_evaluator_x_ms_func(void* pvstate, variables_t* pvars) {
rxval_evaluator_x_ms_state_t* pstate = pvstate;
boxed_xval_t bxval1 = pstate->parg1->pprocess_func(pstate->parg1->pvstate, pvars);
boxed_xval_t bxval2 = pstate->parg2->pprocess_func(pstate->parg2->pvstate, pvars);
if (bxval1.xval.is_terminal) {
return box_ephemeral_val(mv_error());
}
if (!bxval2.xval.is_terminal) {
return box_ephemeral_val(mv_error());
}
// xxx to-string ...
return pstate->pfunc(&bxval1, &bxval2);
}
static void rxval_evaluator_x_ms_free(rxval_evaluator_t* pxevaluator) {
rxval_evaluator_x_ms_state_t* pstate = pxevaluator->pvstate;
pstate->parg1->pfree_func(pstate->parg1);
pstate->parg2->pfree_func(pstate->parg2);
free(pstate);
free(pxevaluator);
}
rxval_evaluator_t* rxval_evaluator_alloc_from_x_ms_func(xv_binary_func_t* pfunc,
rxval_evaluator_t* parg1, rxval_evaluator_t* parg2)
{
rxval_evaluator_x_ms_state_t* pstate = mlr_malloc_or_die(sizeof(rxval_evaluator_x_ms_state_t));
pstate->pfunc = pfunc;
pstate->parg1 = parg1;
pstate->parg2 = parg2;
rxval_evaluator_t* pxevaluator = mlr_malloc_or_die(sizeof(rxval_evaluator_t));
pxevaluator->pvstate = pstate;
pxevaluator->pprocess_func = rxval_evaluator_x_ms_func;
pxevaluator->pfree_func = rxval_evaluator_x_ms_free;
return pxevaluator;
}
// ----------------------------------------------------------------
typedef struct _rxval_evaluator_x_mss_state_t {
xv_ternary_func_t* pfunc;
rxval_evaluator_t* parg1;
rxval_evaluator_t* parg2;
rxval_evaluator_t* parg3;
} rxval_evaluator_x_mss_state_t;
static boxed_xval_t rxval_evaluator_x_mss_func(void* pvstate, variables_t* pvars) {
rxval_evaluator_x_mss_state_t* pstate = pvstate;
boxed_xval_t bxval1 = pstate->parg1->pprocess_func(pstate->parg1->pvstate, pvars);
boxed_xval_t bxval2 = pstate->parg2->pprocess_func(pstate->parg2->pvstate, pvars);
boxed_xval_t bxval3 = pstate->parg3->pprocess_func(pstate->parg3->pvstate, pvars);
if (bxval1.xval.is_terminal) {
return box_ephemeral_val(mv_error());
}
if (!bxval2.xval.is_terminal) {
return box_ephemeral_val(mv_error());
}
if (!bxval3.xval.is_terminal) {
return box_ephemeral_val(mv_error());
}
// xxx to-string ...
return pstate->pfunc(&bxval1, &bxval2, &bxval3);
}
static void rxval_evaluator_x_mss_free(rxval_evaluator_t* pxevaluator) {
rxval_evaluator_x_mss_state_t* pstate = pxevaluator->pvstate;
pstate->parg1->pfree_func(pstate->parg1);
pstate->parg2->pfree_func(pstate->parg2);
pstate->parg3->pfree_func(pstate->parg3);
free(pstate);
free(pxevaluator);
}
rxval_evaluator_t* rxval_evaluator_alloc_from_x_mss_func(xv_ternary_func_t* pfunc,
rxval_evaluator_t* parg1, rxval_evaluator_t* parg2, rxval_evaluator_t* parg3)
{
rxval_evaluator_x_mss_state_t* pstate = mlr_malloc_or_die(sizeof(rxval_evaluator_x_mss_state_t));
pstate->pfunc = pfunc;
pstate->parg1 = parg1;
pstate->parg2 = parg2;
pstate->parg3 = parg3;
rxval_evaluator_t* pxevaluator = mlr_malloc_or_die(sizeof(rxval_evaluator_t));
pxevaluator->pvstate = pstate;
pxevaluator->pprocess_func = rxval_evaluator_x_mss_func;
pxevaluator->pfree_func = rxval_evaluator_x_mss_free;
return pxevaluator;
}

View file

@ -30,10 +30,8 @@ OTHER:
MAPVAR CHECKLIST:
* new functions:
? unary m->i DEPTH
mlr --from s put -f stdlib.mlr -e 'begin{@u=999}@v[NR]=@*; $n=deepcount(@v);dump'
- binary m,s->s JOIN
- binary s,s->m SPLIT
- binary m,s->s JOINK JOINV JOINKV
- binary s,s->m SPLITNV SPLITKV
* debt-reduction
! naming conventions to clarify transfer/copy semantics
@ -248,7 +246,7 @@ UT FOR 5.0.0:
* UT xfuncs:
- ispresent isabsent ismap isscalar & all other predicates
- haskey
- length leafcount
- length depth leafcount
- typeof
~ mapsum mapdiff