mapvar-for iterate; name neatens

This commit is contained in:
John Kerl 2016-10-29 21:05:58 -04:00
parent 96cc9a412c
commit c89eeec00d
9 changed files with 493 additions and 412 deletions

View file

@ -97,7 +97,7 @@ local_stack_frame_t* local_stack_pop(local_stack_t* pstack) {
}
// ----------------------------------------------------------------
mv_t local_stack_frame_get_map(local_stack_frame_t* pframe,
mv_t local_stack_frame_get_map(local_stack_frame_t* pframe, // xxx rename
int vardef_frame_relative_index, sllmv_t* pmvkeys)
{
LOCAL_STACK_TRACE(printf("LOCAL STACK FRAME %p GET %d\n", pframe, vardef_frame_relative_index));
@ -125,6 +125,34 @@ mv_t local_stack_frame_get_map(local_stack_frame_t* pframe,
}
}
// a[b][c] w/ [b]
// a[b][c] w/ [b,c]
// a[b][c] w/ [b,c,d]
// ----------------------------------------------------------------
mlhmmv_value_t* local_stack_frame_get_map_value(local_stack_frame_t* pframe, // xxx rename w/ 'reference' in name
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;
if (pmvalue->u.pnext_level == NULL) {
LOCAL_STACK_TRACE(printf("VALUE IS EMPTY\n"));
return NULL;
} else {
int error = 0;
LOCAL_STACK_TRACE(printf("VALUE IS:\n"));
LOCAL_STACK_TRACE(printf("PTR IS %p\n", pmvalue->u.pnext_level));
LOCAL_STACK_TRACE(mlhmmv_level_print_stacked(pmvalue->u.pnext_level, 0, TRUE, TRUE, "", stdout));
// Maybe null
mlhmmv_value_t* pmval = mlhmmv_get_value_from_level(pmvalue->u.pnext_level, pmvkeys, &error);
return pmval;
}
}
// ----------------------------------------------------------------
void local_stack_frame_assign_map(local_stack_frame_t* pframe,
int vardef_frame_relative_index, sllmv_t* pmvkeys,

View file

@ -100,7 +100,10 @@ static inline mv_t local_stack_frame_get_non_map(local_stack_frame_t* pframe,
}
}
mv_t local_stack_frame_get_map(local_stack_frame_t* pframe,
mv_t local_stack_frame_get_map(local_stack_frame_t* pframe, // xxx rename
int vardef_frame_relative_index, sllmv_t* pmvkeys);
mlhmmv_value_t* local_stack_frame_get_map_value(local_stack_frame_t* pframe, // xxx rename
int vardef_frame_relative_index, sllmv_t* pmvkeys);
// ----------------------------------------------------------------

View file

@ -480,6 +480,32 @@ static mlhmmv_value_t* mlhmmv_get_next_level_entry_value(mlhmmv_level_t* pmap, m
return &pentry->level_value;
}
// ----------------------------------------------------------------
mlhmmv_value_t* mlhmmv_get_value_from_level(mlhmmv_level_t* pstart_level, sllmv_t* pmvkeys, int* perror) {
*perror = MLHMMV_ERROR_NONE;
sllmve_t* prest_keys = pmvkeys->phead;
if (prest_keys == NULL) {
*perror = MLHMMV_ERROR_KEYLIST_TOO_SHALLOW;
}
mlhmmv_level_t* plevel = pstart_level;
mlhmmv_level_entry_t* plevel_entry = mlhmmv_get_next_level_entry(plevel, &prest_keys->value, NULL);
while (prest_keys->pnext != NULL) {
if (plevel_entry == NULL) {
return NULL;
} else {
plevel = plevel_entry->level_value.u.pnext_level;
prest_keys = prest_keys->pnext;
plevel_entry = mlhmmv_get_next_level_entry(plevel_entry->level_value.u.pnext_level,
&prest_keys->value, NULL);
}
}
if (plevel_entry == NULL) {
*perror = MLHMMV_ERROR_KEYLIST_TOO_DEEP;
return NULL;
}
return &plevel_entry->level_value;
}
// ----------------------------------------------------------------
// Removes entries from a specified level downward, unsetting any maps which become empty as a result. For example, if
// e.g. a=>b=>c=>4 and the c level is to be removed, then all up-nodes are emptied out & should be pruned.

View file

@ -103,6 +103,8 @@ void mlhmmv_put_terminal_from_level(mlhmmv_level_t* plevel, sllmve_t* prest_keys
// The CST logic can use this function to get the @records[$key1][$key2] level of the mlhmmv,
// then copy values from there.
mlhmmv_level_t* mlhmmv_get_level(mlhmmv_t* pmap, sllmv_t* pmvkeys, int* perror);
// This is for getting submaps out of local variables.
mlhmmv_value_t* mlhmmv_get_value_from_level(mlhmmv_level_t* plevel, sllmv_t* pmvkeys, int* perror);
// For oosvar-to-oosvar assignment.
void mlhmmv_copy(mlhmmv_t* pmap, sllmv_t* ptokeys, sllmv_t* pfromkeys);

View file

@ -266,7 +266,7 @@ char* mlr_dsl_ast_node_describe_type(mlr_dsl_ast_node_type_t type) {
case MD_AST_NODE_TYPE_FULL_OOSVAR: return "FULL_OOSVAR"; break;
case MD_AST_NODE_TYPE_NON_SIGIL_NAME: return "NON_SIGIL_NAME"; break;
case MD_AST_NODE_TYPE_OPERATOR: return "OPERATOR"; break;
case MD_AST_NODE_TYPE_LOCAL_NON_MAP_ASSIGNMENT: return "LOCAL_ASSIGNMENT"; break;
case MD_AST_NODE_TYPE_LOCAL_NON_MAP_ASSIGNMENT: return "LOCAL_NON_MAP_ASSIGNMENT"; break;
case MD_AST_NODE_TYPE_LOCAL_MAP_ASSIGNMENT: return "LOCAL_MAP_ASSIGNMENT"; break;
case MD_AST_NODE_TYPE_SREC_ASSIGNMENT: return "SREC_ASSIGNMENT"; break;
case MD_AST_NODE_TYPE_INDIRECT_SREC_ASSIGNMENT: return "INDIRECT_SREC_ASSIGNMENT"; break;
@ -308,7 +308,7 @@ char* mlr_dsl_ast_node_describe_type(mlr_dsl_ast_node_type_t type) {
case MD_AST_NODE_TYPE_FOR_LOCAL_MAP_KEY_ONLY: return "FOR_LOCAL_MAP_KEY_ONLY"; break;
case MD_AST_NODE_TYPE_FOR_VARIABLES: return "FOR_VARIABLES"; break;
case MD_AST_NODE_TYPE_TRIPLE_FOR: return "TRIPLE_FOR"; break;
case MD_AST_NODE_TYPE_LOCAL_NON_MAP_VARIABLE: return "LOCAL_VARIABLE"; break;
case MD_AST_NODE_TYPE_LOCAL_NON_MAP_VARIABLE: return "LOCAL_NON_MAP_VARIABLE"; break;
case MD_AST_NODE_TYPE_LOCAL_MAP_VARIABLE: return "LOCAL_MAP_VARIABLE"; break;
case MD_AST_NODE_TYPE_IN: return "IN"; break;
case MD_AST_NODE_TYPE_BREAK: return "BREAK"; break;

View file

@ -230,6 +230,8 @@ typedef struct _mlr_dsl_cst_statement_t {
int for_v_frame_relative_index;
int for_v_type_mask;
int for_map_target_frame_relative_index;
type_inferenced_srec_field_getter_t* ptype_inferenced_srec_field_getter;
// triple-for:

View file

@ -181,7 +181,7 @@ static void handle_for_local_map_aux(
mlr_dsl_cst_statement_t* pstatement,
variables_t* pvars,
cst_outputs_t* pcst_outputs,
mlhmmv_value_t submap,
mlhmmv_value_t* psubmap,
char** prest_for_k_variable_names,
int* prest_for_k_frame_relative_indices,
int* prest_for_k_frame_type_masks,
@ -715,6 +715,7 @@ static mlr_dsl_cst_statement_t* alloc_blank() {
pstatement->for_v_variable_name = NULL;
pstatement->for_v_frame_relative_index = 0;
pstatement->for_v_type_mask = TYPE_MASK_ANY;
pstatement->for_map_target_frame_relative_index = 0;
pstatement->ptype_inferenced_srec_field_getter = NULL;
pstatement->ptriple_for_start_statements = NULL;
pstatement->ptriple_for_pre_continuation_statements = NULL;
@ -1349,7 +1350,10 @@ static mlr_dsl_cst_statement_t* alloc_for_local_map(mlr_dsl_cst_t* pcst, mlr_dsl
pstatement->for_v_frame_relative_index = psubright->vardef_frame_relative_index;
pstatement->for_v_type_mask = mlr_dsl_ast_node_type_to_type_mask(psubright->type);
pstatement->poosvar_lhs_keylist_evaluators = allocate_keylist_evaluators_from_oosvar_node(
// xxx comment liberally
MLR_INTERNAL_CODING_ERROR_IF(pmiddle->vardef_frame_relative_index == MD_UNUSED_INDEX);
pstatement->for_map_target_frame_relative_index = pmiddle->vardef_frame_relative_index;
pstatement->poosvar_lhs_keylist_evaluators = allocate_keylist_evaluators_from_oosvar_node( // xxx rename x 2
pcst, pmiddle, type_inferencing, context_flags);
MLR_INTERNAL_CODING_ERROR_IF(pnode->subframe_var_count == MD_UNUSED_INDEX);
@ -3039,26 +3043,36 @@ static void handle_for_local_map( // xxx vardef_frame_relative_index
// of the for-loop, while the k1/k2/v are bound within the for-loop.
int keys_all_non_null_or_error = FALSE;
// xxx confusing 'oosvar' name ... clean up please.
// xxx confusing 'keylist' name ... clean up please.
sllmv_t* plhskeylist = evaluate_list(pstatement->poosvar_lhs_keylist_evaluators, pvars,
&keys_all_non_null_or_error);
if (keys_all_non_null_or_error) {
// In '(for a, b in c) { ... }' the 'c' is evaluated in the outer scope and
// the a, b are bound within the inner scope.
local_stack_frame_t* pframe = local_stack_get_top_frame(pvars->plocal_stack);
//xxx = local_stack_frame_get_map_value(pframe, pstatement->local_lhs_frame_relative_index, pmvkeys);
// Locate and copy the submap indexed by the keylist. E.g. in 'for ((k1, k2), v in a[3][$4])
// { ... }', the submap is first indexed by the stack-frame slot for "a", then further
// indexed by [3, $4]. Copy it for the very likely case that it is being updated inside the
// for-loop.
mlhmmv_value_t *psubmap = local_stack_frame_get_map_value(pframe,
pstatement->for_map_target_frame_relative_index, plhskeylist);
// xxx copy !!!
local_stack_subframe_enter(pframe, pstatement->pstatement_block->subframe_var_count);
loop_stack_push(pvars->ploop_stack);
// Locate and copy the submap indexed by the keylist. E.g. in 'for ((k1, k2), v in @a[3][$4]) { ... }', the
// submap is indexed by ["a", 3, $4]. Copy it for the very likely case that it is being updated inside the
// for-loop.
mlhmmv_value_t submap = mlhmmv_copy_submap(pvars->poosvars, plhskeylist); // xxx local-map
if (!submap.is_terminal && submap.u.pnext_level != NULL) {
if (!psubmap->is_terminal && psubmap->u.pnext_level != NULL) {
// Recurse over the for-k-names, e.g. ["k1", "k2"], on each call descending one level
// deeper into the submap. Note there must be at least one k-name so we are assuming
// the for-loop within handle_for_local_map_aux was gone through once & thus
// handle_statement_block_with_break_continue was called through there.
handle_for_local_map_aux(pstatement, pvars, pcst_outputs, submap,
handle_for_local_map_aux(pstatement, pvars, pcst_outputs, psubmap,
pstatement->for_map_k_variable_names, pstatement->for_map_k_frame_relative_indices,
pstatement->for_map_k_type_masks, pstatement->for_map_k_count);
@ -3070,7 +3084,8 @@ static void handle_for_local_map( // xxx vardef_frame_relative_index
}
}
mlhmmv_free_submap(submap);
// xxx only after impl copy !!!
// mlhmmv_free_submap(submap);
loop_stack_pop(pvars->ploop_stack);
local_stack_subframe_exit(pframe, pstatement->pstatement_block->subframe_var_count);
@ -3082,7 +3097,7 @@ static void handle_for_local_map_aux( // xxx vardef_frame_relative_index
mlr_dsl_cst_statement_t* pstatement,
variables_t* pvars,
cst_outputs_t* pcst_outputs,
mlhmmv_value_t submap,
mlhmmv_value_t* psubmap,
char** prest_for_k_variable_names,
int* prest_for_k_frame_relative_indices,
int* prest_for_k_type_masks,
@ -3090,17 +3105,17 @@ static void handle_for_local_map_aux( // xxx vardef_frame_relative_index
{
if (prest_for_k_count > 0) { // Keep recursing over remaining k-names
if (submap.is_terminal) {
if (psubmap->is_terminal) {
// The submap was too shallow for the user-specified k-names; there are no terminals here.
} else {
// Loop over keys at this submap level:
for (mlhmmv_level_entry_t* pe = submap.u.pnext_level->phead; pe != NULL; pe = pe->pnext) {
for (mlhmmv_level_entry_t* pe = psubmap->u.pnext_level->phead; pe != NULL; pe = pe->pnext) {
// Bind the k-name to the entry-key mlrval:
local_stack_frame_t* pframe = local_stack_get_top_frame(pvars->plocal_stack);
local_stack_frame_define(pframe, prest_for_k_variable_names[0], prest_for_k_frame_relative_indices[0],
prest_for_k_type_masks[0], mv_copy(&pe->level_key));
// Recurse into the next-level submap:
handle_for_local_map_aux(pstatement, pvars, pcst_outputs, pe->level_value,
handle_for_local_map_aux(pstatement, pvars, pcst_outputs, &pe->level_value,
&prest_for_k_variable_names[1], &prest_for_k_frame_relative_indices[1], &prest_for_k_type_masks[1],
prest_for_k_count - 1);
@ -3116,13 +3131,13 @@ static void handle_for_local_map_aux( // xxx vardef_frame_relative_index
} else { // End of recursion: k-names have all been used up
if (!submap.is_terminal) {
if (!psubmap->is_terminal) {
// The submap was too deep for the user-specified k-names; there are no terminals here.
} else {
// Bind the v-name to the terminal mlrval:
local_stack_frame_t* pframe = local_stack_get_top_frame(pvars->plocal_stack);
local_stack_frame_define(pframe, pstatement->for_v_variable_name, pstatement->for_v_frame_relative_index,
pstatement->for_v_type_mask, mv_copy(&submap.u.mlrval));
pstatement->for_v_type_mask, mv_copy(&psubmap->u.mlrval));
// Execute the loop-body statements:
pstatement->pblock_handler(pstatement->pstatement_block, pvars, pcst_outputs);
}
@ -3148,12 +3163,12 @@ static void handle_for_local_map_key_only( // xxx vardef_frame_relative_index
// submap is indexed by ["a", 3, $4]. Copy it for the very likely case that it is being updated inside the
// for-loop.
sllv_t* pkeys = mlhmmv_copy_keys_from_submap(pvars->poosvars, plhskeylist); // xxx for-local-maQ
local_stack_frame_t* pframe = local_stack_get_top_frame(pvars->plocal_stack);
local_stack_subframe_enter(pframe, pstatement->pstatement_block->subframe_var_count);
loop_stack_push(pvars->ploop_stack);
sllv_t* pkeys = mlhmmv_copy_keys_from_submap(pvars->poosvars, plhskeylist); // xxx for-local-maQ
for (sllve_t* pe = pkeys->phead; pe != NULL; pe = pe->pnext) {
// Bind the v-name to the terminal mlrval:
local_stack_frame_define(pframe,

View file

@ -507,6 +507,11 @@ static void pass_1_for_map_key_only_for_loop(mlr_dsl_ast_node_t* pnode, stkalc_s
//
// Example: 'for(a in @b[c][d]) { var e = a}': the c and d
// should be obtained from the enclosing scope.
if (pkeylistnode->type == MD_AST_NODE_TYPE_LOCAL_NON_MAP_VARIABLE) {
// For-local-map: e.g. 'for(a in b[c][d])'.
pass_1_for_node(pkeylistnode, pframe_group, pmax_subframe_depth, trace);
}
for (sllve_t* pe = pkeylistnode->pchildren->phead; pe != NULL; pe = pe->pnext) {
mlr_dsl_ast_node_t* pchild = pe->pvvalue;
pass_1_for_node(pchild, pframe_group, pmax_subframe_depth, trace);

File diff suppressed because it is too large Load diff