absyntax_utils/function_param_iterator.cc
changeset 595 c41975a290ce
parent 587 1ecf916cc397
child 596 4efb11e44065
equal deleted inserted replaced
594:c8092e909886 595:c41975a290ce
    45  * function in/out/inout parameter, returning the name
    45  * function in/out/inout parameter, returning the name
    46  * of each parameter...function_param_iterator_c
    46  * of each parameter...function_param_iterator_c
    47  */
    47  */
    48 
    48 
    49 
    49 
    50 
    50 #include "function_param_iterator.hh"  /* no longer required, aready included by absyntax_utils.hh */
    51 #include "absyntax_utils.hh"  /* required for extract_integer() */
    51 #include "spec_init_separator.hh"  /* no longer required, aready included by absyntax_utils.hh */
    52 // #include "function_param_iterator.hh"  /* no longer required, aready included by absyntax_utils.hh */
       
    53 // #include "spec_init_separator.hh"  /* no longer required, aready included by absyntax_utils.hh */
       
    54 #include <stdlib.h>  /* required for strtol() */
    52 #include <stdlib.h>  /* required for strtol() */
    55 #include <string.h>
    53 #include <string.h>
    56 #include <strings.h>
    54 #include <strings.h>
    57 
    55 #include <limits> // required for std::numeric_limits< XXX >::max()
       
    56 #include <errno.h> // required for errno
    58 
    57 
    59 //#define DEBUG
    58 //#define DEBUG
    60 #ifdef DEBUG
    59 #ifdef DEBUG
    61 #define TRACE(classname) printf("\n____%s____\n",classname);
    60 #define TRACE(classname) printf("\n____%s____\n",classname);
    62 #else
    61 #else
    65 
    64 
    66 
    65 
    67 #define ERROR error_exit(__FILE__,__LINE__)
    66 #define ERROR error_exit(__FILE__,__LINE__)
    68 /* function defined in main.cc */
    67 /* function defined in main.cc */
    69 extern void error_exit(const char *file_name, int line_no);
    68 extern void error_exit(const char *file_name, int line_no);
       
    69 
       
    70 
       
    71 
       
    72 
       
    73 
       
    74 /* NOTE: The following function is not really needed, as we could get the value that constant_folding_c determined for this
       
    75  *       integer. Remember that currently constant_folding_c runs before this class is ever used/called!
       
    76  *       However, I (Mario) do not currently feel it would be a good idea to restrict the use of this
       
    77  *       abstract syntax utility to only after the constant_folding_c has had a chance to fill in the constant value
       
    78  *       of this symbol. 
       
    79  *       For this reason only, I have opted to let this abstract syntax utility have its own private copy of the
       
    80  *       extract_integer() function.
       
    81  *       Another aspect that makes this OK is that this function will only be used to extract the integer value of the
       
    82  *       index for the first extensible paramater (examples follow shortly). Since this is an extension to IEC 61131-3 
       
    83  *       that we created to allow us to handle extensible functions with very little hard coding, it is OK if we
       
    84  *       impose extra/different limits on how an integer may be legally be formated in this case. This will also 
       
    85  *       only show up in code that describes the interface to the standard function of IEC 61131-3, which the user
       
    86  *       will not ever get to see. We write that IEC 61131-3 code ourselves!
       
    87  *
       
    88  *      Example of source code we will be parsing and analysing:
       
    89  *
       
    90  *      FUNCTION ADD : REAL VAR_INPUT IN 1 .. : REAL; END_VAR RETURN; END_FUNCTION
       
    91  *                                      ^^^
       
    92  *
       
    93  *      FUNCTION MUX : REAL VAR_INPUT K : USINT; IN 0 .. : REAL; END_VAR RETURN; END_FUNCTION
       
    94  *                                                 ^^^
       
    95  *
       
    96  *      Basically, currently this will only be either a '0' or a '1' !!
       
    97  */
       
    98 
       
    99 /* NOTE: it must ignore underscores! */
       
   100 static int extract_first_index_value(symbol_c *sym) {
       
   101   std::string str = "";
       
   102   integer_c *integer;
       
   103   long int ret;
       
   104 
       
   105   if ((integer = dynamic_cast<integer_c *>(sym)) == NULL) ERROR;
       
   106   for(unsigned int i = 0; i < strlen(integer->value); i++)
       
   107     if (integer->value[i] != '_')  str += integer->value[i];
       
   108 
       
   109   errno = 0; // since strtoXX() may legally return 0, we must set errno to 0 to detect errors correctly!
       
   110   ret = strtol(str.c_str(), NULL, 10);
       
   111   if (errno != 0) ERROR;
       
   112   if (ret < 0) ERROR; // the following code assumes that the first index will never be negative!
       
   113   if (ret > std::numeric_limits< int >::max()) ERROR; // output of this function is only an int!!
       
   114 
       
   115   return ret;
       
   116 }
       
   117 
       
   118 
       
   119 
       
   120 
       
   121 
       
   122 
       
   123 
    70 
   124 
    71 
   125 
    72 
   126 
    73 /* compare the name of two __extensible__ function parameters.
   127 /* compare the name of two __extensible__ function parameters.
    74  * The usual use case is to have one of the parameters as used
   128  * The usual use case is to have one of the parameters as used
   128         symbol_c *sym = list->elements[i];
   182         symbol_c *sym = list->elements[i];
   129         extensible_input_parameter_c *extensible_parameter = dynamic_cast<extensible_input_parameter_c *>(sym);
   183         extensible_input_parameter_c *extensible_parameter = dynamic_cast<extensible_input_parameter_c *>(sym);
   130         if (extensible_parameter != NULL) {
   184         if (extensible_parameter != NULL) {
   131           sym = extensible_parameter->var_name;
   185           sym = extensible_parameter->var_name;
   132           current_param_is_extensible = true;
   186           current_param_is_extensible = true;
   133           _first_extensible_param_index = extract_int64_value(extensible_parameter->first_index);
   187           _first_extensible_param_index = extract_first_index_value(extensible_parameter->first_index);
   134         }
   188         }
   135         identifier_c *variable_name = dynamic_cast<identifier_c *>(sym);
   189         identifier_c *variable_name = dynamic_cast<identifier_c *>(sym);
   136         if (variable_name == NULL) ERROR;
   190         if (variable_name == NULL) ERROR;
   137         
   191         
   138         if (!current_param_is_extensible)
   192         if (!current_param_is_extensible)
   165     case search_op:
   219     case search_op:
   166       extensible_input_parameter_c *extensible_parameter = dynamic_cast<extensible_input_parameter_c *>(var_name);
   220       extensible_input_parameter_c *extensible_parameter = dynamic_cast<extensible_input_parameter_c *>(var_name);
   167       if (extensible_parameter != NULL) {
   221       if (extensible_parameter != NULL) {
   168         var_name = extensible_parameter->var_name;
   222         var_name = extensible_parameter->var_name;
   169         current_param_is_extensible = true;
   223         current_param_is_extensible = true;
   170         _first_extensible_param_index = extract_int64_value(extensible_parameter->first_index);
   224         _first_extensible_param_index = extract_first_index_value(extensible_parameter->first_index);
   171       }
   225       }
   172       identifier_c *variable_name = dynamic_cast<identifier_c *>(var_name);
   226       identifier_c *variable_name = dynamic_cast<identifier_c *>(var_name);
   173       if (variable_name == NULL) ERROR;
   227       if (variable_name == NULL) ERROR;
   174       
   228       
   175       if (!current_param_is_extensible)
   229       if (!current_param_is_extensible)
   263   symbol_c *sym = (symbol_c *)res;
   317   symbol_c *sym = (symbol_c *)res;
   264   extensible_input_parameter_c *extensible_parameter = dynamic_cast<extensible_input_parameter_c *>(sym);
   318   extensible_input_parameter_c *extensible_parameter = dynamic_cast<extensible_input_parameter_c *>(sym);
   265   if (extensible_parameter != NULL) {
   319   if (extensible_parameter != NULL) {
   266     sym = extensible_parameter->var_name;
   320     sym = extensible_parameter->var_name;
   267     current_param_is_extensible = true;
   321     current_param_is_extensible = true;
   268     _first_extensible_param_index = extract_int64_value(extensible_parameter->first_index);
   322     _first_extensible_param_index = extract_first_index_value(extensible_parameter->first_index);
   269     current_extensible_param_index = _first_extensible_param_index;
   323     current_extensible_param_index = _first_extensible_param_index;
   270   }
   324   }
   271   identifier = dynamic_cast<identifier_c *>(sym);
   325   identifier = dynamic_cast<identifier_c *>(sym);
   272   if (identifier == NULL)
   326   if (identifier == NULL)
   273     ERROR;
   327     ERROR;