From 2d902cdb03cb2b8cf320d959c968b89bd20ebdbc Mon Sep 17 00:00:00 2001 From: John Kerl Date: Sat, 29 Oct 2016 10:09:06 -0400 Subject: [PATCH] mapvar iterate --- c/containers/local_stack.c | 18 ++++++++++++++++++ c/containers/local_stack.h | 18 +++++++++++++++--- c/containers/mlhmmv.c | 13 +++++++++++++ c/containers/mlhmmv.h | 1 + c/mapping/mlr_dsl_cst_statements.c | 4 ++-- c/mapping/rval_expr_evaluators.c | 9 +++------ 6 files changed, 52 insertions(+), 11 deletions(-) diff --git a/c/containers/local_stack.c b/c/containers/local_stack.c index 0d4b25bad..3eed6c0b3 100644 --- a/c/containers/local_stack.c +++ b/c/containers/local_stack.c @@ -96,6 +96,24 @@ local_stack_frame_t* local_stack_pop(local_stack_t* pstack) { return sllv_pop(pstack->pframes); } +// ---------------------------------------------------------------- +mv_t local_stack_frame_get_map(local_stack_frame_t* pframe, + int vardef_frame_relative_index, sllmv_t* pmvkeys) +{ + LOCAL_STACK_TRACE(printf("LOCAL STACK FRAME %p GET %d\n", pframe, vardef_frame_relative_index)); + LOCAL_STACK_BOUNDS_CHECK(pframe, "GET", FALSE, vardef_frame_relative_index); + + local_stack_frame_entry_t* pentry = &pframe->pvars[vardef_frame_relative_index]; + mlhmmv_value_t* pmvalue = &pentry->value; + // xxx encapsulate + if (pmvalue->is_terminal) { + return mv_absent(); + } else { + int error = 0; + return *mlhmmv_get_terminal_from_level(pmvalue->u.pnext_level, pmvkeys, &error); + } +} + // ---------------------------------------------------------------- void local_stack_frame_assign_map(local_stack_frame_t* pframe, int vardef_frame_relative_index, sllmv_t* pmvkeys, diff --git a/c/containers/local_stack.h b/c/containers/local_stack.h index 982306ddd..f961b9686 100644 --- a/c/containers/local_stack.h +++ b/c/containers/local_stack.h @@ -78,12 +78,24 @@ void local_stack_frame_exit(local_stack_frame_t* pframe); void local_stack_frame_throw_type_mismatch(local_stack_frame_entry_t* pentry, mv_t* pval); // ---------------------------------------------------------------- -static inline mlhmmv_value_t* local_stack_frame_get(local_stack_frame_t* pframe, int vardef_frame_relative_index) { +static inline mv_t local_stack_frame_get_non_map(local_stack_frame_t* pframe, + int vardef_frame_relative_index) +{ LOCAL_STACK_TRACE(printf("LOCAL STACK FRAME %p GET %d\n", pframe, vardef_frame_relative_index)); LOCAL_STACK_BOUNDS_CHECK(pframe, "GET", FALSE, vardef_frame_relative_index); - return &pframe->pvars[vardef_frame_relative_index].value; + // xxx encapsulate + local_stack_frame_entry_t* pentry = &pframe->pvars[vardef_frame_relative_index]; + mlhmmv_value_t* pvalue = &pentry->value; + if (pvalue->is_terminal) { + return pvalue->u.mlrval; + } else { + return mv_absent(); + } } +mv_t local_stack_frame_get_map(local_stack_frame_t* pframe, + int vardef_frame_relative_index, sllmv_t* pmvkeys); + // ---------------------------------------------------------------- static inline void local_stack_frame_define(local_stack_frame_t* pframe, char* variable_name, int vardef_frame_relative_index, int type_mask, mv_t val) @@ -106,7 +118,7 @@ static inline void local_stack_frame_define(local_stack_frame_t* pframe, char* v // ---------------------------------------------------------------- -static inline void local_stack_frame_assign(local_stack_frame_t* pframe, +static inline void local_stack_frame_assign_non_map(local_stack_frame_t* pframe, int vardef_frame_relative_index, mv_t val) { LOCAL_STACK_TRACE(printf("LOCAL STACK FRAME %p SET %d\n", pframe, vardef_frame_relative_index)); diff --git a/c/containers/mlhmmv.c b/c/containers/mlhmmv.c index d9a3eaa81..5e6c7d11c 100644 --- a/c/containers/mlhmmv.c +++ b/c/containers/mlhmmv.c @@ -304,6 +304,7 @@ static void mlhmmv_level_move(mlhmmv_level_t* plevel, mv_t* plevel_key, mlhmmv_v } // ---------------------------------------------------------------- +// xxx merge these two mv_t* mlhmmv_get_terminal(mlhmmv_t* pmap, sllmv_t* pmvkeys, int* perror) { mlhmmv_level_entry_t* plevel_entry = mlhmmv_get_entry_at_level(pmap->proot_level, pmvkeys->phead, perror); if (plevel_entry == NULL) { @@ -316,6 +317,18 @@ mv_t* mlhmmv_get_terminal(mlhmmv_t* pmap, sllmv_t* pmvkeys, int* perror) { return &plevel_entry->level_value.u.mlrval; } +mv_t* mlhmmv_get_terminal_from_level(mlhmmv_level_t* plevel, sllmv_t* pmvkeys, int* perror) { + mlhmmv_level_entry_t* plevel_entry = mlhmmv_get_entry_at_level(plevel, pmvkeys->phead, perror); + if (plevel_entry == NULL) { + return NULL; + } + if (!plevel_entry->level_value.is_terminal) { + *perror = MLHMMV_ERROR_KEYLIST_TOO_SHALLOW; + return NULL; + } + return &plevel_entry->level_value.u.mlrval; +} + // ---------------------------------------------------------------- static mlhmmv_level_entry_t* mlhmmv_get_entry_at_level(mlhmmv_level_t* plevel, sllmve_t* prestkeys, int* perror) { if (perror) diff --git a/c/containers/mlhmmv.h b/c/containers/mlhmmv.h index c24efd213..9564f532e 100644 --- a/c/containers/mlhmmv.h +++ b/c/containers/mlhmmv.h @@ -88,6 +88,7 @@ void mlhmmv_put_terminal(mlhmmv_t* pmap, sllmv_t* pmvkeys, mv_t* pterminal_value // Note: this returns a pointer to the map's data, not to a copy. // The caller shouldn't free it, or modify it. mv_t* mlhmmv_get_terminal(mlhmmv_t* pmap, sllmv_t* pmvkeys, int* perror); +mv_t* mlhmmv_get_terminal_from_level(mlhmmv_level_t* plevel, sllmv_t* pmvkeys, int* perror); // These are an optimization for assignment from full srec, e.g. '@records[$key1][$key2] = $*'. // Using mlhmmv_get_or_create_level, the CST logic can get or create the @records[$key1][$key2] diff --git a/c/mapping/mlr_dsl_cst_statements.c b/c/mapping/mlr_dsl_cst_statements.c index 811790f65..48a2dbf7e 100644 --- a/c/mapping/mlr_dsl_cst_statements.c +++ b/c/mapping/mlr_dsl_cst_statements.c @@ -2254,7 +2254,7 @@ static void handle_local_non_map_variable_assignment( mv_t val = prhs_evaluator->pprocess_func(prhs_evaluator->pvstate, pvars); if (mv_is_present(&val)) { local_stack_frame_t* pframe = local_stack_get_top_frame(pvars->plocal_stack); - local_stack_frame_assign(pframe, pstatement->local_lhs_frame_relative_index, val); + local_stack_frame_assign_non_map(pframe, pstatement->local_lhs_frame_relative_index, val); } else { mv_free(&val); } @@ -2504,7 +2504,7 @@ static void handle_unset_local_variable( cst_outputs_t* pcst_outputs) { local_stack_frame_t* pframe = local_stack_get_top_frame(pvars->plocal_stack); - local_stack_frame_assign(pframe, pvararg->unset_local_variable_frame_relative_index, mv_absent()); + local_stack_frame_assign_non_map(pframe, pvararg->unset_local_variable_frame_relative_index, mv_absent()); } static void handle_unset_vararg_oosvar( diff --git a/c/mapping/rval_expr_evaluators.c b/c/mapping/rval_expr_evaluators.c index d7bdbe135..7d77b104a 100644 --- a/c/mapping/rval_expr_evaluators.c +++ b/c/mapping/rval_expr_evaluators.c @@ -764,13 +764,10 @@ typedef struct _rval_evaluator_from_local_variable_state_t { mv_t rval_evaluator_from_local_variable_func(void* pvstate, variables_t* pvars) { rval_evaluator_from_local_variable_state_t* pstate = pvstate; local_stack_frame_t* pframe = local_stack_get_top_frame(pvars->plocal_stack); - mlhmmv_value_t* pmval = local_stack_frame_get(pframe, pstate->vardef_frame_relative_index); - if (pmval->is_terminal) { - return mv_copy(&pmval->u.mlrval); // xxx temp - } else { - return mv_absent(); - } + mv_t val = local_stack_frame_get_non_map(pframe, pstate->vardef_frame_relative_index); + return mv_copy(&val); } + static void rval_evaluator_from_local_variable_free(rval_evaluator_t* pevaluator) { rval_evaluator_from_local_variable_state_t* pstate = pevaluator->pvstate; free(pstate);