absyntax_utils/function_call_param_iterator.cc
changeset 205 96d8b6e006f0
parent 202 da1a8186f86f
child 247 560075ece524
equal deleted inserted replaced
200:fde2d08ebaee 205:96d8b6e006f0
    22  *
    22  *
    23  */
    23  */
    24 
    24 
    25 /*
    25 /*
    26  * Function call parameter iterator.
    26  * Function call parameter iterator.
    27  * It will iterate through the formal parameters of a function call
    27  * It will iterate through the non-formal parameters of a function call
    28  * (i.e. function calls using the foo(<param1>, <param2>, ...) syntax).
    28  * (i.e. function calls using the foo(<param1>, <param2>, ...) syntax).
    29  * and/or search through the non-formal parameters of a function call
    29  * and/or search through the formal parameters of a function call
    30  * (i.e. function calls using the foo(<name1> = <param1>, <name2> = <param2>, ...) syntax).
    30  * (i.e. function calls using the foo(<name1> = <param1>, <name2> = <param2>, ...) syntax).
    31  *
    31  *
    32  * Calls to function blocks and programs are also supported.
    32  * Calls to function blocks and programs are also supported.
    33  *
    33  *
    34  * Note that calls to next() will only iterate through formal parameters,
    34  * Note that calls to next_nf() will only iterate through non-formal parameters,
    35  * and calls to search()  will only serach through non-formal parameters.
    35  * calls to next_f() will only iterate through formal parameters,
       
    36  * and calls to search_f() will only serach through formal parameters.
    36  */
    37  */
    37 
    38 
    38 
    39 
    39 
    40 
    40 #include "function_call_param_iterator.hh"
    41 #include "function_call_param_iterator.hh"
    56 
    57 
    57 
    58 
    58 
    59 
    59 void *function_call_param_iterator_c::search_list(list_c *list) {
    60 void *function_call_param_iterator_c::search_list(list_c *list) {
    60   switch (current_operation) {
    61   switch (current_operation) {
    61     case iterate_op:
    62     case iterate_nf_op:
    62       for(int i = 0; i < list->n; i++) {
    63       for(int i = 0; i < list->n; i++) {
    63         void *res = list->elements[i]->accept(*this);
    64         void *res = list->elements[i]->accept(*this);
    64         if (NULL != res) {
    65         if (NULL != res) {
    65           /* It went through the handle_parameter_assignment() function,
    66           /* It went through the handle_parameter_assignment() function,
    66            * and is therefore a parameter assignment (<param> = <value>),
    67            * and is therefore a parameter assignment (<param> = <value>),
    67            * and not a simple expression (<value>).
    68            * and not a simple expression (<value>).
    68            */
    69            */
    69           /* we do nothing... */
    70           /* we do nothing... */
    70         } else {
    71         } else {
    71           param_count++;
    72           param_count++;
    72           if (param_count == next_param) {
    73           if (param_count == iterate_nf_next_param) {
    73             return list->elements[i];
    74             return list->elements[i];
    74           }
    75           }
    75         }
    76         }
    76       }
    77       }
    77       return NULL;
    78       return NULL;
    78       break;
    79       break;
    79 
    80 
    80     case search_op:
    81     case iterate_f_op:
       
    82       for(int i = 0; i < list->n; i++) {
       
    83         void *res = list->elements[i]->accept(*this);
       
    84         if (NULL != res) {
       
    85           /* It went through the handle_parameter_assignment() function,
       
    86            * and is therefore a parameter assignment (<param> = <value>),
       
    87            * and not a simple expression (<value>).
       
    88            */
       
    89           param_count++;
       
    90           if (param_count == iterate_f_next_param) {
       
    91             return res;
       
    92           }
       
    93         } else {
       
    94           /* we do nothing... */
       
    95         }
       
    96       }
       
    97       return NULL;
       
    98       break;
       
    99 
       
   100     case search_f_op:
    81       for(int i = 0; i < list->n; i++) {
   101       for(int i = 0; i < list->n; i++) {
    82         void *res = list->elements[i]->accept(*this);
   102         void *res = list->elements[i]->accept(*this);
    83         if (res != NULL)
   103         if (res != NULL)
    84           return res;
   104           return res;
    85       }
   105       }
    91 
   111 
    92 
   112 
    93 
   113 
    94 void *function_call_param_iterator_c::handle_parameter_assignment(symbol_c *variable_name, symbol_c *expression) {
   114 void *function_call_param_iterator_c::handle_parameter_assignment(symbol_c *variable_name, symbol_c *expression) {
    95   switch (current_operation) {
   115   switch (current_operation) {
    96     case iterate_op:
   116     case iterate_nf_op:
    97           /* UGLY HACK -> this will be detected in the search_list() function */
   117           /* UGLY HACK -> this will be detected in the search_list() function */
    98       return (void *)this; /* anything, as long as it is not NULL!! */
   118       return (void *)variable_name; /* anything, as long as it is not NULL!! */
    99       break;
   119       break;
   100 
   120 
   101     case search_op:
   121     case iterate_f_op:
       
   122       current_value = expression;
       
   123       return (void *)variable_name;
       
   124       break;
       
   125 
       
   126     case search_f_op:
   102       identifier_c *variable_name2 = dynamic_cast<identifier_c *>(variable_name);
   127       identifier_c *variable_name2 = dynamic_cast<identifier_c *>(variable_name);
   103       
   128 
   104       if (variable_name2 == NULL) {
       
   105         en_param_c *en_param = dynamic_cast<en_param_c *>(variable_name);
       
   106         if (en_param != NULL)
       
   107           variable_name2 = new identifier_c("EN");
       
   108       }
       
   109       
       
   110       if (variable_name2 == NULL) {
       
   111         eno_param_c *eno_param = dynamic_cast<eno_param_c *>(variable_name);
       
   112         if (eno_param != NULL)
       
   113           variable_name2 = new identifier_c("ENO");
       
   114       }
       
   115       
       
   116       if (variable_name2 == NULL) ERROR;
   129       if (variable_name2 == NULL) ERROR;
   117       
   130 
   118       if (strcasecmp(search_param_name->value, variable_name2->value) == 0)
   131       if (strcasecmp(search_param_name->value, variable_name2->value) == 0)
   119         /* FOUND! This is the same parameter!! */
   132         /* FOUND! This is the same parameter!! */
   120         return (void *)expression;
   133         return (void *)expression;
   121       return NULL;
   134       return NULL;
   122       break;
   135       break;
   127 }
   140 }
   128 
   141 
   129 
   142 
   130 /* start off at the first parameter once again... */
   143 /* start off at the first parameter once again... */
   131 void function_call_param_iterator_c::reset(void) {
   144 void function_call_param_iterator_c::reset(void) {
   132   next_param = param_count = 0;
   145   iterate_nf_next_param = 0;
       
   146   iterate_f_next_param  = 0;
       
   147   param_count = 0;
   133 }
   148 }
   134 
   149 
   135 /* initialise the iterator object.
   150 /* initialise the iterator object.
   136  * We must be given a reference to the function/program/function block call
   151  * We must be given a reference to the function/program/function block call
   137  * that will be analysed...
   152  * that will be analysed...
   148   this->f_call = f_call;
   163   this->f_call = f_call;
   149   search_param_name = NULL;
   164   search_param_name = NULL;
   150   reset();
   165   reset();
   151 }
   166 }
   152 
   167 
   153 /* Skip to the next parameter. After object creation,
   168 /* Skip to the next formal parameter. After object creation,
   154  * the object references on parameter _before_ the first, so
   169  * the object references on parameter _before_ the first, so
   155  * this function must be called once to get the object to
   170  * this function must be called once to get the object to
   156  * reference the first parameter...
   171  * reference the first parameter...
   157  *
   172  *
   158  * Returns whatever is being passed to the parameter!
   173  * Returns the paramater name to which a value is being passed!
   159  */
   174  * You can determine the value being passed by calling 
   160 symbol_c *function_call_param_iterator_c::next(void) {
   175  * function_call_param_iterator_c::search_f()
       
   176  */
       
   177 symbol_c *function_call_param_iterator_c::next_f(void) {
       
   178   current_value = NULL;
   161   param_count = 0;
   179   param_count = 0;
   162   next_param++;
   180   iterate_f_next_param++;
   163   current_operation = function_call_param_iterator_c::iterate_op;
   181   current_operation = function_call_param_iterator_c::iterate_f_op;
   164   void *res = f_call->accept(*this);
   182   void *res = f_call->accept(*this);
   165   return (symbol_c *)res;
   183   return (symbol_c *)res;
   166 }
   184 }
   167 
   185 
       
   186 
       
   187 /* Skip to the next non-formal parameter. After object creation,
       
   188  * the object references on parameter _before_ the first, so
       
   189  * this function must be called once to get the object to
       
   190  * reference the first parameter...
       
   191  *
       
   192  * Returns whatever is being passed to the parameter!
       
   193  */
       
   194 symbol_c *function_call_param_iterator_c::next_nf(void) {
       
   195   current_value = NULL;
       
   196   param_count = 0;
       
   197   iterate_nf_next_param++;
       
   198   current_operation = function_call_param_iterator_c::iterate_nf_op;
       
   199   void *res = f_call->accept(*this);
       
   200   current_value = (symbol_c *)res;
       
   201   return (symbol_c *)res;
       
   202 }
       
   203 
   168 /* Search for the value passed to the parameter named <param_name>...  */
   204 /* Search for the value passed to the parameter named <param_name>...  */
   169 symbol_c *function_call_param_iterator_c::search(symbol_c *param_name) {
   205 symbol_c *function_call_param_iterator_c::search_f(symbol_c *param_name) {
       
   206   current_value = NULL;
   170   if (NULL == param_name) ERROR;
   207   if (NULL == param_name) ERROR;
   171   search_param_name = dynamic_cast<identifier_c *>(param_name);
   208   search_param_name = dynamic_cast<identifier_c *>(param_name);
   172   if (NULL == search_param_name) ERROR;
   209   if (NULL == search_param_name) ERROR;
   173   current_operation = function_call_param_iterator_c::search_op;
   210   current_operation = function_call_param_iterator_c::search_f_op;
   174   void *res = f_call->accept(*this);
   211   void *res = f_call->accept(*this);
       
   212   current_value = (symbol_c *)res;
   175   return (symbol_c *)res;
   213   return (symbol_c *)res;
   176 }
   214 }
   177 
   215 
   178 
   216 /* Returns the value being passed to the current parameter. */
       
   217 symbol_c *function_call_param_iterator_c::get_current_value(void) {
       
   218   return current_value;
       
   219 }
   179 
   220 
   180 /********************************/
   221 /********************************/
   181 /* B 1.7 Configuration elements */
   222 /* B 1.7 Configuration elements */
   182 /********************************/
   223 /********************************/
   183 
   224 
   401 
   442 
   402   // TODO : We do not yet handle a instruction list passed as parameter !!!
   443   // TODO : We do not yet handle a instruction list passed as parameter !!!
   403   // since we do not yet support it, it is best to simply stop than to fail silently...
   444   // since we do not yet support it, it is best to simply stop than to fail silently...
   404   if (NULL != symbol->simple_instr_list) ERROR;
   445   if (NULL != symbol->simple_instr_list) ERROR;
   405 
   446 
   406   return handle_parameter_assignment(symbol->il_assign_operator, symbol->il_operand);
   447   return handle_parameter_assignment((symbol_c *)symbol->il_assign_operator->accept(*this), symbol->il_operand);
   407 }
   448 }
   408 
   449 
   409 /*  il_assign_out_operator variable */
   450 /*  il_assign_out_operator variable */
   410 // SYM_REF2(il_param_out_assignment_c, il_assign_out_operator, variable);
   451 // SYM_REF2(il_param_out_assignment_c, il_assign_out_operator, variable);
   411 void *function_call_param_iterator_c::visit(il_param_out_assignment_c *symbol) {
   452 void *function_call_param_iterator_c::visit(il_param_out_assignment_c *symbol) {
   415 
   456 
   416 
   457 
   417 /*******************/
   458 /*******************/
   418 /* B 2.2 Operators */
   459 /* B 2.2 Operators */
   419 /*******************/
   460 /*******************/
       
   461 /*  any_identifier ASSIGN */
       
   462 // SYM_REF1(il_assign_operator_c, variable_name)
       
   463 void *function_call_param_iterator_c::visit(il_assign_operator_c *symbol) {
       
   464   TRACE("il_assign_operator_c");
       
   465   return (void *)symbol->variable_name;
       
   466 }
       
   467 
   420 /*| [NOT] any_identifier SENDTO */
   468 /*| [NOT] any_identifier SENDTO */
   421 // SYM_REF2(il_assign_out_operator_c, option, variable_name)
   469 // SYM_REF2(il_assign_out_operator_c, option, variable_name)
   422 void *function_call_param_iterator_c::visit(il_assign_out_operator_c *symbol) {
   470 void *function_call_param_iterator_c::visit(il_assign_out_operator_c *symbol) {
   423   TRACE("il_assign_out_operator_c");
   471   TRACE("il_assign_out_operator_c");
   424 
   472 
   425   // TODO : Handle not_param !!!
   473   // TODO : Handle not_param !!!
   426   // we do not yet support it, so it is best to simply stop than to fail silently...
   474   // we do not yet support it, so it is best to simply stop than to fail silently...
   427   if (NULL != symbol->option) ERROR;
   475   // if (NULL != symbol->option) ERROR;
   428 
   476 
   429   return (void *)symbol->variable_name;
   477   return (void *)symbol->variable_name;
   430 }
   478 }
   431 
   479 
   432 
   480 
   442 /*
   490 /*
   443 SYM_REF2(function_invocation_c, function_name, parameter_assignment_list)
   491 SYM_REF2(function_invocation_c, function_name, parameter_assignment_list)
   444 */
   492 */
   445 void *function_call_param_iterator_c::visit(function_invocation_c *symbol) {
   493 void *function_call_param_iterator_c::visit(function_invocation_c *symbol) {
   446   TRACE("function_invocation_c");
   494   TRACE("function_invocation_c");
   447   if ((symbol_c *)symbol == f_call && symbol->parameter_assignment_list != NULL)
   495   /* If the syntax parser is working correctly, exactly one of the 
   448     return symbol->parameter_assignment_list->accept(*this);
   496    * following two symbols will be NULL, while the other is != NULL.
   449   else
   497    */
   450     return NULL;
   498   if (symbol->   formal_param_list != NULL) return symbol->   formal_param_list->accept(*this);
       
   499   if (symbol->nonformal_param_list != NULL) return symbol->nonformal_param_list->accept(*this);
       
   500 
       
   501   return NULL;
   451 }
   502 }
   452 
   503 
   453 
   504 
   454 /********************/
   505 /********************/
   455 /* B 3.2 Statements */
   506 /* B 3.2 Statements */
   472 /* fb_name '(' [param_assignment_list] ')' */
   523 /* fb_name '(' [param_assignment_list] ')' */
   473 /* param_assignment_list -> may be NULL ! */
   524 /* param_assignment_list -> may be NULL ! */
   474 // SYM_REF2(fb_invocation_c, fb_name, param_assignment_list)
   525 // SYM_REF2(fb_invocation_c, fb_name, param_assignment_list)
   475 void *function_call_param_iterator_c::visit(fb_invocation_c *symbol) {
   526 void *function_call_param_iterator_c::visit(fb_invocation_c *symbol) {
   476   TRACE("fb_invocation_c");
   527   TRACE("fb_invocation_c");
   477   if (symbol->param_assignment_list != NULL)
   528   /* If the syntax parser is working correctly, only one of the 
   478     return symbol->param_assignment_list->accept(*this);
   529    * following two symbols will be != NULL.
   479   else
   530    * However, both may be NULL simultaneously!
   480     return NULL;
   531    */
       
   532   if (symbol->   formal_param_list != NULL) return symbol->   formal_param_list->accept(*this);
       
   533   if (symbol->nonformal_param_list != NULL) return symbol->nonformal_param_list->accept(*this);
       
   534 
       
   535   return NULL;
   481 }
   536 }
   482 
   537 
   483 /* helper symbol for fb_invocation */
   538 /* helper symbol for fb_invocation */
   484 /* param_assignment_list ',' param_assignment */
   539 /* param_assignment_list ',' param_assignment */
   485 // SYM_LIST(param_assignment_list_c)
   540 // SYM_LIST(param_assignment_list_c)