absyntax_utils/decompose_var_instance_name.cc
changeset 181 38d6eb056260
child 202 da1a8186f86f
equal deleted inserted replaced
180:64334c5a00b1 181:38d6eb056260
       
     1 /*
       
     2  * (c) 2003 Mario de Sousa
       
     3  *
       
     4  * Offered to the public under the terms of the GNU General Public License
       
     5  * as published by the Free Software Foundation; either version 2 of the
       
     6  * License, or (at your option) any later version.
       
     7  *
       
     8  * This program is distributed in the hope that it will be useful, but
       
     9  * WITHOUT ANY WARRANTY; without even the implied warranty of
       
    10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
       
    11  * Public License for more details.
       
    12  *
       
    13  * This code is made available on the understanding that it will not be
       
    14  * used in safety-critical situations without a full and competent review.
       
    15  */
       
    16 
       
    17 /*
       
    18  * An IEC 61131-3 IL and ST compiler.
       
    19  *
       
    20  * Based on the
       
    21  * FINAL DRAFT - IEC 61131-3, 2nd Ed. (2001-12-10)
       
    22  *
       
    23  */
       
    24 
       
    25 
       
    26 /* Decomposes a variable instance name into its constituents,
       
    27  * example:
       
    28  *    window.points[1].coordinate.x
       
    29  *
       
    30  *  will succesfully return
       
    31  *        - window
       
    32  *        - points
       
    33  *        - coordinate
       
    34  *        - x
       
    35  * on succesive calls to decompose_var_instance_name_c::next_part()
       
    36  */
       
    37 
       
    38 
       
    39 
       
    40 #include "decompose_var_instance_name.hh"
       
    41 
       
    42 decompose_var_instance_name_c::decompose_var_instance_name_c(symbol_c *variable_instance_name) {
       
    43   variable_name = variable_instance_name;
       
    44   next_variable_name = NULL;
       
    45   current_recursive_variable_name = NULL;
       
    46   previously_returned_variable_name = NULL;
       
    47 }
       
    48 
       
    49 symbol_c *decompose_var_instance_name_c::next_part(void) {
       
    50   /* We must always start from the top!
       
    51    * See note in the structured_variable_c visitor
       
    52    * to understand why...
       
    53    */
       
    54   symbol_c *res = (symbol_c *)variable_name->accept(*this);
       
    55   next_variable_name = current_recursive_variable_name;
       
    56 
       
    57   if (previously_returned_variable_name == res)
       
    58     return NULL;
       
    59   previously_returned_variable_name = res;
       
    60   return res;
       
    61 }
       
    62 
       
    63 /*********************/
       
    64 /* B 1.4 - Variables */
       
    65 /*********************/
       
    66 void *decompose_var_instance_name_c::visit(symbolic_variable_c *symbol) {return (void *)(symbol->var_name);}
       
    67 
       
    68 /********************************************/
       
    69 /* B.1.4.1   Directly Represented Variables */
       
    70 /********************************************/
       
    71 void *decompose_var_instance_name_c::visit(direct_variable_c *symbol) {return (void *)symbol;}
       
    72 
       
    73 /*************************************/
       
    74 /* B.1.4.2   Multi-element Variables */
       
    75 /*************************************/
       
    76 /*  subscripted_variable '[' subscript_list ']' */
       
    77 // SYM_REF2(array_variable_c, subscripted_variable, subscript_list)
       
    78 void *decompose_var_instance_name_c::visit(array_variable_c *symbol) {
       
    79   /* NOTE: the subscripted_variable may itself be a structure!,
       
    80    * so we must recursevily visit!
       
    81    */
       
    82   return symbol->subscripted_variable->accept(*this);
       
    83 }
       
    84 
       
    85 /*  record_variable '.' field_selector */
       
    86 /*  WARNING: input and/or output variables of function blocks
       
    87  *           may be accessed as fields of a tructured variable!
       
    88  *           Code handling a structured_variable_c must take
       
    89  *           this into account!
       
    90  */
       
    91 //SYM_REF2(structured_variable_c, record_variable, field_selector)
       
    92 void *decompose_var_instance_name_c::visit(structured_variable_c *symbol) {
       
    93   /* NOTE: The following code will not work, as structured_variable_c
       
    94    *       are grouped on the left, and not on the right!
       
    95    *
       
    96    *       example: window.origin.x
       
    97    *       will result in
       
    98    *       s1 = structured_variable_c("window, "origin");
       
    99    *       s2 = structured_variable_c(s1, "x");
       
   100    *       AND NOT
       
   101    *       s1 = structured_variable_c("origin", "x");
       
   102    *       s2 = structured_variable_c("window", s1);
       
   103    *
       
   104    *       as the following code assumes!!
       
   105    *
       
   106   current_variable_name = symbol->field_selector;
       
   107   return symbol->record_variable->accept(*this);
       
   108    */
       
   109 
       
   110   /* The correct code, is therefore more complex... */
       
   111   if (next_variable_name == symbol) {
       
   112     /* NOTE: field_selector is always an identifier_c,
       
   113      * so we do not have to recursevily visit it again...
       
   114      * return (void *)symbol->field_selector->accept(*this);  -> NOT REQUIRED!!
       
   115      */
       
   116      return (void *)symbol->field_selector;
       
   117   }
       
   118 
       
   119   current_recursive_variable_name = symbol;
       
   120   return symbol->record_variable->accept(*this);
       
   121 }
       
   122 
       
   123 
       
   124 
       
   125