absyntax_utils/case_element_iterator.cc
changeset 347 44ff2a6fcadc
child 377 60b012b7793f
equal deleted inserted replaced
346:620fd98a021d 347:44ff2a6fcadc
       
     1 /*
       
     2  *  matiec - a compiler for the programming languages defined in IEC 61131-3
       
     3  *
       
     4  *  Copyright (C) 2003-2011  Mario de Sousa (msousa@fe.up.pt)
       
     5  *  Copyright (C) 2007-2011  Laurent Bessard and Edouard Tisserant
       
     6  *
       
     7  *  This program is free software: you can redistribute it and/or modify
       
     8  *  it under the terms of the GNU General Public License as published by
       
     9  *  the Free Software Foundation, either version 3 of the License, or
       
    10  *  (at your option) any later version.
       
    11  *
       
    12  *  This program is distributed in the hope that it will be useful,
       
    13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
    15  *  GNU General Public License for more details.
       
    16  *
       
    17  *  You should have received a copy of the GNU General Public License
       
    18  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
       
    19  *
       
    20  *
       
    21  * This code is made available on the understanding that it will not be
       
    22  * used in safety-critical situations without a full and competent review.
       
    23  */
       
    24 
       
    25 /*
       
    26  * An IEC 61131-3 compiler.
       
    27  *
       
    28  * Based on the
       
    29  * FINAL DRAFT - IEC 61131-3, 2nd Ed. (2001-12-10)
       
    30  *
       
    31  */
       
    32 
       
    33 
       
    34 /*
       
    35  * Case element iterator.
       
    36  * Iterate through the elements of a case list.
       
    37  *
       
    38  * This is part of the 4th stage that generates
       
    39  * a c++ source program equivalent to the IL and ST
       
    40  * code.
       
    41  */
       
    42 
       
    43 /* Given a case_list_c and a type of element, iterate through
       
    44  * each element, returning the symbol of each element if from
       
    45  * the good type...case_element_iterator_c
       
    46  */
       
    47 
       
    48 
       
    49 
       
    50 
       
    51 #include "case_element_iterator.hh"
       
    52 
       
    53 
       
    54 //#define DEBUG
       
    55 #ifdef DEBUG
       
    56 #define TRACE(classname) printf("\n____%s____\n",classname);
       
    57 #else
       
    58 #define TRACE(classname)
       
    59 #endif
       
    60 
       
    61 
       
    62 #define ERROR error_exit(__FILE__,__LINE__)
       
    63 /* function defined in main.cc */
       
    64 extern void error_exit(const char *file_name, int line_no);
       
    65 
       
    66 
       
    67 void* case_element_iterator_c::handle_case_element(symbol_c *case_element) {
       
    68   if (current_case_element == case_element) {
       
    69     current_case_element = NULL;
       
    70   }
       
    71   else if (current_case_element == NULL) {
       
    72 	current_case_element = case_element;
       
    73 	return case_element;
       
    74   }
       
    75 
       
    76   /* Not found! */
       
    77   return NULL;
       
    78 }
       
    79 
       
    80 void* case_element_iterator_c::iterate_list(list_c *list) {
       
    81   void *res;
       
    82   for (int i = 0; i < list->n; i++) {
       
    83     res = list->elements[i]->accept(*this);
       
    84     if (res != NULL)
       
    85         return res;
       
    86   }
       
    87   return NULL;
       
    88 }
       
    89 
       
    90 /* start off at the first case element once again... */
       
    91 void case_element_iterator_c::reset(void) {
       
    92   current_case_element = NULL;
       
    93 }
       
    94 
       
    95 
       
    96 /* initialise the iterator object.
       
    97  * We must be given a reference to a case_list_c that will be analysed...
       
    98  */
       
    99 case_element_iterator_c::case_element_iterator_c(symbol_c *list, case_element_t element_type) {
       
   100   /* do some consistency check... */
       
   101   case_list_c* case_list = dynamic_cast<case_list_c*>(list);
       
   102 
       
   103   if (NULL == case_list) ERROR;
       
   104 
       
   105   /* OK. Now initialise this object... */
       
   106   this->case_list = list;
       
   107   this->wanted_element_type = element_type;
       
   108   reset();
       
   109 }
       
   110 
       
   111 
       
   112 
       
   113 /* Skip to the next case element of type chosen. After object creation,
       
   114  * the object references on case element _before_ the first, so
       
   115  * this function must be called once to get the object to
       
   116  * reference the first element...
       
   117  *
       
   118  * Returns the case element's symbol!
       
   119  */
       
   120 symbol_c *case_element_iterator_c::next(void) {
       
   121   void *res = case_list->accept(*this);
       
   122   if (res == NULL) 
       
   123     return NULL;
       
   124 
       
   125   return current_case_element;
       
   126 }
       
   127 
       
   128 /******************************/
       
   129 /* B 1.2.1 - Numeric Literals */
       
   130 /******************************/
       
   131 void *case_element_iterator_c::visit(integer_c *symbol) {
       
   132   switch (wanted_element_type) {
       
   133 	case element_single:
       
   134 	  return handle_case_element(symbol);
       
   135 	  break;
       
   136 	default:
       
   137 	  break;
       
   138   }
       
   139   return NULL;
       
   140 }
       
   141 
       
   142 void *case_element_iterator_c::visit(neg_integer_c *symbol) {
       
   143   switch (wanted_element_type) {
       
   144 	case element_single:
       
   145 	  return handle_case_element(symbol);
       
   146 	  break;
       
   147 	default:
       
   148 	  break;
       
   149   }
       
   150   return NULL;
       
   151 }
       
   152 
       
   153 /********************************/
       
   154 /* B 1.3.3 - Derived data types */
       
   155 /********************************/
       
   156 /*  signed_integer DOTDOT signed_integer */
       
   157 void *case_element_iterator_c::visit(subrange_c *symbol) {
       
   158   switch (wanted_element_type) {
       
   159     case element_subrange:
       
   160       return handle_case_element(symbol);
       
   161       break;
       
   162     default:
       
   163       break;
       
   164   }
       
   165   return NULL;
       
   166 }
       
   167 
       
   168 /* enumerated_type_name '#' identifier */
       
   169 void *case_element_iterator_c::visit(enumerated_value_c *symbol) {
       
   170   switch (wanted_element_type) {
       
   171     case element_single:
       
   172       return handle_case_element(symbol);
       
   173       break;
       
   174     default:
       
   175       break;
       
   176   }
       
   177   return NULL;
       
   178 }
       
   179 
       
   180 /********************************/
       
   181 /* B 3.2.3 Selection Statements */
       
   182 /********************************/
       
   183 void *case_element_iterator_c::visit(case_list_c *symbol) {
       
   184   return iterate_list(symbol);
       
   185 }
       
   186