From e51f98d6d3e2e9e61d85ae99d78490cbc4184b7a Mon Sep 17 00:00:00 2001 From: John Kerl Date: Thu, 3 Nov 2016 19:05:06 -0400 Subject: [PATCH] cst-federation iterate: condish statements --- c/mapping/Makefile.am | 3 +- c/mapping/mlr_dsl_cst.h | 27 +- c/mapping/mlr_dsl_cst_condish_statements.c | 464 +++++++++++++++++++++ c/mapping/mlr_dsl_cst_statements.c | 335 +-------------- 4 files changed, 482 insertions(+), 347 deletions(-) create mode 100644 c/mapping/mlr_dsl_cst_condish_statements.c diff --git a/c/mapping/Makefile.am b/c/mapping/Makefile.am index cb3c11504..1fb781042 100644 --- a/c/mapping/Makefile.am +++ b/c/mapping/Makefile.am @@ -56,9 +56,10 @@ libmapping_la_SOURCES= \ mlr_dsl_cst_func_subr.c \ mlr_dsl_cst_keywords.c \ mlr_dsl_cst_statements.c \ - mlr_dsl_cst_output_statements.c \ + mlr_dsl_cst_condish_statements.c \ mlr_dsl_cst_for_srec_statements.c \ mlr_dsl_cst_triple_for_statements.c \ + mlr_dsl_cst_output_statements.c \ mlr_dsl_stack_allocate.c \ stats1_accumulators.c \ stats1_accumulators.h \ diff --git a/c/mapping/mlr_dsl_cst.h b/c/mapping/mlr_dsl_cst.h index bcba00769..96fb22b2f 100644 --- a/c/mapping/mlr_dsl_cst.h +++ b/c/mapping/mlr_dsl_cst.h @@ -207,9 +207,6 @@ typedef struct _mlr_dsl_cst_statement_t { // Vararg stuff for emit and unset sllv_t* pvarargs; - // if-elif-elif-else: - sllv_t* pif_chain_statements; - char** for_map_k_variable_names; int* for_map_k_frame_relative_indices; int* for_map_k_type_masks; @@ -378,6 +375,21 @@ void mlr_dsl_keyword_usage(FILE* output_stream, char* keyword); // ================================================================ // xxx comment/reorg ... +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// mapping/mlr_dsl_cst_condish_statements.c +mlr_dsl_cst_statement_allocator_t alloc_conditional_block; +mlr_dsl_cst_statement_allocator_t alloc_if_head; +mlr_dsl_cst_statement_allocator_t alloc_while; +mlr_dsl_cst_statement_allocator_t alloc_do_while; + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// mapping/mlr_dsl_cst_for_srec_statements.c +mlr_dsl_cst_statement_allocator_t alloc_for_srec; + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// mapping/mlr_dsl_cst_triple_for_statements.c +mlr_dsl_cst_statement_allocator_t alloc_triple_for; + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // mapping/mlr_dsl_cst_output_statements.c @@ -408,15 +420,6 @@ mlr_dsl_cst_statement_t* alloc_print( mlr_dsl_cst_statement_allocator_t alloc_dump; -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// mapping/mlr_dsl_cst_for_srec_statements.c -mlr_dsl_cst_statement_allocator_t alloc_for_srec; - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// mapping/mlr_dsl_cst_triple_for_statements.c - -mlr_dsl_cst_statement_allocator_t alloc_triple_for; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // mapping/mlr_dsl_cst_func_subr.c diff --git a/c/mapping/mlr_dsl_cst_condish_statements.c b/c/mapping/mlr_dsl_cst_condish_statements.c new file mode 100644 index 000000000..df16d1ef0 --- /dev/null +++ b/c/mapping/mlr_dsl_cst_condish_statements.c @@ -0,0 +1,464 @@ +#include +#include "lib/mlr_globals.h" +#include "lib/mlrutil.h" +#include "mlr_dsl_cst.h" +#include "context_flags.h" + +// ================================================================ +typedef struct _conditional_block_state_t { + rval_evaluator_t* pexpression_evaluator; +} conditional_block_state_t; + +static mlr_dsl_cst_statement_handler_t handle_conditional_block; +static mlr_dsl_cst_statement_freer_t free_conditional_block; + +// ---------------------------------------------------------------- +mlr_dsl_cst_statement_t* alloc_conditional_block(mlr_dsl_cst_t* pcst, mlr_dsl_ast_node_t* pnode, + int type_inferencing, int context_flags) +{ + conditional_block_state_t* pstate = mlr_malloc_or_die(sizeof(conditional_block_state_t)); + + pstate->pexpression_evaluator = NULL; + + // Right node is a list of statements to be executed if the left evaluates to true. + mlr_dsl_ast_node_t* pleft = pnode->pchildren->phead->pvvalue; + mlr_dsl_ast_node_t* pright = pnode->pchildren->phead->pnext->pvvalue; + + pstate->pexpression_evaluator = rval_evaluator_alloc_from_ast( + pleft, pcst->pfmgr, type_inferencing, context_flags); + + MLR_INTERNAL_CODING_ERROR_IF(pright->subframe_var_count == MD_UNUSED_INDEX); + cst_statement_block_t* pblock = cst_statement_block_alloc(pright->subframe_var_count); + + for (sllve_t* pe = pright->pchildren->phead; pe != NULL; pe = pe->pnext) { + mlr_dsl_ast_node_t* pbody_ast_node = pe->pvvalue; + mlr_dsl_cst_statement_t *pchild_statement = mlr_dsl_cst_alloc_statement(pcst, pbody_ast_node, + type_inferencing, context_flags); + sllv_append(pblock->pstatements, pchild_statement); + } + + mlr_dsl_cst_block_handler_t* pblock_handler = (context_flags & IN_BREAKABLE) + ? handle_statement_block_with_break_continue + : mlr_dsl_cst_handle_statement_block; + + return mlr_dsl_cst_statement_valloc_with_block( + pnode, + handle_conditional_block, + pblock, + pblock_handler, + free_conditional_block, + pstate); +} + +// ---------------------------------------------------------------- +// xxx move all frees between allocs & handles. and header-file order too. + +static void free_conditional_block(mlr_dsl_cst_statement_t* pstatement) { // conditional_block + conditional_block_state_t* pstate = pstatement->pvstate; + + pstate->pexpression_evaluator->pfree_func(pstate->pexpression_evaluator); + + free(pstate); +} + +// ---------------------------------------------------------------- +static void handle_conditional_block( + mlr_dsl_cst_statement_t* pstatement, + variables_t* pvars, + cst_outputs_t* pcst_outputs) +{ + conditional_block_state_t* pstate = pstatement->pvstate; + + local_stack_frame_t* pframe = local_stack_get_top_frame(pvars->plocal_stack); + local_stack_subframe_enter(pframe, pstatement->pblock->subframe_var_count); + + rval_evaluator_t* pexpression_evaluator = pstate->pexpression_evaluator; + + mv_t val = pexpression_evaluator->pprocess_func(pexpression_evaluator->pvstate, pvars); + if (mv_is_non_null(&val)) { + mv_set_boolean_strict(&val); + if (val.u.boolv) { + pstatement->pblock_handler(pstatement->pblock, pvars, pcst_outputs); + } + } + + local_stack_subframe_exit(pframe, pstatement->pblock->subframe_var_count); +} + +// ================================================================ +typedef struct _if_head_state_t { + sllv_t* pif_chain_statements; +} if_head_state_t; + +typedef struct _if_item_state_t { + rval_evaluator_t* pexpression_evaluator; +} if_item_state_t; + +static mlr_dsl_cst_statement_handler_t handle_if_head; +static mlr_dsl_cst_statement_freer_t free_if_head; +static mlr_dsl_cst_statement_freer_t free_if_item; + +static mlr_dsl_cst_statement_t* alloc_if_item( + mlr_dsl_cst_t* pcst, + mlr_dsl_ast_node_t* pitemnode, + mlr_dsl_ast_node_t* pexprnode, + mlr_dsl_ast_node_t* plistnode, + int type_inferencing, + int context_flags); + +// ---------------------------------------------------------------- +// Example parser-input: +// +// if (NR == 9) { +// $x = 10; +// $x = 11 +// } elif (NR == 12) { +// $x = 13; +// $x = 14 +// } else { +// $x = 15; +// $x = 16 +// }; +// +// Corresponding parser-output AST: +// if_head (if_head): +// if (if_item): +// == (operator): +// NR (context_variable). +// 9 (numeric_literal). +// list (statement_list): +// = (srec_assignment): +// x (field_name). +// 10 (numeric_literal). +// = (srec_assignment): +// x (field_name). +// 11 (numeric_literal). +// elif (if_item): +// == (operator): +// NR (context_variable). +// 12 (numeric_literal). +// list (statement_list): +// = (srec_assignment): +// x (field_name). +// 13 (numeric_literal). +// = (srec_assignment): +// x (field_name). +// 14 (numeric_literal). +// else (if_item): +// list (statement_list): +// = (srec_assignment): +// x (field_name). +// 15 (numeric_literal). +// = (srec_assignment): +// x (field_name). +// 16 (numeric_literal). + +mlr_dsl_cst_statement_t* alloc_if_head(mlr_dsl_cst_t* pcst, mlr_dsl_ast_node_t* pnode, + int type_inferencing, int context_flags) +{ + if_head_state_t* pstate = mlr_malloc_or_die(sizeof(if_head_state_t)); + + pstate->pif_chain_statements = sllv_alloc(); + + for (sllve_t* pe = pnode->pchildren->phead; pe != NULL; pe = pe->pnext) { + // For if and elif: + // * Left subnode is the AST for the boolean expression. + // * Right subnode is a list of statements to be executed if the left evaluates to true. + // For else: + // * Sole subnode is a list of statements to be executed. + mlr_dsl_ast_node_t* pitemnode = pe->pvvalue; + mlr_dsl_ast_node_t* pexprnode = NULL; + mlr_dsl_ast_node_t* plistnode = NULL; + if (pitemnode->pchildren->length == 2) { + pexprnode = pitemnode->pchildren->phead->pvvalue; + plistnode = pitemnode->pchildren->phead->pnext->pvvalue; + } else { + pexprnode = NULL; + plistnode = pitemnode->pchildren->phead->pvvalue; + } + + sllv_append(pstate->pif_chain_statements, + alloc_if_item(pcst, pitemnode, pexprnode, plistnode, type_inferencing, context_flags) + ); + } + + mlr_dsl_cst_block_handler_t* pblock_handler = (context_flags & IN_BREAKABLE) + ? handle_statement_block_with_break_continue + : mlr_dsl_cst_handle_statement_block; + + return mlr_dsl_cst_statement_valloc_with_block( + pnode, + handle_if_head, + NULL, + pblock_handler, + free_if_head, + pstate); +} + +static mlr_dsl_cst_statement_t* alloc_if_item(mlr_dsl_cst_t* pcst, + mlr_dsl_ast_node_t* pitemnode, mlr_dsl_ast_node_t* pexprnode, mlr_dsl_ast_node_t* plistnode, + int type_inferencing, int context_flags) +{ + if_item_state_t* pstate = mlr_malloc_or_die(sizeof(if_item_state_t)); + + MLR_INTERNAL_CODING_ERROR_IF(plistnode->subframe_var_count == MD_UNUSED_INDEX); + cst_statement_block_t* pblock = cst_statement_block_alloc(plistnode->subframe_var_count); + + for (sllve_t* pe = plistnode->pchildren->phead; pe != NULL; pe = pe->pnext) { + mlr_dsl_ast_node_t* pbody_ast_node = pe->pvvalue; + mlr_dsl_cst_statement_t *pchild_statement = mlr_dsl_cst_alloc_statement(pcst, pbody_ast_node, + type_inferencing, context_flags); + sllv_append(pblock->pstatements, pchild_statement); + } + + pstate->pexpression_evaluator = pexprnode != NULL + ? rval_evaluator_alloc_from_ast(pexprnode, pcst->pfmgr, + type_inferencing, context_flags) // if-statement or elif-statement + : rval_evaluator_alloc_from_boolean(TRUE); // else-statement + + return mlr_dsl_cst_statement_valloc_with_block( + pitemnode, + NULL, // handled by the containing if-head evaluator + pblock, + NULL, // handled by the containing if-head evaluator + free_if_item, + pstate); +} + +// ---------------------------------------------------------------- +// xxx move all frees between allocs & handles. and header-file order too. + +static void free_if_head(mlr_dsl_cst_statement_t* pstatement) { + if_head_state_t* pstate = pstatement->pvstate; + + if (pstate->pif_chain_statements != NULL) { + for (sllve_t* pe = pstate->pif_chain_statements->phead; pe != NULL; pe = pe->pnext) + mlr_dsl_cst_statement_free(pe->pvvalue); + sllv_free(pstate->pif_chain_statements); + } + + free(pstate); +} + +static void free_if_item(mlr_dsl_cst_statement_t* pstatement) { + if_item_state_t* pstate = pstatement->pvstate; + + pstate->pexpression_evaluator->pfree_func(pstate->pexpression_evaluator); + + free(pstate); +} + +// ---------------------------------------------------------------- +static void handle_if_head( + mlr_dsl_cst_statement_t* pstatement, + variables_t* pvars, + cst_outputs_t* pcst_outputs) +{ + if_head_state_t* pstate = pstatement->pvstate; + + for (sllve_t* pe = pstate->pif_chain_statements->phead; pe != NULL; pe = pe->pnext) { + mlr_dsl_cst_statement_t* pitem_statement = pe->pvvalue; + if_item_state_t* pitem_state = pitem_statement->pvstate; + rval_evaluator_t* pexpression_evaluator = pitem_state->pexpression_evaluator; + + mv_t val = pexpression_evaluator->pprocess_func(pexpression_evaluator->pvstate, pvars); + if (mv_is_non_null(&val)) { + mv_set_boolean_strict(&val); + if (val.u.boolv) { + local_stack_frame_t* pframe = local_stack_get_top_frame(pvars->plocal_stack); + local_stack_subframe_enter(pframe, pitem_statement->pblock->subframe_var_count); + + pstatement->pblock_handler(pitem_statement->pblock, pvars, pcst_outputs); + + local_stack_subframe_exit(pframe, pitem_statement->pblock->subframe_var_count); + break; + } + } + } +} + +// ================================================================ +typedef struct _while_state_t { + rval_evaluator_t* pexpression_evaluator; +} while_state_t; + +static mlr_dsl_cst_statement_handler_t handle_while; +static mlr_dsl_cst_statement_freer_t free_while; + +// ---------------------------------------------------------------- +mlr_dsl_cst_statement_t* alloc_while(mlr_dsl_cst_t* pcst, mlr_dsl_ast_node_t* pnode, + int type_inferencing, int context_flags) +{ + while_state_t* pstate = mlr_malloc_or_die(sizeof(while_state_t)); + + pstate->pexpression_evaluator = NULL; + + // Left child node is the AST for the boolean expression. + // Right child node is the list of statements in the body. + 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(pright->subframe_var_count == MD_UNUSED_INDEX); + cst_statement_block_t* pblock = cst_statement_block_alloc(pright->subframe_var_count); + + for (sllve_t* pe = pright->pchildren->phead; pe != NULL; pe = pe->pnext) { + mlr_dsl_ast_node_t* pbody_ast_node = pe->pvvalue; + mlr_dsl_cst_statement_t *pchild_statement = mlr_dsl_cst_alloc_statement(pcst, pbody_ast_node, + type_inferencing, context_flags); + sllv_append(pblock->pstatements, pchild_statement); + } + + pstate->pexpression_evaluator = rval_evaluator_alloc_from_ast( + pleft, pcst->pfmgr, type_inferencing, context_flags); + + return mlr_dsl_cst_statement_valloc_with_block( + pnode, + handle_while, + pblock, + handle_statement_block_with_break_continue, + free_while, + pstate); +} + +// ---------------------------------------------------------------- +// xxx move all frees between allocs & handles. and header-file order too. + +static void free_while(mlr_dsl_cst_statement_t* pstatement) { // xxx + while_state_t* pstate = pstatement->pvstate; + + pstate->pexpression_evaluator->pfree_func(pstate->pexpression_evaluator); + + free(pstate); +} + +// ---------------------------------------------------------------- +static void handle_while( + mlr_dsl_cst_statement_t* pstatement, + variables_t* pvars, + cst_outputs_t* pcst_outputs) +{ + while_state_t* pstate = pstatement->pvstate; + + local_stack_frame_t* pframe = local_stack_get_top_frame(pvars->plocal_stack); + local_stack_subframe_enter(pframe, pstatement->pblock->subframe_var_count); + loop_stack_push(pvars->ploop_stack); + + rval_evaluator_t* pexpression_evaluator = pstate->pexpression_evaluator; + + while (TRUE) { + mv_t val = pexpression_evaluator->pprocess_func(pexpression_evaluator->pvstate, pvars); + if (mv_is_non_null(&val)) { + mv_set_boolean_strict(&val); + if (val.u.boolv) { + pstatement->pblock_handler(pstatement->pblock, pvars, pcst_outputs); + if (loop_stack_get(pvars->ploop_stack) & LOOP_BROKEN) { + loop_stack_clear(pvars->ploop_stack, LOOP_BROKEN); + break; + } else if (loop_stack_get(pvars->ploop_stack) & LOOP_CONTINUED) { + loop_stack_clear(pvars->ploop_stack, LOOP_CONTINUED); + } + } else { + break; + } + } else { + break; + } + } + + loop_stack_pop(pvars->ploop_stack); + local_stack_subframe_exit(pframe, pstatement->pblock->subframe_var_count); +} + + +// ================================================================ +typedef struct _do_while_state_t { + rval_evaluator_t* pexpression_evaluator; +} do_while_state_t; + +static mlr_dsl_cst_statement_handler_t handle_do_while; +static mlr_dsl_cst_statement_freer_t free_do_while; + +// ---------------------------------------------------------------- +mlr_dsl_cst_statement_t* alloc_do_while(mlr_dsl_cst_t* pcst, mlr_dsl_ast_node_t* pnode, + int type_inferencing, int context_flags) +{ + do_while_state_t* pstate = mlr_malloc_or_die(sizeof(do_while_state_t)); + + pstate->pexpression_evaluator = NULL; + + // Left child node is the list of statements in the body. + // Right child node is the AST for the boolean expression. + 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->subframe_var_count == MD_UNUSED_INDEX); + cst_statement_block_t* pblock = cst_statement_block_alloc(pright->subframe_var_count); + + for (sllve_t* pe = pleft->pchildren->phead; pe != NULL; pe = pe->pnext) { + mlr_dsl_ast_node_t* pbody_ast_node = pe->pvvalue; + mlr_dsl_cst_statement_t *pchild_statement = mlr_dsl_cst_alloc_statement(pcst, pbody_ast_node, + type_inferencing, context_flags); + sllv_append(pblock->pstatements, pchild_statement); + } + + pstate->pexpression_evaluator = rval_evaluator_alloc_from_ast( + pright, pcst->pfmgr, type_inferencing, context_flags); + + return mlr_dsl_cst_statement_valloc_with_block( + pnode, + handle_do_while, + pblock, + handle_statement_block_with_break_continue, + free_do_while, + pstate); +} + +// ---------------------------------------------------------------- +// xxx move all frees between allocs & handles. and header-file order too. + +static void free_do_while(mlr_dsl_cst_statement_t* pstatement) { // xxx + do_while_state_t* pstate = pstatement->pvstate; + + pstate->pexpression_evaluator->pfree_func(pstate->pexpression_evaluator); + + free(pstate); +} + +// ---------------------------------------------------------------- +static void handle_do_while( + mlr_dsl_cst_statement_t* pstatement, + variables_t* pvars, + cst_outputs_t* pcst_outputs) +{ + do_while_state_t* pstate = pstatement->pvstate; + + local_stack_frame_t* pframe = local_stack_get_top_frame(pvars->plocal_stack); + local_stack_subframe_enter(pframe, pstatement->pblock->subframe_var_count); + loop_stack_push(pvars->ploop_stack); + + rval_evaluator_t* pexpression_evaluator = pstate->pexpression_evaluator; + + while (TRUE) { + pstatement->pblock_handler(pstatement->pblock, pvars, pcst_outputs); + if (loop_stack_get(pvars->ploop_stack) & LOOP_BROKEN) { + loop_stack_clear(pvars->ploop_stack, LOOP_BROKEN); + break; + } else if (loop_stack_get(pvars->ploop_stack) & LOOP_CONTINUED) { + loop_stack_clear(pvars->ploop_stack, LOOP_CONTINUED); + // don't skip the boolean test + } + + mv_t val = pexpression_evaluator->pprocess_func(pexpression_evaluator->pvstate, pvars); + if (mv_is_non_null(&val)) { + mv_set_boolean_strict(&val); + if (!val.u.boolv) { + break; + } + } else { + break; + } + } + + loop_stack_pop(pvars->ploop_stack); + local_stack_subframe_exit(pframe, pstatement->pblock->subframe_var_count); +} diff --git a/c/mapping/mlr_dsl_cst_statements.c b/c/mapping/mlr_dsl_cst_statements.c index 5e9ee99f5..07c5903ea 100644 --- a/c/mapping/mlr_dsl_cst_statements.c +++ b/c/mapping/mlr_dsl_cst_statements.c @@ -29,7 +29,6 @@ static mlr_dsl_cst_statement_allocator_t alloc_return_value_from_full_oosvar; static mlr_dsl_cst_statement_allocator_t alloc_return_value_from_full_srec; // xxx needs grammar support static mlr_dsl_cst_statement_allocator_t alloc_return_value_from_function_callsite; static mlr_dsl_cst_statement_allocator_t alloc_return_value_non_map_valued; -static mlr_dsl_cst_statement_allocator_t alloc_return_void; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - static mlr_dsl_cst_statement_allocator_t alloc_srec_assignment; @@ -52,12 +51,6 @@ static mlr_dsl_cst_statement_allocator_t alloc_full_srec_from_oosvar_assignment; static mlr_dsl_cst_statement_allocator_t alloc_env_assignment; static mlr_dsl_cst_statement_allocator_t alloc_unset; -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -static mlr_dsl_cst_statement_allocator_t alloc_conditional_block; -static mlr_dsl_cst_statement_allocator_t alloc_if_head; -static mlr_dsl_cst_statement_allocator_t alloc_while; -static mlr_dsl_cst_statement_allocator_t alloc_do_while; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - static mlr_dsl_cst_statement_allocator_t alloc_for_oosvar; static mlr_dsl_cst_statement_allocator_t alloc_for_oosvar_key_only; @@ -80,13 +73,6 @@ static mlr_dsl_cst_statement_t* alloc_final_filter( int type_inferencing, int context_flags); -static mlr_dsl_cst_statement_t* alloc_if_item( - mlr_dsl_cst_t* pcst, - mlr_dsl_ast_node_t* pexprnode, - mlr_dsl_ast_node_t* plistnode, - int type_inferencing, - int context_flags); - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - static mlr_dsl_cst_statement_handler_t handle_return_void; static mlr_dsl_cst_statement_handler_t handle_return_value_from_local_non_map_variable; @@ -114,16 +100,13 @@ static mlr_dsl_cst_statement_handler_t handle_unset_all; static mlr_dsl_cst_statement_handler_t handle_filter; static mlr_dsl_cst_statement_handler_t handle_final_filter; -static mlr_dsl_cst_statement_handler_t handle_conditional_block; -static mlr_dsl_cst_statement_handler_t handle_while; -static mlr_dsl_cst_statement_handler_t handle_do_while; + static mlr_dsl_cst_statement_handler_t handle_for_oosvar; static mlr_dsl_cst_statement_handler_t handle_for_oosvar_key_only; static mlr_dsl_cst_statement_handler_t handle_for_local_map; static mlr_dsl_cst_statement_handler_t handle_for_local_map_key_only; static mlr_dsl_cst_statement_handler_t handle_break; static mlr_dsl_cst_statement_handler_t handle_continue; -static mlr_dsl_cst_statement_handler_t handle_if_head; static mlr_dsl_cst_statement_handler_t handle_bare_boolean; static void handle_for_oosvar_aux( @@ -617,7 +600,6 @@ static mlr_dsl_cst_statement_t* alloc_blank(mlr_dsl_ast_node_t* past_node) { pstatement->poosvar_rhs_keylist_evaluators = NULL; pstatement->pvarargs = NULL; pstatement->pblock = NULL; - pstatement->pif_chain_statements = NULL; pstatement->for_map_k_variable_names = NULL; pstatement->for_map_k_frame_relative_indices = NULL; @@ -1100,59 +1082,6 @@ static mlr_dsl_cst_statement_t* alloc_unset(mlr_dsl_cst_t* pcst, mlr_dsl_ast_nod return pstatement; } -// ---------------------------------------------------------------- -static mlr_dsl_cst_statement_t* alloc_while(mlr_dsl_cst_t* pcst, mlr_dsl_ast_node_t* pnode, - int type_inferencing, int context_flags) -{ - mlr_dsl_cst_statement_t* pstatement = alloc_blank(pnode); - - // Left child node is the AST for the boolean expression. - // Right child node is the list of statements in the body. - 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(pright->subframe_var_count == MD_UNUSED_INDEX); - pstatement->pblock = cst_statement_block_alloc(pright->subframe_var_count); - - for (sllve_t* pe = pright->pchildren->phead; pe != NULL; pe = pe->pnext) { - mlr_dsl_ast_node_t* pbody_ast_node = pe->pvvalue; - mlr_dsl_cst_statement_t *pchild_statement = mlr_dsl_cst_alloc_statement(pcst, pbody_ast_node, - type_inferencing, context_flags); - sllv_append(pstatement->pblock->pstatements, pchild_statement); - } - - pstatement->pstatement_handler = handle_while; - pstatement->pblock_handler = handle_statement_block_with_break_continue; - pstatement->prhs_evaluator = rval_evaluator_alloc_from_ast(pleft, pcst->pfmgr, type_inferencing, context_flags); - return pstatement; -} - -static mlr_dsl_cst_statement_t* alloc_do_while(mlr_dsl_cst_t* pcst, mlr_dsl_ast_node_t* pnode, - int type_inferencing, int context_flags) -{ - mlr_dsl_cst_statement_t* pstatement = alloc_blank(pnode); - - // Left child node is the list of statements in the body. - // Right child node is the AST for the boolean expression. - 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->subframe_var_count == MD_UNUSED_INDEX); - pstatement->pblock = cst_statement_block_alloc(pleft->subframe_var_count); - - for (sllve_t* pe = pleft->pchildren->phead; pe != NULL; pe = pe->pnext) { - mlr_dsl_ast_node_t* pbody_ast_node = pe->pvvalue; - mlr_dsl_cst_statement_t *pchild_statement = mlr_dsl_cst_alloc_statement(pcst, pbody_ast_node, - type_inferencing, context_flags); - sllv_append(pstatement->pblock->pstatements, pchild_statement); - } - - pstatement->pstatement_handler = handle_do_while; - pstatement->pblock_handler = handle_statement_block_with_break_continue; - pstatement->prhs_evaluator = rval_evaluator_alloc_from_ast(pright, pcst->pfmgr, type_inferencing, context_flags); - return pstatement; -} - // ---------------------------------------------------------------- // $ mlr -n put -v 'for((k1,k2,k3),v in @a["4"][$5]) { $6 = 7; $8 = 9}' // AST ROOT: @@ -1379,141 +1308,6 @@ static mlr_dsl_cst_statement_t* alloc_continue(mlr_dsl_cst_t* pcst, mlr_dsl_ast_ return pstatement; } -// ---------------------------------------------------------------- -static mlr_dsl_cst_statement_t* alloc_conditional_block(mlr_dsl_cst_t* pcst, mlr_dsl_ast_node_t* pnode, - int type_inferencing, int context_flags) -{ - mlr_dsl_cst_statement_t* pstatement = alloc_blank(pnode); - - // Left node is the AST for the boolean expression. - // Right node is a list of statements to be executed if the left evaluates to true. - 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(pright->subframe_var_count == MD_UNUSED_INDEX); - pstatement->pblock = cst_statement_block_alloc(pright->subframe_var_count); - - for (sllve_t* pe = pright->pchildren->phead; pe != NULL; pe = pe->pnext) { - mlr_dsl_ast_node_t* pbody_ast_node = pe->pvvalue; - mlr_dsl_cst_statement_t *pchild_statement = mlr_dsl_cst_alloc_statement(pcst, pbody_ast_node, - type_inferencing, context_flags); - sllv_append(pstatement->pblock->pstatements, pchild_statement); - } - - pstatement->pstatement_handler = handle_conditional_block; - pstatement->pblock_handler = (context_flags & IN_BREAKABLE) - ? handle_statement_block_with_break_continue - : mlr_dsl_cst_handle_statement_block; - pstatement->prhs_evaluator = rval_evaluator_alloc_from_ast(pleft, pcst->pfmgr, type_inferencing, context_flags); - return pstatement; -} - -// ---------------------------------------------------------------- -// Example parser-input: -// -// if (NR == 9) { -// $x = 10; -// $x = 11 -// } elif (NR == 12) { -// $x = 13; -// $x = 14 -// } else { -// $x = 15; -// $x = 16 -// }; -// -// Corresponding parser-output AST: -// if_head (if_head): -// if (if_item): -// == (operator): -// NR (context_variable). -// 9 (numeric_literal). -// list (statement_list): -// = (srec_assignment): -// x (field_name). -// 10 (numeric_literal). -// = (srec_assignment): -// x (field_name). -// 11 (numeric_literal). -// elif (if_item): -// == (operator): -// NR (context_variable). -// 12 (numeric_literal). -// list (statement_list): -// = (srec_assignment): -// x (field_name). -// 13 (numeric_literal). -// = (srec_assignment): -// x (field_name). -// 14 (numeric_literal). -// else (if_item): -// list (statement_list): -// = (srec_assignment): -// x (field_name). -// 15 (numeric_literal). -// = (srec_assignment): -// x (field_name). -// 16 (numeric_literal). - -static mlr_dsl_cst_statement_t* alloc_if_head(mlr_dsl_cst_t* pcst, mlr_dsl_ast_node_t* pnode, - int type_inferencing, int context_flags) -{ - mlr_dsl_cst_statement_t* pstatement = alloc_blank(pnode); - - sllv_t* pif_chain_statements = sllv_alloc(); - for (sllve_t* pe = pnode->pchildren->phead; pe != NULL; pe = pe->pnext) { - // For if and elif: - // * Left subnode is the AST for the boolean expression. - // * Right subnode is a list of statements to be executed if the left evaluates to true. - // For else: - // * Sole subnode is a list of statements to be executed. - mlr_dsl_ast_node_t* pitemnode = pe->pvvalue; - mlr_dsl_ast_node_t* pexprnode = NULL; - mlr_dsl_ast_node_t* plistnode = NULL; - if (pitemnode->pchildren->length == 2) { - pexprnode = pitemnode->pchildren->phead->pvvalue; - plistnode = pitemnode->pchildren->phead->pnext->pvvalue; - } else { - pexprnode = NULL; - plistnode = pitemnode->pchildren->phead->pvvalue; - } - - sllv_append(pif_chain_statements, alloc_if_item(pcst, pexprnode, plistnode, - type_inferencing, context_flags)); - } - - pstatement->pstatement_handler = handle_if_head; - pstatement->pblock_handler = (context_flags & IN_BREAKABLE) - ? handle_statement_block_with_break_continue - : mlr_dsl_cst_handle_statement_block; - pstatement->pif_chain_statements = pif_chain_statements; - return pstatement; -} - -static mlr_dsl_cst_statement_t* alloc_if_item(mlr_dsl_cst_t* pcst, mlr_dsl_ast_node_t* pexprnode, - mlr_dsl_ast_node_t* plistnode, int type_inferencing, int context_flags) -{ - mlr_dsl_cst_statement_t* pstatement = alloc_blank(pexprnode); - - MLR_INTERNAL_CODING_ERROR_IF(plistnode->subframe_var_count == MD_UNUSED_INDEX); - pstatement->pblock = cst_statement_block_alloc(plistnode->subframe_var_count); - - for (sllve_t* pe = plistnode->pchildren->phead; pe != NULL; pe = pe->pnext) { - mlr_dsl_ast_node_t* pbody_ast_node = pe->pvvalue; - mlr_dsl_cst_statement_t *pchild_statement = mlr_dsl_cst_alloc_statement(pcst, pbody_ast_node, - type_inferencing, context_flags); - sllv_append(pstatement->pblock->pstatements, pchild_statement); - } - - pstatement->pstatement_handler = NULL; // handled by the containing if-head evaluator - pstatement->prhs_evaluator = pexprnode != NULL - ? rval_evaluator_alloc_from_ast(pexprnode, pcst->pfmgr, - type_inferencing, context_flags) // if-statement or elif-statement - : rval_evaluator_alloc_from_boolean(TRUE); // else-statement - return pstatement; -} - // ---------------------------------------------------------------- static mlr_dsl_cst_statement_t* alloc_filter(mlr_dsl_cst_t* pcst, mlr_dsl_ast_node_t* pnode, int type_inferencing, int context_flags) @@ -1670,12 +1464,6 @@ void mlr_dsl_cst_statement_free(mlr_dsl_cst_statement_t* pstatement) { cst_statement_block_free(pstatement->pblock); - if (pstatement->pif_chain_statements != NULL) { - for (sllve_t* pe = pstatement->pif_chain_statements->phead; pe != NULL; pe = pe->pnext) - mlr_dsl_cst_statement_free(pe->pvvalue); - sllv_free(pstatement->pif_chain_statements); - } - if (pstatement->for_map_k_variable_names != NULL) { for (int i = 0; i < pstatement->for_map_k_count; i++) free(pstatement->for_map_k_variable_names[i]); @@ -2336,127 +2124,6 @@ static void handle_final_filter( } } -// ---------------------------------------------------------------- -static void handle_conditional_block( - mlr_dsl_cst_statement_t* pstatement, - variables_t* pvars, - cst_outputs_t* pcst_outputs) -{ - local_stack_frame_t* pframe = local_stack_get_top_frame(pvars->plocal_stack); - local_stack_subframe_enter(pframe, pstatement->pblock->subframe_var_count); - - rval_evaluator_t* prhs_evaluator = pstatement->prhs_evaluator; - - mv_t val = prhs_evaluator->pprocess_func(prhs_evaluator->pvstate, pvars); - if (mv_is_non_null(&val)) { - mv_set_boolean_strict(&val); - if (val.u.boolv) { - pstatement->pblock_handler(pstatement->pblock, pvars, pcst_outputs); - } - } - - local_stack_subframe_exit(pframe, pstatement->pblock->subframe_var_count); -} - -// ---------------------------------------------------------------- -static void handle_if_head( - mlr_dsl_cst_statement_t* pstatement, - variables_t* pvars, - cst_outputs_t* pcst_outputs) -{ - for (sllve_t* pe = pstatement->pif_chain_statements->phead; pe != NULL; pe = pe->pnext) { - mlr_dsl_cst_statement_t* pitemnode = pe->pvvalue; - rval_evaluator_t* prhs_evaluator = pitemnode->prhs_evaluator; - - mv_t val = prhs_evaluator->pprocess_func(prhs_evaluator->pvstate, pvars); - if (mv_is_non_null(&val)) { - mv_set_boolean_strict(&val); - if (val.u.boolv) { - local_stack_frame_t* pframe = local_stack_get_top_frame(pvars->plocal_stack); - local_stack_subframe_enter(pframe, pitemnode->pblock->subframe_var_count); - - pstatement->pblock_handler(pitemnode->pblock, pvars, pcst_outputs); - - local_stack_subframe_exit(pframe, pitemnode->pblock->subframe_var_count); - break; - } - } - } -} - -// ---------------------------------------------------------------- -static void handle_while( - mlr_dsl_cst_statement_t* pstatement, - variables_t* pvars, - cst_outputs_t* pcst_outputs) -{ - local_stack_frame_t* pframe = local_stack_get_top_frame(pvars->plocal_stack); - local_stack_subframe_enter(pframe, pstatement->pblock->subframe_var_count); - loop_stack_push(pvars->ploop_stack); - - rval_evaluator_t* prhs_evaluator = pstatement->prhs_evaluator; - - while (TRUE) { - mv_t val = prhs_evaluator->pprocess_func(prhs_evaluator->pvstate, pvars); - if (mv_is_non_null(&val)) { - mv_set_boolean_strict(&val); - if (val.u.boolv) { - pstatement->pblock_handler(pstatement->pblock, pvars, pcst_outputs); - if (loop_stack_get(pvars->ploop_stack) & LOOP_BROKEN) { - loop_stack_clear(pvars->ploop_stack, LOOP_BROKEN); - break; - } else if (loop_stack_get(pvars->ploop_stack) & LOOP_CONTINUED) { - loop_stack_clear(pvars->ploop_stack, LOOP_CONTINUED); - } - } else { - break; - } - } else { - break; - } - } - - loop_stack_pop(pvars->ploop_stack); - local_stack_subframe_exit(pframe, pstatement->pblock->subframe_var_count); -} - -// ---------------------------------------------------------------- -static void handle_do_while( - mlr_dsl_cst_statement_t* pstatement, - variables_t* pvars, - cst_outputs_t* pcst_outputs) -{ - local_stack_frame_t* pframe = local_stack_get_top_frame(pvars->plocal_stack); - local_stack_subframe_enter(pframe, pstatement->pblock->subframe_var_count); - loop_stack_push(pvars->ploop_stack); - - rval_evaluator_t* prhs_evaluator = pstatement->prhs_evaluator; - - while (TRUE) { - pstatement->pblock_handler(pstatement->pblock, pvars, pcst_outputs); - if (loop_stack_get(pvars->ploop_stack) & LOOP_BROKEN) { - loop_stack_clear(pvars->ploop_stack, LOOP_BROKEN); - break; - } else if (loop_stack_get(pvars->ploop_stack) & LOOP_CONTINUED) { - loop_stack_clear(pvars->ploop_stack, LOOP_CONTINUED); - // don't skip the boolean test - } - - mv_t val = prhs_evaluator->pprocess_func(prhs_evaluator->pvstate, pvars); - if (mv_is_non_null(&val)) { - mv_set_boolean_strict(&val); - if (!val.u.boolv) { - break; - } - } else { - break; - } - } - - loop_stack_pop(pvars->ploop_stack); - local_stack_subframe_exit(pframe, pstatement->pblock->subframe_var_count); -} - // ---------------------------------------------------------------- static void handle_for_oosvar( mlr_dsl_cst_statement_t* pstatement,