"Fossies" - the Fresh Open Source Software Archive

Member "mlr-5.6.2/c/dsl/mlr_dsl_cst_triple_for_statements.c" (25 Aug 2019, 6716 Bytes) of package /linux/misc/mlr-5.6.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "mlr_dsl_cst_triple_for_statements.c" see the Fossies "Dox" file reference documentation.

    1 #include <stdlib.h>
    2 #include "lib/mlr_globals.h"
    3 #include "lib/mlrutil.h"
    4 #include "mlr_dsl_cst.h"
    5 #include "context_flags.h"
    6 
    7 static mlr_dsl_cst_statement_handler_t handle_triple_for;
    8 static mlr_dsl_cst_statement_freer_t free_triple_for;
    9 
   10 typedef struct _triple_for_state_t {
   11     sllv_t* ptriple_for_start_statements;
   12     sllv_t* ptriple_for_pre_continuation_statements;
   13     rval_evaluator_t* ptriple_for_continuation_evaluator;
   14     sllv_t* ptriple_for_update_statements;
   15 } triple_for_state_t;
   16 
   17 // ----------------------------------------------------------------
   18 mlr_dsl_cst_statement_t* alloc_triple_for(mlr_dsl_cst_t* pcst, mlr_dsl_ast_node_t* pnode,
   19     int type_inferencing, int context_flags)
   20 {
   21     mlr_dsl_ast_node_t* pstart_statements_node        = pnode->pchildren->phead->pvvalue;
   22     mlr_dsl_ast_node_t* pcontinuation_statements_node = pnode->pchildren->phead->pnext->pvvalue;
   23     mlr_dsl_ast_node_t* pupdate_statements_node       = pnode->pchildren->phead->pnext->pnext->pvvalue;
   24     mlr_dsl_ast_node_t* pbody_statements_node         = pnode->pchildren->phead->pnext->pnext->pnext->pvvalue;
   25 
   26     triple_for_state_t* pstate = mlr_malloc_or_die(sizeof(triple_for_state_t));
   27 
   28     pstate->ptriple_for_start_statements = sllv_alloc();
   29     for (sllve_t* pe = pstart_statements_node->pchildren->phead; pe != NULL; pe = pe->pnext) {
   30         mlr_dsl_ast_node_t* pbody_ast_node = pe->pvvalue;
   31         sllv_append(pstate->ptriple_for_start_statements,
   32             mlr_dsl_cst_alloc_statement(
   33                 pcst, pbody_ast_node, type_inferencing, context_flags & ~IN_BREAKABLE));
   34     }
   35 
   36     // Continuation statements are split into the final boolean, and the statements before (if any).
   37     pstate->ptriple_for_pre_continuation_statements = sllv_alloc();
   38     // Empty continuation for triple-for is an implicit TRUE.
   39     if (pcontinuation_statements_node->pchildren->length == 0) {
   40         pstate->ptriple_for_continuation_evaluator = rval_evaluator_alloc_from_boolean(TRUE);
   41     } else {
   42         for (
   43             sllve_t* pe = pcontinuation_statements_node->pchildren->phead;
   44             pe != NULL && pe->pnext != NULL;
   45             pe = pe->pnext
   46         )
   47         {
   48             mlr_dsl_ast_node_t* pbody_ast_node = pe->pvvalue;
   49             sllv_append(pstate->ptriple_for_pre_continuation_statements,
   50                 mlr_dsl_cst_alloc_statement(pcst, pbody_ast_node,
   51                 type_inferencing, context_flags & ~IN_BREAKABLE));
   52         }
   53         mlr_dsl_ast_node_t* pfinal_continuation_statement_node =
   54             pcontinuation_statements_node->pchildren->ptail->pvvalue;
   55         if (mlr_dsl_ast_node_cannot_be_bare_boolean(pfinal_continuation_statement_node)) {
   56             fprintf(stderr,
   57                 "%s: the final triple-for continutation statement must be a bare boolean.\n",
   58                 MLR_GLOBALS.bargv0);
   59             exit(1);
   60         }
   61         pstate->ptriple_for_continuation_evaluator = rval_evaluator_alloc_from_ast(
   62             pfinal_continuation_statement_node, pcst->pfmgr,
   63             type_inferencing, (context_flags & ~IN_BREAKABLE) | IN_TRIPLE_FOR_CONTINUE);
   64     }
   65 
   66     pstate->ptriple_for_update_statements = sllv_alloc();
   67     for (sllve_t* pe = pupdate_statements_node->pchildren->phead; pe != NULL; pe = pe->pnext) {
   68         mlr_dsl_ast_node_t* pbody_ast_node = pe->pvvalue;
   69         sllv_append(pstate->ptriple_for_update_statements, mlr_dsl_cst_alloc_statement(pcst, pbody_ast_node,
   70             type_inferencing, context_flags & ~IN_BREAKABLE));
   71     }
   72 
   73     MLR_INTERNAL_CODING_ERROR_IF(pnode->subframe_var_count == MD_UNUSED_INDEX);
   74     cst_statement_block_t* pblock = cst_statement_block_alloc(pnode->subframe_var_count);
   75 
   76     for (sllve_t* pe = pbody_statements_node->pchildren->phead; pe != NULL; pe = pe->pnext) {
   77         mlr_dsl_ast_node_t* pbody_ast_node = pe->pvvalue;
   78         sllv_append(pblock->pstatements, mlr_dsl_cst_alloc_statement(pcst, pbody_ast_node,
   79             type_inferencing, context_flags));
   80     }
   81 
   82     return mlr_dsl_cst_statement_valloc_with_block(
   83         pnode,
   84         handle_triple_for,
   85         pblock,
   86         mlr_dsl_cst_handle_statement_block_with_break_continue,
   87         free_triple_for,
   88         pstate);
   89 }
   90 
   91 static void free_triple_for(mlr_dsl_cst_statement_t* pstatement, context_t* pctx) {
   92 
   93     triple_for_state_t* pstate = pstatement->pvstate;
   94 
   95     if (pstate->ptriple_for_start_statements != NULL) {
   96         for (sllve_t* pe = pstate->ptriple_for_start_statements->phead; pe != NULL; pe = pe->pnext) {
   97             mlr_dsl_cst_statement_t* ps = pe->pvvalue;
   98             mlr_dsl_cst_statement_free(ps, pctx);
   99         }
  100         sllv_free(pstate->ptriple_for_start_statements);
  101     }
  102 
  103     if (pstate->ptriple_for_pre_continuation_statements != NULL) {
  104         for (sllve_t* pe = pstate->ptriple_for_pre_continuation_statements->phead; pe != NULL; pe = pe->pnext) {
  105             mlr_dsl_cst_statement_t* ps = pe->pvvalue;
  106             mlr_dsl_cst_statement_free(ps, pctx);
  107         }
  108         sllv_free(pstate->ptriple_for_pre_continuation_statements);
  109     }
  110 
  111     if (pstate->ptriple_for_continuation_evaluator != NULL) {
  112         pstate->ptriple_for_continuation_evaluator->pfree_func(pstate->ptriple_for_continuation_evaluator);
  113     }
  114 
  115     if (pstate->ptriple_for_update_statements != NULL) {
  116         for (sllve_t* pe = pstate->ptriple_for_update_statements->phead; pe != NULL; pe = pe->pnext) {
  117             mlr_dsl_cst_statement_t* ps = pe->pvvalue;
  118             mlr_dsl_cst_statement_free(ps, pctx);
  119         }
  120         sllv_free(pstate->ptriple_for_update_statements);
  121     }
  122 
  123     free(pstate);
  124 }
  125 
  126 // ----------------------------------------------------------------
  127 static void handle_triple_for(
  128     mlr_dsl_cst_statement_t* pstatement,
  129     variables_t*             pvars,
  130     cst_outputs_t*           pcst_outputs)
  131 {
  132     local_stack_frame_t* pframe = local_stack_get_top_frame(pvars->plocal_stack);
  133     local_stack_subframe_enter(pframe, pstatement->pblock->subframe_var_count);
  134     loop_stack_push(pvars->ploop_stack);
  135 
  136     triple_for_state_t* pstate = pstatement->pvstate;
  137 
  138     // Start statements
  139     mlr_dsl_cst_handle_statement_list(pstate->ptriple_for_start_statements, pvars, pcst_outputs);
  140 
  141     while (TRUE) {
  142 
  143         // Continuation statements:
  144         // * all but the last one are simply executed ...
  145         mlr_dsl_cst_handle_statement_list(pstate->ptriple_for_pre_continuation_statements, pvars, pcst_outputs);
  146         // * ... and the last one is used to determine continuation:
  147         rval_evaluator_t* pev = pstate->ptriple_for_continuation_evaluator;
  148         mv_t val = pev->pprocess_func(pev->pvstate, pvars);
  149         if (mv_is_non_null(&val))
  150             mv_set_boolean_strict(&val);
  151         if (!val.u.boolv)
  152             break;
  153 
  154         // Body statements
  155         mlr_dsl_cst_handle_statement_block_with_break_continue(pstatement->pblock, pvars, pcst_outputs);
  156 
  157         if (loop_stack_get(pvars->ploop_stack) & LOOP_BROKEN) {
  158             loop_stack_clear(pvars->ploop_stack, LOOP_BROKEN);
  159             break;
  160         } else if (loop_stack_get(pvars->ploop_stack) & LOOP_CONTINUED) {
  161             loop_stack_clear(pvars->ploop_stack, LOOP_CONTINUED);
  162         }
  163 
  164         // Update statements
  165         mlr_dsl_cst_handle_statement_list(pstate->ptriple_for_update_statements, pvars, pcst_outputs);
  166     }
  167 
  168     loop_stack_pop(pvars->ploop_stack);
  169     local_stack_subframe_exit(pframe, pstatement->pblock->subframe_var_count);
  170 }