absyntax_utils/search_varfb_instance_type.cc
changeset 625 c0bda77b37a0
parent 412 aad38592bdde
parent 619 f8c9ac5c529a
child 693 51a2fa6441b9
equal deleted inserted replaced
412:aad38592bdde 625:c0bda77b37a0
     1 /*
     1 /*
     2  *  matiec - a compiler for the programming languages defined in IEC 61131-3
     2  *  matiec - a compiler for the programming languages defined in IEC 61131-3
     3  *
     3  *
     4  *  Copyright (C) 2003-2011  Mario de Sousa (msousa@fe.up.pt)
     4  *  Copyright (C) 2003-2012  Mario de Sousa (msousa@fe.up.pt)
     5  *  Copyright (C) 2007-2011  Laurent Bessard and Edouard Tisserant
     5  *  Copyright (C) 2007-2011  Laurent Bessard and Edouard Tisserant
     6  *
     6  *
     7  *  This program is free software: you can redistribute it and/or modify
     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
     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
     9  *  the Free Software Foundation, either version 3 of the License, or
    73  *   option (2) will return INT
    73  *   option (2) will return INT
    74  * 
    74  * 
    75  *
    75  *
    76  * Member functions:
    76  * Member functions:
    77  * ================
    77  * ================
       
    78  *   get_basetype_id()    ---> returns 2A   (implemented, although currently it is not needed! )
    78  *   get_basetype_decl()  ---> returns 2B 
    79  *   get_basetype_decl()  ---> returns 2B 
    79  *   get_type_id()        ---> returns 1A
    80  *   get_type_id()        ---> returns 1A
    80  * 
    81  * 
    81  *   Since we haven't yet needed them, we don't yet implement
    82  *   Since we haven't yet needed it, we don't yet implement
    82  *   get_basetype_id()    ----> would return 2A
    83  *   get_type_decl()      ---> returns 1B 
    83  *   get_type_decl()      ----> would return 1B
       
    84  */ 
    84  */ 
    85 
    85 
    86 
    86 
    87 /*
    87 
    88  * TODO: this code has a memory leak...
       
    89  *       We call 'new' in several locations, but bever get to 'delete' the object instances...
       
    90  */
       
    91 #include "absyntax_utils.hh"
    88 #include "absyntax_utils.hh"
    92 
    89 
    93 
    90 
       
    91 void search_varfb_instance_type_c::init(void) {
       
    92   this->current_type_id        = NULL;
       
    93   this->current_basetype_id    = NULL;
       
    94   this->current_basetype_decl  = NULL;
       
    95   this->current_field_selector = NULL;
       
    96 }
       
    97 
       
    98 
    94 search_varfb_instance_type_c::search_varfb_instance_type_c(symbol_c *search_scope): search_var_instance_decl(search_scope) {
    99 search_varfb_instance_type_c::search_varfb_instance_type_c(symbol_c *search_scope): search_var_instance_decl(search_scope) {
    95   this->decompose_var_instance_name = NULL;
   100   this->init();
    96   this->current_structelement_name = NULL;
   101 }
    97   this->current_typeid = NULL;
   102 
    98   this->current_basetypeid = NULL;
   103 
    99 }
   104 /* We expect to be passed a symbolic_variable_c */
   100 
   105 symbol_c *search_varfb_instance_type_c::get_type_id(symbol_c *variable_name) {
   101 symbol_c *search_varfb_instance_type_c::get_type_decl(symbol_c *variable_name) {
   106   this->init();
   102   this->current_structelement_name = NULL;
   107   variable_name->accept(*this);
   103   this->current_typeid = NULL;
   108   return current_type_id;
   104   this->current_basetypeid = NULL;
   109 }
   105   this->decompose_var_instance_name = new decompose_var_instance_name_c(variable_name);
   110 
   106   if (NULL == decompose_var_instance_name) ERROR;
   111 
   107 
   112 symbol_c *search_varfb_instance_type_c::get_basetype_id(symbol_c *variable_name) {
   108   /* find the part of the variable name that will appear in the
   113   this->init();
   109    * variable declaration, for e.g., in window.point.x, this would be
   114   variable_name->accept(*this);
   110    * window!
   115   return current_basetype_id;
       
   116 }
       
   117 
       
   118 
       
   119 symbol_c *search_varfb_instance_type_c::get_basetype_decl(symbol_c *variable_name) {
       
   120   this->init();
       
   121   variable_name->accept(*this);
       
   122   return current_basetype_decl;
       
   123 }  
       
   124 
       
   125 
       
   126 
       
   127 
       
   128 /*************************/
       
   129 /* B.1 - Common elements */
       
   130 /*************************/
       
   131 /*******************************************/
       
   132 /* B 1.1 - Letters, digits and identifiers */
       
   133 /*******************************************/
       
   134 // SYM_TOKEN(identifier_c)
       
   135 void *search_varfb_instance_type_c::visit(identifier_c *variable_name) {
       
   136   /* symbol should be a variable name!! */
       
   137   /* Note: although the method is called get_decl(), it is getting the declaration of the variable, which for us is the type_id of that variable! */
       
   138   current_type_id       = search_var_instance_decl.get_decl (variable_name);
       
   139   current_basetype_decl = search_base_type.get_basetype_decl(current_type_id);
       
   140   current_basetype_id   = search_base_type.get_basetype_id  (current_type_id);
       
   141     
       
   142   /* What if the variable has not been declared?  Then this should not be a compiler error! 
       
   143    * However, currently stage 2 of the compiler already detects when variables have not been delcared,
       
   144    * so if the variable's declaration is not found, then that means that we have an internal compiler error!
       
   145    * 
       
   146    * Actually, the above is not true anymore. See the use of the any_symbolic_variable in iec_bison.yy
       
   147    *  - when defining the delay of a delayed action association in SFC
       
   148    *  - in program connections inside configurations (will this search_varfb_instance_type_c class be called to handle this??)
   111    */
   149    */
   112   symbol_c *var_name_part = decompose_var_instance_name->next_part();
   150   // if (NULL == current_type_id) ERROR; 
   113   if (NULL == var_name_part) ERROR;
   151 
   114 
   152   return NULL;
   115   /* Now we try to find the variable instance declaration, to determine its type... */
   153 }
   116   symbol_c *var_decl = search_var_instance_decl.get_decl(var_name_part);
   154 
   117   if (NULL == var_decl) ERROR;
   155 
   118 
   156 
   119   /* if it is a struct or function block, we must search the type
   157 
   120    * of the struct or function block member.
       
   121    * This is done by this class visiting the var_decl.
       
   122    * This class, while visiting, will recursively call
       
   123    * decompose_var_instance_name->get_next() when and if required...
       
   124    */
       
   125   symbol_c *res = (symbol_c *)var_decl->accept(*this);
       
   126   /* NOTE: A Null result is not really an internal compiler error, but rather an error in 
       
   127    * the IEC 61131-3 source code being compiled. This means we cannot just abort the compiler with ERROR.
       
   128    * //   if (NULL == res) ERROR;
       
   129    */
       
   130   if (NULL == res) return NULL;
       
   131 
       
   132   /* make sure that we have decomposed all structure elements of the variable name */
       
   133   symbol_c *var_name = decompose_var_instance_name->next_part();
       
   134   /* NOTE: A non-NULL result is not really an internal compiler error, but rather an error in 
       
   135    * the IEC 61131-3 source code being compiled. 
       
   136    *  (for example, 'int_var.struct_elem' in the source code, when 'int_var' is a simple integer,
       
   137    *   and not a structure, will result in this result being non-NULL!)
       
   138    * This means we cannot just abort the compiler with ERROR.
       
   139    * //   if (NULL != var_name) ERROR;
       
   140    */
       
   141   if (NULL != var_name) return NULL;
       
   142 
       
   143   return res;
       
   144 }
       
   145 
       
   146 
       
   147 symbol_c *search_varfb_instance_type_c::get_basetype_decl(symbol_c *variable_name) {
       
   148   symbol_c *res = get_type_decl(variable_name);
       
   149   if (NULL == res) return NULL;
       
   150   return (symbol_c *)base_type(res);
       
   151 }  
       
   152 
       
   153 
       
   154 unsigned int search_varfb_instance_type_c::get_vartype(symbol_c *variable_name) {
       
   155   this->current_structelement_name = NULL;
       
   156   this->current_typeid = NULL;
       
   157   this->current_basetypeid = NULL;
       
   158   this->is_complex = false;
       
   159   this->decompose_var_instance_name = new decompose_var_instance_name_c(variable_name);
       
   160   if (NULL == decompose_var_instance_name) ERROR;
       
   161 
       
   162   /* find the part of the variable name that will appear in the
       
   163    * variable declaration, for e.g., in window.point.x, this would be
       
   164    * window!
       
   165    */
       
   166   symbol_c *var_name_part = decompose_var_instance_name->next_part();
       
   167   if (NULL == var_name_part) ERROR;
       
   168 
       
   169   /* Now we try to find the variable instance declaration, to determine its type... */
       
   170   symbol_c *var_decl = search_var_instance_decl.get_decl(var_name_part);
       
   171   if (NULL == var_decl) {
       
   172     /* variable instance declaration not found! */
       
   173     return 0;
       
   174   }
       
   175 
       
   176   /* if it is a struct or function block, we must search the type
       
   177    * of the struct or function block member.
       
   178    * This is done by this class visiting the var_decl.
       
   179    * This class, while visiting, will recursively call
       
   180    * decompose_var_instance_name->get_next() when and if required...
       
   181    */
       
   182   var_decl->accept(*this);
       
   183   unsigned int res = search_var_instance_decl.get_vartype();
       
   184   
       
   185   /* make sure that we have decomposed all structure elements of the variable name */
       
   186   symbol_c *var_name = decompose_var_instance_name->next_part();
       
   187   if (NULL != var_name) ERROR;
       
   188 
       
   189   return res;
       
   190 }
       
   191 
       
   192 symbol_c *search_varfb_instance_type_c::get_type_id(symbol_c *variable_name) {
       
   193   this->current_typeid = NULL;
       
   194   symbol_c *vartype = this->get_type_decl(variable_name);
       
   195   if (this->current_typeid != NULL)
       
   196     return this->current_typeid;
       
   197   else
       
   198     return vartype;
       
   199 }
       
   200 
       
   201 bool search_varfb_instance_type_c::type_is_complex(void) {
       
   202   return this->is_complex;
       
   203 }
       
   204 
       
   205 /* a helper function... */
       
   206 void *search_varfb_instance_type_c::visit_list(list_c *list)	{
       
   207   if (NULL == current_structelement_name) ERROR;
       
   208 
       
   209   for(int i = 0; i < list->n; i++) {
       
   210     void *res = list->elements[i]->accept(*this);
       
   211     if (res != NULL)
       
   212       return res;
       
   213   }
       
   214   /* not found! */
       
   215   return NULL;
       
   216 }
       
   217 
       
   218 /* a helper function... */
       
   219 void *search_varfb_instance_type_c::base_type(symbol_c *symbol)	{
       
   220     search_base_type_c search_base_type;
       
   221     return symbol->accept(search_base_type);
       
   222 }
       
   223 
       
   224 /* We override the base class' visitor to identifier_c.
       
   225  * This is so because the base class does not consider a function block
       
   226  * to be a type, unlike this class that allows a variable instance
       
   227  * of a function block type...
       
   228  */
       
   229 void *search_varfb_instance_type_c::visit(identifier_c *type_name) {
       
   230   /* we only store the new type id if none had been found yet.
       
   231    * Since we will recursively carry on looking at the base type 
       
   232    * to determine the base type declaration and id, we must only set this variable
       
   233    * the first time.
       
   234    * e.g. TYPE myint1_t : int    := 1;
       
   235    *           myint2_t : int1_t := 2;
       
   236    *           myint3_t : int2_t := 3;
       
   237    *      END_TYPE;
       
   238    *      VAR
       
   239    *          myint1 : myint1_t;
       
   240    *          myint2 : myint2_t;
       
   241    *          myint3 : myint3_t;
       
   242    *      END_VAR
       
   243    *        
       
   244    *     If we ask for typeid of     myint3, it must return myint3_t
       
   245    *     If we ask for basetypeid of myint3, it must return int
       
   246    *
       
   247    *     When determining the data type of myint3, we will recursively go all the way
       
   248    *     down to int, but we must still only store myint3_t as the base type id.
       
   249    */
       
   250   if (NULL == this->current_typeid)
       
   251     this->current_typeid = type_name;
       
   252   this->current_basetypeid = type_name;
       
   253 
       
   254   /* look up the type declaration... */
       
   255   symbol_c *fb_decl = function_block_type_symtable.find_value(type_name);
       
   256   if (fb_decl != function_block_type_symtable.end_value())
       
   257     /* Type declaration found!! */
       
   258     return fb_decl->accept(*this);
       
   259 
       
   260   /* No. It is not a function block, so we let
       
   261    * the base class take care of it...
       
   262    */
       
   263   return search_base_type_c::visit(type_name);
       
   264 }
       
   265 
   158 
   266 /********************************/
   159 /********************************/
   267 /* B 1.3.3 - Derived data types */
   160 /* B 1.3.3 - Derived data types */
   268 /********************************/
   161 /********************************/
   269 
       
   270 /*  identifier ':' array_spec_init */
   162 /*  identifier ':' array_spec_init */
       
   163 /* NOTE: I don't think this will ever get called, since in the visit method for array_variable_c
       
   164  * we use the basetype_decl for recursively calling this class, and the base type should never be a 
       
   165  * array_type_declaration_c, but for now, let's leave it in...
       
   166  */
   271 void *search_varfb_instance_type_c::visit(array_type_declaration_c *symbol) {
   167 void *search_varfb_instance_type_c::visit(array_type_declaration_c *symbol) {
   272   return symbol->array_spec_init->accept(*this);
   168   ERROR;
       
   169   return NULL;
   273 }
   170 }
   274     
   171     
   275 /* array_specification [ASSIGN array_initialization] */
   172 /* array_specification [ASSIGN array_initialization] */
   276 /* array_initialization may be NULL ! */
   173 /* array_initialization may be NULL ! */
       
   174 /* NOTE: I don't think this will ever get called, since in the visit method for array_variable_c
       
   175  * we use the basetype_decl for recursively calling this class, and the base type should never be a 
       
   176  * array_spec_init_c, but for now, let's leave it in...
       
   177  */
   277 void *search_varfb_instance_type_c::visit(array_spec_init_c *symbol) {
   178 void *search_varfb_instance_type_c::visit(array_spec_init_c *symbol) {
   278   return symbol->array_specification->accept(*this);
   179   /* Note that the 'array_specification' may be either an identifier of a previsously defined array type, 
       
   180    * or an array_specification_c, so we can not stop here and simply return a array_spec_init_c, 
       
   181    * especially if we are looking for the base class!
       
   182    */
       
   183   ERROR;
       
   184   return NULL;
   279 }
   185 }
   280 
   186 
   281 /* ARRAY '[' array_subrange_list ']' OF non_generic_type_name */
   187 /* ARRAY '[' array_subrange_list ']' OF non_generic_type_name */
       
   188 /* NOTE: This method will be reached after being called from the 
       
   189  * search_varfb_instance_type_c::visit(array_variable_c *symbol)
       
   190  * method, so we must return the data type of the data stored in the array, 
       
   191  * and not the data type of the array itself!
       
   192  */
   282 void *search_varfb_instance_type_c::visit(array_specification_c *symbol) {
   193 void *search_varfb_instance_type_c::visit(array_specification_c *symbol) {
   283   this->is_complex = true;
   194   /* found the type of the element we were looking for! */
   284   this->current_typeid = symbol;
   195   current_type_id       = symbol->non_generic_type_name;
   285   return symbol->non_generic_type_name->accept(*this);
   196   current_basetype_decl = search_base_type.get_basetype_decl(current_type_id);
   286 }
   197   current_basetype_id   = search_base_type.get_basetype_id  (current_type_id);
       
   198     
       
   199   return NULL; 
       
   200 }
       
   201 
   287 
   202 
   288 /*  structure_type_name ':' structure_specification */
   203 /*  structure_type_name ':' structure_specification */
   289 /* NOTE: this is only used inside a TYPE ... END_TYPE declaration. 
   204 /* NOTE: this is only used inside a TYPE ... END_TYPE declaration. 
   290  * It is never used directly when declaring a new variable! 
   205  * It is never used directly when declaring a new variable! 
   291  */
   206  */
       
   207 /* NOTE: I don't think this will ever get called, since in the visit method for structured_variable_c
       
   208  * we use the basetype_decl for recursively calling this class, and the base type should never be a 
       
   209  * structure_type_declaration_c, but for now, let's leave it in...
       
   210  */
   292 void *search_varfb_instance_type_c::visit(structure_type_declaration_c *symbol) {
   211 void *search_varfb_instance_type_c::visit(structure_type_declaration_c *symbol) {
   293   this->is_complex = true;
   212   if (NULL == current_field_selector) ERROR;
   294 
   213   symbol->structure_specification->accept(*this);
   295   if (NULL == current_structelement_name) ERROR;
   214   return NULL;
   296   return symbol->structure_specification->accept(*this);
       
   297   /* NOTE: structure_specification will point to either a
   215   /* NOTE: structure_specification will point to either a
   298    *       initialized_structure_c
   216    *       initialized_structure_c
   299    *       OR A
   217    *       OR A
   300    *       structure_element_declaration_list_c
   218    *       structure_element_declaration_list_c
   301    */
   219    */
   302 }
   220 }
   303 
   221 
   304 /*  var1_list ':' structure_type_name */
       
   305 void *search_varfb_instance_type_c::visit(structured_var_declaration_c *symbol) {
       
   306   this->is_complex = true;
       
   307   if (NULL != current_structelement_name) ERROR;
       
   308 
       
   309   /* make sure that we have decomposed all structure elements of the variable name */
       
   310   symbol_c *var_name = decompose_var_instance_name->next_part();
       
   311   if (NULL == var_name) {
       
   312 	/* this is it... !
       
   313 	 * No need to look any further...
       
   314 	 * Note also that, unlike for the struct types, a function block may
       
   315 	 * not be defined based on another (i.e. no inheritance is allowed),
       
   316 	 * so this function block is already the most base type.
       
   317 	 * We simply return it.
       
   318 	 */
       
   319 	return (void *)symbol;
       
   320   }
       
   321 
       
   322   /* reset current_type_id because of new structure element part */
       
   323   this->current_typeid = NULL;
       
   324 
       
   325   /* look for the var_name in the structure declaration */
       
   326   current_structelement_name = var_name;
       
   327 
       
   328   /* recursively find out the data type of current_structelement_name... */
       
   329   return symbol->structure_type_name->accept(*this);
       
   330 }
       
   331 
       
   332 /* structure_type_name ASSIGN structure_initialization */
   222 /* structure_type_name ASSIGN structure_initialization */
   333 /* structure_initialization may be NULL ! */
   223 /* structure_initialization may be NULL ! */
   334 // SYM_REF2(initialized_structure_c, structure_type_name, structure_initialization)
   224 // SYM_REF2(initialized_structure_c, structure_type_name, structure_initialization)
   335 /* NOTE: only the initialized structure is ever used when declaring a new variable instance */
   225 /* NOTE: only the initialized structure is never used when declaring a new variable instance */
       
   226 /* NOTE: I don't think this will ever get called, since in the visit method for structured_variable_c
       
   227  * we use the basetype_decl for recursively calling this class, and the base type should never be a 
       
   228  * initialized_structure_c, but for now, let's leave it in...
       
   229  */
   336 void *search_varfb_instance_type_c::visit(initialized_structure_c *symbol)	{
   230 void *search_varfb_instance_type_c::visit(initialized_structure_c *symbol)	{
   337   this->is_complex = true;
   231   if (NULL != current_field_selector) ERROR;
   338   if (NULL != current_structelement_name) ERROR;
   232   
   339   
   233   /* recursively find out the data type of current_field_selector... */
   340   /* make sure that we have decomposed all structure elements of the variable name */
   234   symbol->structure_type_name->accept(*this);
   341   symbol_c *var_name = decompose_var_instance_name->next_part();
   235   return NULL;
   342   if (NULL == var_name) {
       
   343     /* this is it... !
       
   344      * No need to look any further...
       
   345      * Note also that, unlike for the struct types, a function block may
       
   346      * not be defined based on another (i.e. no inheritance is allowed),
       
   347      * so this function block is already the most base type.
       
   348      * We simply return it.
       
   349      */
       
   350     return (void *)symbol;
       
   351   }
       
   352 
       
   353   /* reset current_type_id because of new structure element part */
       
   354   this->current_typeid = NULL;
       
   355 
       
   356   /* look for the var_name in the structure declaration */
       
   357   current_structelement_name = var_name;
       
   358 
       
   359   /* recursively find out the data type of current_structelement_name... */
       
   360   return symbol->structure_type_name->accept(*this);
       
   361 }
   236 }
   362 
   237 
   363 /* helper symbol for structure_declaration */
   238 /* helper symbol for structure_declaration */
   364 /* structure_declaration:  STRUCT structure_element_declaration_list END_STRUCT */
   239 /* structure_declaration:  STRUCT structure_element_declaration_list END_STRUCT */
   365 /* structure_element_declaration_list structure_element_declaration ';' */
   240 /* structure_element_declaration_list structure_element_declaration ';' */
   366 void *search_varfb_instance_type_c::visit(structure_element_declaration_list_c *symbol)	{
   241 void *search_varfb_instance_type_c::visit(structure_element_declaration_list_c *symbol)	{
   367   if (NULL == current_structelement_name) ERROR;
   242   if (NULL == current_field_selector) ERROR;
       
   243 
   368   /* now search the structure declaration */
   244   /* now search the structure declaration */
   369   return visit_list(symbol);
   245   for(int i = 0; i < symbol->n; i++) {
       
   246     symbol->elements[i]->accept(*this);
       
   247   }
       
   248 
       
   249   return NULL;
   370 }
   250 }
   371 
   251 
   372 /*  structure_element_name ':' spec_init */
   252 /*  structure_element_name ':' spec_init */
   373 void *search_varfb_instance_type_c::visit(structure_element_declaration_c *symbol) {
   253 void *search_varfb_instance_type_c::visit(structure_element_declaration_c *symbol) {
   374   if (NULL == current_structelement_name) ERROR;
   254   if (NULL == current_field_selector) ERROR;
   375 
   255 
   376   if (compare_identifiers(symbol->structure_element_name, current_structelement_name) == 0) {
   256   if (compare_identifiers(symbol->structure_element_name, current_field_selector) == 0) {
   377     current_structelement_name = NULL;
       
   378     /* found the type of the element we were looking for! */
   257     /* found the type of the element we were looking for! */
   379     return symbol->spec_init->accept(*this);
   258     current_type_id       = symbol->spec_init;
       
   259     current_basetype_decl = search_base_type.get_basetype_decl(current_type_id);
       
   260     current_basetype_id   = search_base_type.get_basetype_id  (current_type_id);
   380   }  
   261   }  
   381 
   262 
   382   /* Did not find the type of the element we were looking for! */
   263   /* Did not find the type of the element we were looking for! */
   383   /* Will keep looking... */
   264   /* Will keep looking... */
   384   return NULL;
   265   return NULL;
   390 void *search_varfb_instance_type_c::visit(structure_element_initialization_list_c *symbol) {ERROR; return NULL;} /* should never get called... */
   271 void *search_varfb_instance_type_c::visit(structure_element_initialization_list_c *symbol) {ERROR; return NULL;} /* should never get called... */
   391 /*  structure_element_name ASSIGN value */
   272 /*  structure_element_name ASSIGN value */
   392 void *search_varfb_instance_type_c::visit(structure_element_initialization_c *symbol) {ERROR; return NULL;} /* should never get called... */
   273 void *search_varfb_instance_type_c::visit(structure_element_initialization_c *symbol) {ERROR; return NULL;} /* should never get called... */
   393 
   274 
   394 
   275 
       
   276 /*********************/
       
   277 /* B 1.4 - Variables */
       
   278 /*********************/
       
   279 // SYM_REF1(symbolic_variable_c, var_name)
       
   280 void *search_varfb_instance_type_c::visit(symbolic_variable_c *symbol) {
       
   281   symbol->var_name->accept(*this);
       
   282   return NULL;
       
   283 }
       
   284 
       
   285 /********************************************/
       
   286 /* B.1.4.1   Directly Represented Variables */
       
   287 /********************************************/
       
   288 // SYM_TOKEN(direct_variable_c)
       
   289 /* We do not yet handle this. Will we ever need to handle it, as the data type of the direct variable is
       
   290  * directly obtainable from the syntax of the direct variable itself?
       
   291  */
       
   292 
       
   293 /*************************************/
       
   294 /* B 1.4.2 - Multi-element variables */
       
   295 /*************************************/
       
   296 /*  subscripted_variable '[' subscript_list ']' */
       
   297 // SYM_REF2(array_variable_c, subscripted_variable, subscript_list)
       
   298 /* NOTE: when passed a array_variable_c, which represents some IEC61131-3 code similar to X[42]
       
   299  * we must return the data type of the value _stored_ in the array.
       
   300  * If you want to get the data type of the array itself (i.e. just the X variable, without the [42])
       
   301  * then this class must be called with the identifier_c 'X'.
       
   302  */
       
   303 void *search_varfb_instance_type_c::visit(array_variable_c *symbol) {
       
   304   /* determine the data type of the subscripted_variable... 
       
   305    * This should be an array_specification_c
       
   306    *    ARRAY [xx..yy] OF Stored_Data_Type
       
   307    */
       
   308   symbol->subscripted_variable->accept(*this);
       
   309   symbol_c *basetype_decl = current_basetype_decl;
       
   310   this->init(); /* set all current_*** pointers to NULL ! */
       
   311   
       
   312   /* Now we determine the 'Stored_Data_Type', i.e. the data type of the variable stored in the array. */
       
   313   if (NULL != basetype_decl) {
       
   314     basetype_decl->accept(*this);
       
   315   }
       
   316   
       
   317   return NULL;
       
   318 }
       
   319 
       
   320 
       
   321 /*  record_variable '.' field_selector */
       
   322 /*  WARNING: input and/or output variables of function blocks
       
   323  *           may be accessed as fields of a structured variable!
       
   324  *           Code handling a structured_variable_c must take this into account!
       
   325  *           (i.e. that a FB instance may be accessed as a structured variable)!
       
   326  *
       
   327  *  WARNING: Status bit (.X) and activation time (.T) of STEPS in SFC diagrams
       
   328  *           may be accessed as fields of a structured variable!
       
   329  *           Code handling a structured_variable_c must take this into account 
       
   330  *           (i.e. that an SFC STEP may be accessed as a structured variable)!
       
   331  */
       
   332 // SYM_REF2(structured_variable_c, record_variable, field_selector)
       
   333 void *search_varfb_instance_type_c::visit(structured_variable_c *symbol) {
       
   334   symbol->record_variable->accept(*this);
       
   335   symbol_c *basetype_decl = current_basetype_decl;
       
   336   this->init(); /* set all current_*** pointers to NULL ! */
       
   337   
       
   338   /* Now we search for the data type of the field... But only if we were able to determine the data type of the variable */
       
   339   if (NULL != basetype_decl) {
       
   340     current_field_selector = symbol->field_selector;
       
   341     basetype_decl->accept(*this);
       
   342     current_field_selector = NULL;
       
   343   }
       
   344   
       
   345   return NULL;
       
   346 }
       
   347 
       
   348 
   395 
   349 
   396 /**************************************/
   350 /**************************************/
   397 /* B.1.5 - Program organization units */
   351 /* B.1.5 - Program organization units */
   398 /**************************************/
   352 /**************************************/
   399 /*****************************/
   353 /*****************************/
   400 /* B 1.5.2 - Function Blocks */
   354 /* B 1.5.2 - Function Blocks */
   401 /*****************************/
   355 /*****************************/
       
   356 
   402 /*  FUNCTION_BLOCK derived_function_block_name io_OR_other_var_declarations function_block_body END_FUNCTION_BLOCK */
   357 /*  FUNCTION_BLOCK derived_function_block_name io_OR_other_var_declarations function_block_body END_FUNCTION_BLOCK */
   403 // SYM_REF4(function_block_declaration_c, fblock_name, var_declarations, fblock_body, unused)
   358 // SYM_REF4(function_block_declaration_c, fblock_name, var_declarations, fblock_body, unused)
   404 void *search_varfb_instance_type_c::visit(function_block_declaration_c *symbol) {
   359 void *search_varfb_instance_type_c::visit(function_block_declaration_c *symbol) {
   405   /* make sure that we have decomposed all structure elements of the variable name */
   360   if (NULL == current_field_selector) ERROR;
   406   symbol_c *var_name = decompose_var_instance_name->next_part();
   361 
   407   if (NULL == var_name) {
   362   /* now search the function block declaration for the variable... */
   408     /* this is it... !
   363   /* If not found, these pointers will all be set to NULL!! */
   409      * No need to look any further...
   364   search_var_instance_decl_c search_decl(symbol);
   410      * Note also that, unlike for the struct types, a function block may
   365   current_type_id       = search_decl.get_decl(current_field_selector);
   411      * not be defined based on another (i.e. no inheritance is allowed),
   366   current_basetype_decl = search_base_type.get_basetype_decl(current_type_id);
   412      * so this function block is already the most base type.
   367   current_basetype_id   = search_base_type.get_basetype_id  (current_type_id);
   413      * We simply return it.
   368   
   414      */
   369   return NULL;
   415     return (void *)symbol;
   370 }
   416    }
   371 
   417 
   372 
   418    /* reset current_type_id because of new structure element part */
   373 
   419    this->current_typeid = NULL;
   374 /*********************************************/
   420 
   375 /* B.1.6  Sequential function chart elements */
   421    /* now search the function block declaration for the variable... */
   376 /*********************************************/
   422    search_var_instance_decl_c search_decl(symbol);
   377 /* INITIAL_STEP step_name ':' action_association_list END_STEP */
   423    symbol_c *var_decl = search_decl.get_decl(var_name);
   378 // SYM_REF2(initial_step_c, step_name, action_association_list)
   424    if (NULL == var_decl) {
   379 /* NOTE: this method may be called from visit(structured_variable_c *symbol) method| */
   425      /* variable instance declaration not found! */
   380 void *search_varfb_instance_type_c::visit(initial_step_c *symbol) {
   426      return NULL;
   381   if (NULL == current_field_selector) ERROR;
   427    }
   382 
   428 #if 0
   383   identifier_c T("T");
   429    /* We have found the declaration.
   384   identifier_c X("X");
   430     * Should we look any further?
   385   
   431     */
   386   if (compare_identifiers(&T, current_field_selector) == 0)   
   432    var_name = decompose_var_instance_name->next_part();
   387     current_type_id = &search_constant_type_c::time_type_name;
   433    if (NULL == var_name) {
   388   if (compare_identifiers(&X, current_field_selector) == 0)   
   434      /* this is it... ! */
   389     current_type_id = &search_constant_type_c::bool_type_name;
   435      return base_type(var_decl);
   390   
   436    }
   391   current_basetype_decl = search_base_type.get_basetype_decl(current_type_id);
   437 
   392   current_basetype_id   = search_base_type.get_basetype_id  (current_type_id);
   438   current_structelement_name = var_name;
   393 
   439   /* recursively find out the data type of var_name... */
   394   return NULL;
   440   return symbol->var_declarations->accept(*this);
   395 }
   441 #endif
   396 
   442   /* carry on recursively, in case the variable has more elements to be decomposed... */
   397 
   443   return var_decl->accept(*this);
   398 /* STEP step_name ':' action_association_list END_STEP */
   444 }
   399 // SYM_REF2(step_c, step_name, action_association_list)
       
   400 /* NOTE: this method may be called from visit(structured_variable_c *symbol) method| */
       
   401 void *search_varfb_instance_type_c::visit(step_c *symbol) {
       
   402   /* The code here should be identicial to the code in the visit(initial_step_c *) visitor! So we simply call the other visitor! */
       
   403   initial_step_c initial_step(NULL, NULL);
       
   404   return initial_step.accept(*this);
       
   405 }