mapvar iterate

This commit is contained in:
John Kerl 2016-10-27 22:50:21 -04:00
parent ecd457eec8
commit d61f679dfc
4 changed files with 93 additions and 7 deletions

View file

@ -168,6 +168,7 @@ typedef struct _mlr_dsl_cst_statement_t {
char* local_lhs_variable_name;
int local_lhs_frame_relative_index;
int local_lhs_type_mask;
sllv_t* plocal_map_lhs_keylist_evaluators; // Assignment to local map-variable
// Assignment to srec
char* srec_lhs_field_name;

View file

@ -656,6 +656,7 @@ static mlr_dsl_cst_statement_t* alloc_blank() {
pstatement->preturn_evaluator = NULL;
pstatement->pblock_handler = NULL;
pstatement->poosvar_lhs_keylist_evaluators = NULL;
pstatement->plocal_map_lhs_keylist_evaluators = NULL;
pstatement->pemit_keylist_evaluators = NULL;
pstatement->num_emit_keylist_evaluators = 0;
pstatement->ppemit_keylist_evaluators = NULL;
@ -750,20 +751,33 @@ static mlr_dsl_cst_statement_t* alloc_local_map_variable_assignment(mlr_dsl_cst_
{
mlr_dsl_cst_statement_t* pstatement = alloc_blank();
// xxx keylist evaluators
MLR_INTERNAL_CODING_ERROR_IF((pnode->pchildren == NULL) || (pnode->pchildren->length != 2));
mlr_dsl_ast_node_t* pleft = pnode->pchildren->phead->pvvalue;
mlr_dsl_ast_node_t* pright = pnode->pchildren->phead->pnext->pvvalue;
MLR_INTERNAL_CODING_ERROR_IF(pleft->type != MD_AST_NODE_TYPE_LOCAL_VARIABLE);
MLR_INTERNAL_CODING_ERROR_IF(pleft->pchildren != NULL);
MLR_INTERNAL_CODING_ERROR_IF(pleft->type != MD_AST_NODE_TYPE_LOCAL_MAP_VARIABLE);
MLR_INTERNAL_CODING_ERROR_IF(pleft->pchildren == NULL);
pstatement->pnode_handler = handle_local_map_variable_assignment;
pstatement->local_lhs_variable_name = mlr_strdup_or_die(pleft->text);
MLR_INTERNAL_CODING_ERROR_IF(pleft->vardef_frame_relative_index == MD_UNUSED_INDEX);
pstatement->local_lhs_frame_relative_index = pleft->vardef_frame_relative_index;
// xxx to code up
// sllv_t* plocal_map_lhs_keylist_evaluators = allocate_keylist_evaluators_from_oosvar_node(pcst, pleft,
// type_inferencing, context_flags);
//
// if (pleft->type == MD_AST_NODE_TYPE_OOSVAR_KEYLIST && pright->type == MD_AST_NODE_TYPE_OOSVAR_KEYLIST) {
// pstatement->pnode_handler = handle_oosvar_to_oosvar_assignment;
// pstatement->poosvar_rhs_keylist_evaluators = allocate_keylist_evaluators_from_oosvar_node(pcst, pright,
// type_inferencing, context_flags);
// } else {
// pstatement->pnode_handler = handle_oosvar_assignment;
// pstatement->poosvar_rhs_keylist_evaluators = NULL;
// }
//
// pstatement->plocal_map_lhs_keylist_evaluators = plocal_map_lhs_keylist_evaluators;
pstatement->prhs_evaluator = rval_evaluator_alloc_from_ast(pright, pcst->pfmgr, type_inferencing, context_flags);
return pstatement;
}

View file

@ -43,6 +43,8 @@ rval_evaluator_t* rval_evaluator_alloc_from_indirect_field_name(mlr_dsl_ast_node
int type_inferencing, int context_flags);
rval_evaluator_t* rval_evaluator_alloc_from_oosvar_keylist(mlr_dsl_ast_node_t* pnode, fmgr_t* pfmgr,
int type_inferencing, int context_flags);
rval_evaluator_t* rval_evaluator_alloc_from_local_map_keylist(mlr_dsl_ast_node_t* pnode, fmgr_t* pfmgr,
int type_inferencing, int context_flags);
// This is used for evaluating strings and numbers in literal expressions, e.g. '$x = "abc"'
// or '$x = "left_\1". The values are subject to replacement with regex captures. See comments

View file

@ -90,7 +90,7 @@ rval_evaluator_t* rval_evaluator_alloc_from_ast(mlr_dsl_ast_node_t* pnode, fmgr_
return rval_evaluator_alloc_from_oosvar_keylist(pnode, pfmgr, type_inferencing, context_flags);
} else if (pnode->type == MD_AST_NODE_TYPE_LOCAL_MAP_VARIABLE) {
return NULL; // xxx map-local keylist
return rval_evaluator_alloc_from_local_map_keylist(pnode, pfmgr, type_inferencing, context_flags);
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
} else if (pnode->type == MD_AST_NODE_TYPE_ENV) {
@ -337,6 +337,75 @@ rval_evaluator_t* rval_evaluator_alloc_from_oosvar_keylist(mlr_dsl_ast_node_t* p
return pevaluator;
}
// ================================================================
typedef struct _rval_evaluator_local_map_keylist_state_t {
int vardef_frame_relative_index;
sllv_t* plocal_map_rhs_keylist_evaluators;
} rval_evaluator_local_map_keylist_state_t;
mv_t rval_evaluator_local_map_keylist_func(void* pvstate, variables_t* pvars) {
rval_evaluator_local_map_keylist_state_t* pstate = pvstate;
int all_non_null_or_error = TRUE;
sllmv_t* pmvkeys = evaluate_list(pstate->plocal_map_rhs_keylist_evaluators, pvars, &all_non_null_or_error);
mv_t rv = mv_absent();
if (all_non_null_or_error) {
int error = 0;
mv_t* pval = mlhmmv_get_terminal(pvars->poosvars, pmvkeys, &error); // xxx temp -- get from stack frame
if (pval != NULL) {
if (pval->type == MT_STRING && *pval->u.strv == 0)
rv = mv_empty();
else
rv = mv_copy(pval);
}
}
sllmv_free(pmvkeys);
return rv;
}
static void rval_evaluator_local_map_keylist_free(rval_evaluator_t* pevaluator) {
rval_evaluator_local_map_keylist_state_t* pstate = pevaluator->pvstate;
for (sllve_t* pe = pstate->plocal_map_rhs_keylist_evaluators->phead; pe != NULL; pe = pe->pnext) {
rval_evaluator_t* pevaluator = pe->pvvalue;
pevaluator->pfree_func(pevaluator);
}
sllv_free(pstate->plocal_map_rhs_keylist_evaluators);
free(pstate);
free(pevaluator);
}
rval_evaluator_t* rval_evaluator_alloc_from_local_map_keylist(mlr_dsl_ast_node_t* pnode, fmgr_t* pfmgr,
int type_inferencing, int context_flags)
{
rval_evaluator_local_map_keylist_state_t* pstate = mlr_malloc_or_die(
sizeof(rval_evaluator_local_map_keylist_state_t));
MLR_INTERNAL_CODING_ERROR_IF(pnode->vardef_frame_relative_index == MD_UNUSED_INDEX);
sllv_t* pkeylist_evaluators = sllv_alloc();
for (sllve_t* pe = pnode->pchildren->phead; pe != NULL; pe = pe->pnext) {
mlr_dsl_ast_node_t* pkeynode = pe->pvvalue;
if (pkeynode->type == MD_AST_NODE_TYPE_STRING_LITERAL) {
sllv_append(pkeylist_evaluators, rval_evaluator_alloc_from_string(pkeynode->text));
} else {
sllv_append(pkeylist_evaluators, rval_evaluator_alloc_from_ast(pkeynode, pfmgr,
type_inferencing, context_flags));
}
}
pstate->plocal_map_rhs_keylist_evaluators = pkeylist_evaluators;
rval_evaluator_t* pevaluator = mlr_malloc_or_die(sizeof(rval_evaluator_t));
pevaluator->pvstate = pstate;
pevaluator->pprocess_func = NULL;
pevaluator->pprocess_func = rval_evaluator_local_map_keylist_func;
pevaluator->pfree_func = rval_evaluator_local_map_keylist_free;
return pevaluator;
}
// ================================================================
// This is used for evaluating strings and numbers in literal expressions, e.g. '$x = "abc"'
// or '$x = "left_\1". The values are subject to replacement with regex captures. See comments