mapvar iterate: recursive-map-literal 1st light

This commit is contained in:
John Kerl 2016-11-10 09:17:13 -05:00
parent 2f22d5147b
commit f9fba12f68
4 changed files with 49 additions and 21 deletions

View file

@ -263,6 +263,21 @@ static void mlhmmv_level_put_no_enlarge(mlhmmv_level_t* plevel, sllmve_t* prest_
}
}
// ----------------------------------------------------------------
mlhmmv_level_t* mlhmmv_put_empty_map_from_level(mlhmmv_level_t* plevel, sllmve_t* prest_keys) {
mv_t x = mv_absent();
mlhmmv_put_terminal_from_level(plevel, prest_keys, &x); // xxx optimize to avoid 2nd lookup
int error;
sllmv_t s = { // xxx simplify API
.phead = prest_keys,
.ptail = prest_keys,
.length = 1
};
mlhmmv_value_t* pxval = mlhmmv_get_value_from_level(plevel, &s, &error);
*pxval = mlhmmv_value_alloc_empty_map();
return pxval->u.pnext_level;
}
// ----------------------------------------------------------------
// This is done only on map-level enlargement.
// Example:

View file

@ -99,6 +99,7 @@ mv_t* mlhmmv_get_terminal_from_level(mlhmmv_level_t* plevel, sllmv_t* pmvkeys, i
// level of the mlhmmv, then copy values there.
mlhmmv_level_t* mlhmmv_get_or_create_level(mlhmmv_t* pmap, sllmv_t* pmvkeys);
void mlhmmv_put_terminal_from_level(mlhmmv_level_t* plevel, sllmve_t* prest_keys, mv_t* pterminal_value);
mlhmmv_level_t* mlhmmv_put_empty_map_from_level(mlhmmv_level_t* plevel, sllmve_t* prest_keys);
// This is an assignment for assignment to full srec, e.g. '$* = @records[$key1][$key2]'.
// The CST logic can use this function to get the @records[$key1][$key2] level of the mlhmmv,

View file

@ -490,7 +490,7 @@ mv_t sub_precomp_func(mv_t* pval1, regex_t* pregex, string_builder_t* psb, mv_t*
return mv_from_string_with_free(output);
} else {
mv_free(pval3);
return mv_from_string_with_free(mlr_strdup_or_die(output));
return mv_from_string_with_free(mlr_strdup_or_die(output)); // just modify regex_sub to always alloc
}
}

View file

@ -104,7 +104,7 @@ rxval_evaluator_t* rxval_evaluator_alloc_from_ast(mlr_dsl_ast_node_t* pnode, fmg
// text="m", type=NONINDEXED_LOCAL_VARIABLE.
typedef struct _map_literal_list_evaluator_t {
sllv_t* ppairs;
sllv_t* ppair_evaluators;
} map_literal_list_evaluator_t;
typedef struct _map_literal_pair_evaluator_t {
rval_evaluator_t* pkey_evaluator;
@ -117,7 +117,7 @@ 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->ppairs = sllv_alloc();
plist_evaluator->ppair_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) {
@ -149,7 +149,7 @@ static map_literal_list_evaluator_t* allocate_map_literal_evaluator_from_ast(
MLR_INTERNAL_CODING_ERROR();
}
sllv_append(plist_evaluator->ppairs, ppair);
sllv_append(plist_evaluator->ppair_evaluators, ppair);
}
return plist_evaluator;
}
@ -159,26 +159,36 @@ 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->ppair_evaluators->phead; pe != NULL; pe = pe->pnext) {
map_literal_pair_evaluator_t* ppair = pe->pvvalue;
// mlhmmv_put_terminal_from_level will copy keys and values
mv_t mvkey = ppair->pkey_evaluator->pprocess_func(ppair->pkey_evaluator->pvstate, pvars);
if (ppair->is_terminal) {
sllmve_t e = { .value = mvkey, .free_flags = 0, .pnext = NULL };
mv_t mvval = ppair->pval_evaluator->pprocess_func(ppair->pval_evaluator->pvstate, pvars);
mlhmmv_put_terminal_from_level(plevel, &e, &mvval);
} else {
// xxx make mlhmmv method
sllmve_t e = { .value = mvkey, .free_flags = 0, .pnext = NULL };
mlhmmv_level_t* pnext_level = mlhmmv_put_empty_map_from_level(plevel, &e);
rxval_evaluator_from_map_literal_aux(pstate, ppair->plist_evaluator, pnext_level, pvars);
}
}
}
mlhmmv_value_t rxval_evaluator_from_map_literal_func(void* pvstate, variables_t* pvars) {
rxval_evaluator_from_map_literal_state_t* pstate = pvstate;
mlhmmv_value_t xval = mlhmmv_value_alloc_empty_map();
for (sllve_t* pe = pstate->proot_list_evaluator->ppairs->phead; pe != NULL; pe = pe->pnext) {
map_literal_pair_evaluator_t* ppair = pe->pvvalue;
// mlhmmv_put_terminal_from_level will copy keys and valuess
mv_t mvkey = ppair->pkey_evaluator->pprocess_func(ppair->pkey_evaluator->pvstate, pvars);
if (ppair->is_terminal) {
sllmve_t e = { .value = mvkey, .free_flags = 0, .pnext = NULL };
mv_t mvval = ppair->pval_evaluator->pprocess_func(ppair->pval_evaluator->pvstate, pvars);
mlhmmv_put_terminal_from_level(xval.u.pnext_level, &e, &mvval);
} else {
//xxx recurse on ppair->plist_evaluator; -- xxx need an aux func
}
}
rxval_evaluator_from_map_literal_aux(pstate, pstate->proot_list_evaluator, xval.u.pnext_level, pvars);
return xval;
}
@ -373,11 +383,13 @@ mlhmmv_value_t rxval_evaluator_from_full_srec_func(void* pvstate, variables_t* p
mlhmmv_value_t xval = mlhmmv_value_alloc_empty_map(); // xxx memory leak. replace w/ initter.
for (lrece_t* pe = pvars->pinrec->phead; pe != NULL; pe = pe->pnext) {
mv_t k = mv_from_string(pe->key, NO_FREE); // mlhmmv_put_terminal_from_level will copy
// mlhmmv_put_terminal_from_level 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_put_terminal_from_level(xval.u.pnext_level, &e, pomv);
mlhmmv_put_terminal_from_level(xval.u.pnext_level, &e, pomv); // xxx make a simpler 1-level API call
} else {
mv_t v = mv_from_string(pe->value, NO_FREE); // mlhmmv_put_terminal_from_level will copy
mlhmmv_put_terminal_from_level(xval.u.pnext_level, &e, &v);