mirror of
https://github.com/johnkerl/miller.git
synced 2026-07-28 10:13:59 +00:00
nested-retval fixup
This commit is contained in:
parent
3141ac9f8e
commit
573f26fbb8
6 changed files with 67 additions and 21 deletions
|
|
@ -212,6 +212,10 @@ static sllv_t* mapper_filter_process(lrec_t* pinrec, context_t* pctx, void* pvst
|
|||
.pctx = pctx,
|
||||
.pbind_stack = NULL,
|
||||
.ploop_stack = NULL,
|
||||
.return_state = {
|
||||
.returned = FALSE,
|
||||
.retval = mv_absent(),
|
||||
}
|
||||
};
|
||||
|
||||
mv_t val = pstate->pevaluator->pprocess_func(pstate->pevaluator->pvstate, &variables);
|
||||
|
|
|
|||
|
|
@ -350,6 +350,10 @@ static sllv_t* mapper_put_process(lrec_t* pinrec, context_t* pctx, void* pvstate
|
|||
.pctx = pctx,
|
||||
.pbind_stack = pstate->pbind_stack,
|
||||
.ploop_stack = pstate->ploop_stack,
|
||||
.return_state = {
|
||||
.returned = FALSE,
|
||||
.retval = mv_absent(),
|
||||
}
|
||||
};
|
||||
cst_outputs_t cst_outputs = (cst_outputs_t) {
|
||||
.pshould_emit_rec = &should_emit_rec,
|
||||
|
|
@ -372,6 +376,10 @@ static sllv_t* mapper_put_process(lrec_t* pinrec, context_t* pctx, void* pvstate
|
|||
.pctx = pctx,
|
||||
.pbind_stack = pstate->pbind_stack,
|
||||
.ploop_stack = pstate->ploop_stack,
|
||||
.return_state = {
|
||||
.returned = FALSE,
|
||||
.retval = mv_absent(),
|
||||
}
|
||||
};
|
||||
cst_outputs_t cst_outputs = (cst_outputs_t) {
|
||||
.pshould_emit_rec = &should_emit_rec,
|
||||
|
|
@ -400,6 +408,10 @@ static sllv_t* mapper_put_process(lrec_t* pinrec, context_t* pctx, void* pvstate
|
|||
.pctx = pctx,
|
||||
.pbind_stack = pstate->pbind_stack,
|
||||
.ploop_stack = pstate->ploop_stack,
|
||||
.return_state = {
|
||||
.returned = FALSE,
|
||||
.retval = mv_absent(),
|
||||
}
|
||||
};
|
||||
cst_outputs_t cst_outputs = (cst_outputs_t) {
|
||||
.pshould_emit_rec = &should_emit_rec,
|
||||
|
|
|
|||
|
|
@ -116,6 +116,8 @@ static void handle_statement_list_with_break_continue(
|
|||
cst_outputs_t* pcst_outputs);
|
||||
|
||||
static cst_statement_handler_t handle_subr_callsite;
|
||||
static cst_statement_handler_t handle_return_void;
|
||||
static cst_statement_handler_t handle_return_value;
|
||||
|
||||
static cst_statement_handler_t handle_local_variable_assignment;
|
||||
static cst_statement_handler_t handle_srec_assignment;
|
||||
|
|
@ -724,7 +726,6 @@ static mlr_dsl_cst_statement_t* alloc_blank() {
|
|||
pstatement->psubr_defsite = NULL;
|
||||
pstatement->local_variable_name = NULL;
|
||||
pstatement->preturn_evaluator = NULL;
|
||||
pstatement->is_return_void = FALSE;
|
||||
pstatement->pblock_handler = NULL;
|
||||
pstatement->poosvar_lhs_keylist_evaluators = NULL;
|
||||
pstatement->pemit_keylist_evaluators = NULL;
|
||||
|
|
@ -776,6 +777,7 @@ static mlr_dsl_cst_statement_t* alloc_return_value(mlr_dsl_cst_t* pcst, mlr_dsl_
|
|||
mlr_dsl_ast_node_t* prhs_node = pnode->pchildren->phead->pvvalue;
|
||||
pstatement->preturn_evaluator = rval_evaluator_alloc_from_ast(prhs_node, pcst->pfmgr,
|
||||
type_inferencing, context_flags);
|
||||
pstatement->pnode_handler = handle_return_value;
|
||||
return pstatement;
|
||||
}
|
||||
|
||||
|
|
@ -783,7 +785,7 @@ static mlr_dsl_cst_statement_t* alloc_return_void(mlr_dsl_cst_t* pcst, mlr_dsl_a
|
|||
int type_inferencing, int context_flags)
|
||||
{
|
||||
mlr_dsl_cst_statement_t* pstatement = alloc_blank();
|
||||
pstatement->is_return_void = TRUE;
|
||||
pstatement->pnode_handler = handle_return_void;
|
||||
return pstatement;
|
||||
}
|
||||
|
||||
|
|
@ -1996,6 +1998,10 @@ void mlr_dsl_cst_handle_statement_list(
|
|||
for (sllve_t* pe = pcst_statements->phead; pe != NULL; pe = pe->pnext) {
|
||||
mlr_dsl_cst_statement_t* pstatement = pe->pvvalue;
|
||||
pstatement->pnode_handler(pstatement, pvars, pcst_outputs);
|
||||
// The UDF/subroutine executor will clear the flag, and consume the retval if there is one.
|
||||
if (pvars->return_state.returned) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2012,6 +2018,10 @@ static void handle_statement_list_with_break_continue(
|
|||
if (loop_stack_get(pvars->ploop_stack) != 0) {
|
||||
break;
|
||||
}
|
||||
// The UDF/subroutine executor will clear the flag, and consume the retval if there is one.
|
||||
if (pvars->return_state.returned) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2030,6 +2040,25 @@ static void handle_subr_callsite(
|
|||
pstatement->subr_callsite_arguments);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
static void handle_return_void(
|
||||
mlr_dsl_cst_statement_t* pstatement,
|
||||
variables_t* pvars,
|
||||
cst_outputs_t* pcst_outputs)
|
||||
{
|
||||
pvars->return_state.returned = TRUE;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
static void handle_return_value(
|
||||
mlr_dsl_cst_statement_t* pstatement,
|
||||
variables_t* pvars,
|
||||
cst_outputs_t* pcst_outputs)
|
||||
{
|
||||
pvars->return_state.returned = TRUE;
|
||||
pvars->return_state.retval = pstatement->preturn_evaluator->pprocess_func(pstatement->preturn_evaluator->pvstate, pvars);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
static void handle_local_variable_assignment(
|
||||
mlr_dsl_cst_statement_t* pstatement,
|
||||
|
|
|
|||
|
|
@ -118,8 +118,6 @@ typedef struct _mlr_dsl_cst_statement_t {
|
|||
|
||||
// Return statement within user-defined function
|
||||
rval_evaluator_t* preturn_evaluator;
|
||||
// Return statement within user-defined subroutine
|
||||
int is_return_void;
|
||||
|
||||
// There are two variants of statement-list handlers: one for inside loop bodies which has to check break/continue
|
||||
// flags after each statement, and another for outside loop bodies which doesn't need to check those. (This is a
|
||||
|
|
|
|||
|
|
@ -144,16 +144,15 @@ static mv_t cst_udf_process_callback(void* pvstate, int arity, mv_t* args, varia
|
|||
|
||||
for (sllve_t* pe = pstate->pblock_statements->phead; pe != NULL; pe = pe->pnext) {
|
||||
mlr_dsl_cst_statement_t* pstatement = pe->pvvalue;
|
||||
if (pstatement->preturn_evaluator != NULL) {
|
||||
// return statement
|
||||
retval = pstatement->preturn_evaluator->pprocess_func(pstatement->preturn_evaluator->pvstate, pvars);
|
||||
pstatement->pnode_handler(pstatement, pvars, pcst_outputs);
|
||||
if (loop_stack_get(pvars->ploop_stack) != 0) {
|
||||
break;
|
||||
}
|
||||
if (pvars->return_state.returned) {
|
||||
pvars->return_state.returned = FALSE;
|
||||
retval = pvars->return_state.retval;
|
||||
pvars->return_state.retval = mv_absent();
|
||||
break;
|
||||
} else {
|
||||
// anything else
|
||||
pstatement->pnode_handler(pstatement, pvars, pcst_outputs);
|
||||
if (loop_stack_get(pvars->ploop_stack) != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -270,15 +269,13 @@ void mlr_dsl_cst_execute_subroutine(subr_defsite_t* pstate, variables_t* pvars,
|
|||
|
||||
for (sllve_t* pe = pstate->pblock_statements->phead; pe != NULL; pe = pe->pnext) {
|
||||
mlr_dsl_cst_statement_t* pstatement = pe->pvvalue;
|
||||
if (pstatement->is_return_void) {
|
||||
// return statement
|
||||
pstatement->pnode_handler(pstatement, pvars, pcst_outputs);
|
||||
if (loop_stack_get(pvars->ploop_stack) != 0) {
|
||||
break;
|
||||
}
|
||||
if (pvars->return_state.returned) {
|
||||
pvars->return_state.returned = FALSE;
|
||||
break;
|
||||
} else {
|
||||
// anything else
|
||||
pstatement->pnode_handler(pstatement, pvars, pcst_outputs);
|
||||
if (loop_stack_get(pvars->ploop_stack) != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,6 +39,11 @@
|
|||
|
||||
struct _rval_evaluator_t; // forward reference for method declarations
|
||||
|
||||
typedef struct _return_state_t {
|
||||
int returned;
|
||||
mv_t retval;
|
||||
} return_state_t;
|
||||
|
||||
typedef struct _variables_t {
|
||||
lrec_t* pinrec;
|
||||
lhmsmv_t* ptyped_overlay;
|
||||
|
|
@ -47,6 +52,7 @@ typedef struct _variables_t {
|
|||
context_t* pctx;
|
||||
bind_stack_t* pbind_stack;
|
||||
loop_stack_t* ploop_stack;
|
||||
return_state_t return_state;
|
||||
} variables_t;
|
||||
|
||||
typedef mv_t rval_evaluator_process_func_t(void* pvstate, variables_t* pvars);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue