From 96c003111f2eb27cfd5016fe26ef2c55f10fc8ca Mon Sep 17 00:00:00 2001 From: John Kerl Date: Tue, 6 Dec 2016 13:07:58 -0500 Subject: [PATCH] xvfuncs iterate: depth, splits, joins --- c/containers/xvfuncs.c | 46 ++++++++++++++- c/containers/xvfuncs.h | 18 ++++-- c/dsl/function_manager.c | 37 +++++++++++- c/dsl/rval_evaluators.h | 4 ++ c/dsl/rxval_func_evaluators.c | 106 ++++++++++++++++++++++++++++++++++ c/todo.txt | 8 +-- 6 files changed, 205 insertions(+), 14 deletions(-) diff --git a/c/containers/xvfuncs.c b/c/containers/xvfuncs.c index 6646884b4..79c29315b 100644 --- a/c/containers/xvfuncs.c +++ b/c/containers/xvfuncs.c @@ -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 +} diff --git a/c/containers/xvfuncs.h b/c/containers/xvfuncs.h index b1b874314..3d7512f10 100644 --- a/c/containers/xvfuncs.h +++ b/c/containers/xvfuncs.h @@ -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 diff --git a/c/dsl/function_manager.c b/c/dsl/function_manager.c index 5de9e85e9..b4c8430c7 100644 --- a/c/dsl/function_manager.c +++ b/c/dsl/function_manager.c @@ -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; } diff --git a/c/dsl/rval_evaluators.h b/c/dsl/rval_evaluators.h index e7cceaac7..66fb433f7 100644 --- a/c/dsl/rval_evaluators.h +++ b/c/dsl/rval_evaluators.h @@ -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 diff --git a/c/dsl/rxval_func_evaluators.c b/c/dsl/rxval_func_evaluators.c index 6ed10acd8..a19814cd7 100644 --- a/c/dsl/rxval_func_evaluators.c +++ b/c/dsl/rxval_func_evaluators.c @@ -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; +} diff --git a/c/todo.txt b/c/todo.txt index 6d10002e2..1d9f48a4e 100644 --- a/c/todo.txt +++ b/c/todo.txt @@ -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