stage4/generate_iec/generate_iec.cc
changeset 0 fb772792efd1
child 1 5d893a68be6e
equal deleted inserted replaced
-1:000000000000 0:fb772792efd1
       
     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 /*
       
    27  * Code to be included into the code generated by the 4th stage.
       
    28  *
       
    29  * This is part of the 4th stage that generates
       
    30  * a ST and IL source program equivalent to the IL and ST
       
    31  * code.
       
    32  * This is expected to be used mainly in debuging the syntax
       
    33  * and lexical parser, and as a starting point for other
       
    34  * 4th stages.
       
    35  */
       
    36 
       
    37 
       
    38 
       
    39 
       
    40 
       
    41 
       
    42 // #include <stdio.h>  /* required for NULL */
       
    43 #include <string>
       
    44 #include <iostream>
       
    45 #include "generate_iec.hh"
       
    46 
       
    47 #include "../stage4.hh"
       
    48 
       
    49 
       
    50 
       
    51 
       
    52 
       
    53 
       
    54 //class generate_iec_c: public iterator_visitor_c {
       
    55 class generate_iec_c: public visitor_c {
       
    56   private:
       
    57     stage4out_c &s4o;
       
    58 
       
    59 
       
    60   public:
       
    61     generate_iec_c(stage4out_c *s4o_ptr): s4o(*s4o_ptr) {}
       
    62     ~generate_iec_c(void) {}
       
    63 
       
    64 
       
    65   private:
       
    66 
       
    67 void *print_token(token_c *token) {
       
    68   return s4o.print(token->value);
       
    69 }
       
    70 
       
    71 void *print_literal(symbol_c *type, symbol_c *value) {
       
    72   type->accept(*this);
       
    73   s4o.print("#");
       
    74   value->accept(*this);
       
    75   return NULL;
       
    76 }
       
    77 
       
    78 void *print_list(list_c *list,
       
    79 			       std::string pre_elem_str = "",
       
    80 			       std::string inter_elem_str = "",
       
    81 			       std::string post_elem_str = "") {
       
    82   if (list->n > 0) {
       
    83     s4o.print(pre_elem_str);
       
    84     list->elements[0]->accept(*this);
       
    85   }
       
    86 
       
    87   for(int i = 1; i < list->n; i++) {
       
    88     s4o.print(inter_elem_str);
       
    89     list->elements[i]->accept(*this);
       
    90   }
       
    91 
       
    92   if (list->n > 0)
       
    93     s4o.print(post_elem_str);
       
    94 
       
    95   return NULL;
       
    96 }
       
    97 
       
    98 
       
    99 void *print_binary_expression(symbol_c *l_exp,
       
   100 			      symbol_c *r_exp,
       
   101 			      const char *operation) {
       
   102   s4o.print("(");
       
   103   l_exp->accept(*this);
       
   104   s4o.print(operation);
       
   105   r_exp->accept(*this);
       
   106   s4o.print(")");
       
   107   return NULL;
       
   108 }
       
   109 
       
   110 void *print_unary_expression(symbol_c *exp,
       
   111 			     const char *operation) {
       
   112   s4o.print(operation);
       
   113   exp->accept(*this);
       
   114   return NULL;
       
   115 }
       
   116 
       
   117 
       
   118 
       
   119 
       
   120 
       
   121   public:
       
   122 /***************************/
       
   123 /* 2.1.6 Pragmas */
       
   124 /***************************/
       
   125 void *visit(pragma_c *symbol) {return print_token(symbol);}
       
   126 
       
   127 
       
   128 /***************************/
       
   129 /* B 0 - Programming Model */
       
   130 /***************************/
       
   131 void *visit(library_c *symbol) {return print_list(symbol);}
       
   132 
       
   133 /*******************************************/
       
   134 /* B 1.1 - Letters, digits and identifiers */
       
   135 /*******************************************/
       
   136 void *visit(identifier_c *symbol) {return print_token(symbol);}
       
   137 
       
   138 /*********************/
       
   139 /* B 1.2 - Constants */
       
   140 /*********************/
       
   141 
       
   142 /******************************/
       
   143 /* B 1.2.1 - Numeric Literals */
       
   144 /******************************/
       
   145 void *visit(real_c *symbol) {return print_token(symbol);}
       
   146 void *visit(integer_c *symbol) {return print_token(symbol);}
       
   147 void *visit(binary_integer_c *symbol) {return print_token(symbol);}
       
   148 void *visit(octal_integer_c *symbol) {return print_token(symbol);}
       
   149 void *visit(hex_integer_c *symbol) {return print_token(symbol);}
       
   150 
       
   151 void *visit(numeric_literal_c *symbol) {return print_literal(symbol->type, symbol->value);}
       
   152 void *visit(integer_literal_c *symbol) {return print_literal(symbol->type, symbol->value);}
       
   153 void *visit(real_literal_c *symbol) {return print_literal(symbol->type, symbol->value);}
       
   154 void *visit(bit_string_literal_c *symbol) {return print_literal(symbol->type, symbol->value);}
       
   155 void *visit(boolean_literal_c *symbol) {return print_literal(symbol->type, symbol->value);}
       
   156 
       
   157 /* helper class for boolean_literal_c */
       
   158 void *visit(boolean_true_c *symbol) {s4o.print(/*"TRUE"*/"1"); return NULL;}
       
   159 void *visit(boolean_false_c *symbol) {s4o.print(/*"FALSE"*/"0"); return NULL;}
       
   160 
       
   161 /*******************************/
       
   162 /* B.1.2.2   Character Strings */
       
   163 /*******************************/
       
   164 void *visit(double_byte_character_string_c *symbol) {return print_token(symbol);}
       
   165 void *visit(single_byte_character_string_c *symbol) {return print_token(symbol);}
       
   166 
       
   167 
       
   168 /***************************/
       
   169 /* B 1.2.3 - Time Literals */
       
   170 /***************************/
       
   171 
       
   172 /************************/
       
   173 /* B 1.2.3.1 - Duration */
       
   174 /************************/
       
   175 void *visit(neg_time_c *symbol) {s4o.print("-"); return NULL;}
       
   176 
       
   177 void *visit(duration_c *symbol) {
       
   178   s4o.print("TIME#");
       
   179   if (symbol->neg != NULL)
       
   180     symbol->neg->accept(*this);
       
   181   symbol->interval->accept(*this);
       
   182   return NULL;
       
   183 }
       
   184 
       
   185 void *visit(fixed_point_c *symbol) {return print_token(symbol);}
       
   186 
       
   187 void *visit(days_c *symbol) {
       
   188   symbol->days->accept(*this);
       
   189   s4o.print("d");
       
   190   if (symbol->hours != NULL)
       
   191     symbol->hours->accept(*this);
       
   192   return NULL;
       
   193 }
       
   194 
       
   195 void *visit(hours_c *symbol) {
       
   196   symbol->hours->accept(*this);
       
   197   s4o.print("h");
       
   198   if (symbol->minutes != NULL)
       
   199     symbol->minutes->accept(*this);
       
   200   return NULL;
       
   201 }
       
   202 
       
   203 void *visit(minutes_c *symbol) {
       
   204   symbol->minutes->accept(*this);
       
   205   s4o.print("m");
       
   206   if (symbol->seconds != NULL)
       
   207     symbol->seconds->accept(*this);
       
   208   return NULL;
       
   209 }
       
   210 
       
   211 void *visit(seconds_c *symbol) {
       
   212   symbol->seconds->accept(*this);
       
   213   s4o.print("s");
       
   214   if (symbol->milliseconds != NULL)
       
   215     symbol->milliseconds->accept(*this);
       
   216   return NULL;
       
   217 }
       
   218 
       
   219 void *visit(milliseconds_c *symbol) {
       
   220   symbol->milliseconds->accept(*this);
       
   221   s4o.print("ms");
       
   222   return NULL;
       
   223 }
       
   224 
       
   225 /************************************/
       
   226 /* B 1.2.3.2 - Time of day and Date */
       
   227 /************************************/
       
   228 
       
   229 void *visit(time_of_day_c *symbol) {
       
   230   s4o.print("TIME_OF_DAY#");
       
   231   symbol->daytime->accept(*this);
       
   232   return NULL;
       
   233 }
       
   234 
       
   235 void *visit(daytime_c *symbol) {
       
   236   symbol->day_hour->accept(*this);
       
   237   s4o.print(":");
       
   238   symbol->day_minute->accept(*this);
       
   239   s4o.print(":");
       
   240   symbol->day_second->accept(*this);
       
   241   return NULL;
       
   242 }
       
   243 
       
   244 
       
   245 void *visit(date_c *symbol) {
       
   246   s4o.print("DATE#");
       
   247   symbol->date_literal->accept(*this);
       
   248   return NULL;
       
   249 }
       
   250 
       
   251 void *visit(date_literal_c *symbol) {
       
   252   symbol->year->accept(*this);
       
   253   s4o.print("-");
       
   254   symbol->month->accept(*this);
       
   255   s4o.print("-");
       
   256   symbol->day->accept(*this);
       
   257   return NULL;
       
   258 }
       
   259 
       
   260 void *visit(date_and_time_c *symbol) {
       
   261   s4o.print("DATE_AND_TIME#");
       
   262   symbol->date_literal->accept(*this);
       
   263   s4o.print("-");
       
   264   symbol->daytime->accept(*this);
       
   265   return NULL;
       
   266 }
       
   267 
       
   268 
       
   269 
       
   270 /***********************************/
       
   271 /* B 1.3.1 - Elementary Data Types */
       
   272 /***********************************/
       
   273 void *visit(time_type_name_c *symbol) {s4o.print("TIME"); return NULL;}
       
   274 void *visit(bool_type_name_c *symbol) {s4o.print("BOOL"); return NULL;}
       
   275 void *visit(sint_type_name_c *symbol) {s4o.print("SINT"); return NULL;}
       
   276 void *visit(int_type_name_c *symbol) {s4o.print("INT"); return NULL;}
       
   277 void *visit(dint_type_name_c *symbol) {s4o.print("DINT"); return NULL;}
       
   278 void *visit(lint_type_name_c *symbol) {s4o.print("LINT"); return NULL;}
       
   279 void *visit(usint_type_name_c *symbol) {s4o.print("USINT"); return NULL;}
       
   280 void *visit(uint_type_name_c *symbol) {s4o.print("UINT"); return NULL;}
       
   281 void *visit(udint_type_name_c *symbol) {s4o.print("UDINT"); return NULL;}
       
   282 void *visit(ulint_type_name_c *symbol) {s4o.print("ULINT"); return NULL;}
       
   283 void *visit(real_type_name_c *symbol) {s4o.print("REAL"); return NULL;}
       
   284 void *visit(lreal_type_name_c *symbol) {s4o.print("LREAL"); return NULL;}
       
   285 void *visit(date_type_name_c *symbol) {s4o.print("DATE"); return NULL;}
       
   286 void *visit(tod_type_name_c *symbol) {s4o.print("TOD"); return NULL;}
       
   287 void *visit(dt_type_name_c *symbol) {s4o.print("DT"); return NULL;}
       
   288 void *visit(byte_type_name_c *symbol) {s4o.print("BYTE"); return NULL;}
       
   289 void *visit(word_type_name_c *symbol) {s4o.print("WORD"); return NULL;}
       
   290 void *visit(lword_type_name_c *symbol) {s4o.print("LWORD"); return NULL;}
       
   291 void *visit(dword_type_name_c *symbol) {s4o.print("DWORD"); return NULL;}
       
   292 void *visit(string_type_name_c *symbol) {s4o.print("STRING"); return NULL;}
       
   293 void *visit(wstring_type_name_c *symbol) {s4o.print("WSTRING"); return NULL;}
       
   294 
       
   295 
       
   296 
       
   297 /********************************/
       
   298 /* B 1.3.3 - Derived data types */
       
   299 /********************************/
       
   300 /*  TYPE type_declaration_list END_TYPE */
       
   301 void *visit(data_type_declaration_c *symbol) {
       
   302   s4o.print("TYPE\n");
       
   303   s4o.indent_right();
       
   304   symbol->type_declaration_list->accept(*this);
       
   305   s4o.indent_left();
       
   306   s4o.print("END_TYPE\n\n\n");
       
   307   return NULL;
       
   308 }
       
   309 
       
   310 
       
   311 /* helper symbol for data_type_declaration */
       
   312 /*| type_declaration_list type_declaration ';' */
       
   313 void *visit(type_declaration_list_c *symbol) {
       
   314   return print_list(symbol, s4o.indent_spaces, ";\n" + s4o.indent_spaces, ";\n");
       
   315 }
       
   316 
       
   317 
       
   318 /*  simple_type_name ':' simple_spec_init */
       
   319 void *visit(simple_type_declaration_c *symbol) {
       
   320   symbol->simple_type_name->accept(*this);
       
   321   s4o.print(" : ");
       
   322   symbol->simple_spec_init->accept(*this);
       
   323   return NULL;
       
   324 }
       
   325 
       
   326 /* simple_specification ASSIGN constant */
       
   327 void *visit(simple_spec_init_c *symbol) {
       
   328   symbol->simple_specification->accept(*this);
       
   329   if (symbol->constant != NULL) {
       
   330     s4o.print(" := ");
       
   331     symbol->constant->accept(*this);
       
   332   }
       
   333   return NULL;
       
   334 }
       
   335 
       
   336 /*  subrange_type_name ':' subrange_spec_init */
       
   337 void *visit(subrange_type_declaration_c *symbol) {
       
   338   symbol->subrange_type_name->accept(*this);
       
   339   s4o.print(" : ");
       
   340   symbol->subrange_spec_init->accept(*this);
       
   341   return NULL;
       
   342 }
       
   343 
       
   344 /* subrange_specification ASSIGN signed_integer */
       
   345 void *visit(subrange_spec_init_c *symbol) {
       
   346   symbol->subrange_specification->accept(*this);
       
   347   if (symbol->signed_integer != NULL) {
       
   348     s4o.print(" := ");
       
   349     symbol->signed_integer->accept(*this);
       
   350   }
       
   351   return NULL;
       
   352 }
       
   353 
       
   354 /*  integer_type_name '(' subrange')' */
       
   355 void *visit(subrange_specification_c *symbol) {
       
   356   symbol->integer_type_name->accept(*this);
       
   357   s4o.print("(");
       
   358   symbol->subrange->accept(*this);
       
   359   s4o.print(")");
       
   360   return NULL;
       
   361 }
       
   362 
       
   363 /*  signed_integer DOTDOT signed_integer */
       
   364 void *visit(subrange_c *symbol) {
       
   365   symbol->lower_limit->accept(*this);
       
   366   s4o.print(" .. ");
       
   367   symbol->upper_limit->accept(*this);
       
   368   return NULL;
       
   369 }
       
   370 
       
   371 /*  enumerated_type_name ':' enumerated_spec_init */
       
   372 void *visit(enumerated_type_declaration_c *symbol) {
       
   373   symbol->enumerated_type_name->accept(*this);
       
   374   s4o.print(" : ");
       
   375   symbol->enumerated_spec_init->accept(*this);
       
   376   return NULL;
       
   377 }
       
   378 
       
   379 /* enumerated_specification ASSIGN enumerated_value */
       
   380 void *visit(enumerated_spec_init_c *symbol) {
       
   381   symbol->enumerated_specification->accept(*this);
       
   382   if (symbol->enumerated_value != NULL) {
       
   383     s4o.print(" := ");
       
   384     symbol->enumerated_value->accept(*this);
       
   385   }
       
   386   return NULL;
       
   387 }
       
   388 
       
   389 /* helper symbol for enumerated_specification->enumerated_spec_init */
       
   390 /* enumerated_value_list ',' enumerated_value */
       
   391 void *visit(enumerated_value_list_c *symbol) {print_list(symbol, "(", ", ", ")"); return NULL;}
       
   392 
       
   393 /* enumerated_type_name '#' identifier */
       
   394 void *visit(enumerated_value_c *symbol) {
       
   395   symbol->type->accept(*this);
       
   396   s4o.print("#");
       
   397   symbol->value->accept(*this);
       
   398   return NULL;
       
   399 }
       
   400 
       
   401 /*  identifier ':' array_spec_init */
       
   402 void *visit(array_type_declaration_c *symbol) {
       
   403   symbol->identifier->accept(*this);
       
   404   s4o.print(" : ");
       
   405   symbol->array_spec_init->accept(*this);
       
   406   return NULL;
       
   407 }
       
   408 
       
   409 /* array_specification [ASSIGN array_initialization} */
       
   410 /* array_initialization may be NULL ! */
       
   411 void *visit(array_spec_init_c *symbol) {
       
   412   symbol->array_specification->accept(*this);
       
   413   if (symbol->array_initialization != NULL) {
       
   414     s4o.print(" := ");
       
   415     symbol->array_initialization->accept(*this);
       
   416   }
       
   417   return NULL;
       
   418 }
       
   419 
       
   420 /* ARRAY '[' array_subrange_list ']' OF non_generic_type_name */
       
   421 void *visit(array_specification_c *symbol) {
       
   422   s4o.print("ARRAY [");
       
   423   symbol->array_subrange_list->accept(*this);
       
   424   s4o.print("] OF ");
       
   425   symbol->non_generic_type_name->accept(*this);
       
   426   return NULL;
       
   427 }
       
   428 
       
   429 /* helper symbol for array_specification */
       
   430 /* array_subrange_list ',' subrange */
       
   431 void *visit(array_subrange_list_c *symbol) {print_list(symbol, "", ", "); return NULL;}
       
   432 
       
   433 /* helper symbol for array_initialization */
       
   434 /* array_initial_elements_list ',' array_initial_elements */
       
   435 void *visit(array_initial_elements_list_c *symbol) {print_list(symbol, "[", ", ", "]"); return NULL;}
       
   436 
       
   437 /* integer '(' [array_initial_element] ')' */
       
   438 /* array_initial_element may be NULL ! */
       
   439 void *visit(array_initial_elements_c *symbol) {
       
   440   symbol->integer->accept(*this);
       
   441   s4o.print("(");
       
   442   if (symbol->array_initial_element != NULL)
       
   443     symbol->array_initial_element->accept(*this);
       
   444   s4o.print(")");
       
   445   return NULL;
       
   446 }
       
   447 
       
   448 /*  structure_type_name ':' structure_specification */
       
   449 void *visit(structure_type_declaration_c *symbol) {
       
   450   symbol->structure_type_name->accept(*this);
       
   451   s4o.print(" : ");
       
   452   symbol->structure_specification->accept(*this);
       
   453   return NULL;
       
   454 }
       
   455 
       
   456 /* structure_type_name ASSIGN structure_initialization */
       
   457 /* structure_initialization may be NULL ! */
       
   458 void *visit(initialized_structure_c *symbol) {
       
   459   symbol->structure_type_name->accept(*this);
       
   460   if (symbol->structure_initialization != NULL) {
       
   461     s4o.print(" := ");
       
   462     symbol->structure_initialization->accept(*this);
       
   463   }
       
   464   return NULL;
       
   465 }
       
   466 
       
   467 /* helper symbol for structure_declaration */
       
   468 /* structure_declaration:  STRUCT structure_element_declaration_list END_STRUCT */
       
   469 /* structure_element_declaration_list structure_element_declaration ';' */
       
   470 void *visit(structure_element_declaration_list_c *symbol) {
       
   471   s4o.print("STRUCT\n");
       
   472   s4o.indent_right();
       
   473   print_list(symbol, s4o.indent_spaces, ";\n" + s4o.indent_spaces, ";\n" + s4o.indent_spaces);
       
   474   s4o.print("END_STRUCT");
       
   475   s4o.indent_left();
       
   476   return NULL;
       
   477 }
       
   478 
       
   479 /*  structure_element_name ':' *_spec_init */
       
   480 void *visit(structure_element_declaration_c *symbol) {
       
   481   symbol->structure_element_name->accept(*this);
       
   482   s4o.print(" : ");
       
   483   symbol->spec_init->accept(*this);
       
   484   return NULL;
       
   485 }
       
   486 
       
   487 /* helper symbol for structure_initialization */
       
   488 /* structure_initialization: '(' structure_element_initialization_list ')' */
       
   489 /* structure_element_initialization_list ',' structure_element_initialization */
       
   490 void *visit(structure_element_initialization_list_c *symbol) {print_list(symbol, "(", ", ", ")"); return NULL;}
       
   491 
       
   492 /*  structure_element_name ASSIGN value */
       
   493 void *visit(structure_element_initialization_c *symbol) {
       
   494   symbol->structure_element_name->accept(*this);
       
   495   s4o.print(" := ");
       
   496   symbol->value->accept(*this);
       
   497   return NULL;
       
   498 }
       
   499 
       
   500 /*  string_type_name ':' elementary_string_type_name string_type_declaration_size string_type_declaration_init */
       
   501 void *visit(string_type_declaration_c *symbol) {
       
   502   symbol->string_type_name->accept(*this);
       
   503   s4o.print(" : ");
       
   504   symbol->elementary_string_type_name->accept(*this);
       
   505   symbol->string_type_declaration_size->accept(*this);
       
   506   if (symbol->string_type_declaration_init != NULL)
       
   507     symbol->string_type_declaration_init->accept(*this);
       
   508   return NULL;
       
   509 }
       
   510 
       
   511 
       
   512 
       
   513 
       
   514 
       
   515 /*********************/
       
   516 /* B 1.4 - Variables */
       
   517 /*********************/
       
   518 void *visit(symbolic_variable_c *symbol) {
       
   519   symbol->var_name->accept(*this);
       
   520   return NULL;
       
   521 }
       
   522 
       
   523 /********************************************/
       
   524 /* B.1.4.1   Directly Represented Variables */
       
   525 /********************************************/
       
   526 void *visit(direct_variable_c *symbol) {return print_token(symbol);}
       
   527 
       
   528 
       
   529 /*************************************/
       
   530 /* B.1.4.2   Multi-element Variables */
       
   531 /*************************************/
       
   532 /*  subscripted_variable '[' subscript_list ']' */
       
   533 void *visit(array_variable_c *symbol) {
       
   534   symbol->subscripted_variable->accept(*this);
       
   535   s4o.print("[");
       
   536   symbol->subscript_list->accept(*this);
       
   537   s4o.print("]");
       
   538   return NULL;
       
   539 }
       
   540 
       
   541 
       
   542 /* subscript_list ',' subscript */
       
   543 void *visit(subscript_list_c *symbol) {return print_list(symbol, "", ", ");}
       
   544 
       
   545 /*  record_variable '.' field_selector */
       
   546 void *visit(structured_variable_c *symbol) {
       
   547   symbol->record_variable->accept(*this);
       
   548   s4o.print(".");
       
   549   symbol->field_selector->accept(*this);
       
   550   return NULL;
       
   551 }
       
   552 
       
   553 
       
   554 /******************************************/
       
   555 /* B 1.4.3 - Declaration & Initialisation */
       
   556 /******************************************/
       
   557 void *visit(constant_option_c *symbol) {s4o.print("CONSTANT"); return NULL;}
       
   558 void *visit(retain_option_c *symbol) {s4o.print("RETAIN"); return NULL;}
       
   559 void *visit(non_retain_option_c *symbol) {s4o.print("NON_RETAIN"); return NULL;}
       
   560 
       
   561 /* VAR_INPUT [RETAIN | NON_RETAIN] input_declaration_list END_VAR */
       
   562 /* option -> the RETAIN/NON_RETAIN/<NULL> directive... */
       
   563 void *visit(input_declarations_c *symbol) {
       
   564   s4o.print(s4o.indent_spaces); s4o.print("VAR_INPUT ");
       
   565   if (symbol->option != NULL)
       
   566     symbol->option->accept(*this);
       
   567   s4o.print("\n");
       
   568   s4o.indent_right();
       
   569   symbol->input_declaration_list->accept(*this);
       
   570   s4o.indent_left();
       
   571   s4o.print(s4o.indent_spaces); s4o.print("END_VAR\n");
       
   572   return NULL;
       
   573 }
       
   574 
       
   575 /* helper symbol for input_declarations */
       
   576 /*| input_declaration_list input_declaration ';' */
       
   577 void *visit(input_declaration_list_c *symbol) {
       
   578   return print_list(symbol, s4o.indent_spaces, ";\n" + s4o.indent_spaces, ";\n");
       
   579 }
       
   580 
       
   581 /* edge -> The F_EDGE or R_EDGE directive */
       
   582 void *visit(edge_declaration_c *symbol) {
       
   583   symbol->var1_list->accept(*this);
       
   584   s4o.print(" : BOOL ");
       
   585   symbol->edge->accept(*this);
       
   586   return NULL;
       
   587 }
       
   588 
       
   589 
       
   590 void *visit(raising_edge_option_c *symbol) {
       
   591   s4o.print("R_EDGE");
       
   592   return NULL;
       
   593 }
       
   594 
       
   595 void *visit(falling_edge_option_c *symbol) {
       
   596   s4o.print("F_EDGE");
       
   597   return NULL;
       
   598 }
       
   599 
       
   600 
       
   601 /* var1_list is one of the following...
       
   602  *    simple_spec_init_c *
       
   603  *    subrange_spec_init_c *
       
   604  *    enumerated_spec_init_c *
       
   605  */
       
   606 void *visit(var1_init_decl_c *symbol) {
       
   607   symbol->var1_list->accept(*this);
       
   608   s4o.print(" : ");
       
   609   symbol->spec_init->accept(*this);
       
   610   return NULL;
       
   611 }
       
   612 
       
   613 
       
   614 void *visit(var1_list_c *symbol) {return print_list(symbol, "", ", ");}
       
   615 
       
   616 
       
   617 /* var1_list ':' array_spec_init */
       
   618 void *visit(array_var_init_decl_c *symbol) {
       
   619   symbol->var1_list->accept(*this);
       
   620   s4o.print(" : ");
       
   621   symbol->array_spec_init->accept(*this);
       
   622   return NULL;
       
   623 }
       
   624 
       
   625 
       
   626 /*  var1_list ':' initialized_structure */
       
   627 void *visit(structured_var_init_decl_c *symbol) {
       
   628   symbol->var1_list->accept(*this);
       
   629   s4o.print(" : ");
       
   630   symbol->initialized_structure->accept(*this);
       
   631   return NULL;
       
   632 }
       
   633 
       
   634 /* name_list ':' function_block_type_name ASSIGN structure_initialization */
       
   635 /* structure_initialization -> may be NULL ! */
       
   636 void *visit(fb_name_decl_c *symbol) {
       
   637   symbol->fb_name_list->accept(*this);
       
   638   s4o.print(" : ");
       
   639   symbol->function_block_type_name->accept(*this);
       
   640   if (symbol->structure_initialization != NULL) {
       
   641     s4o.print(" := ");
       
   642     symbol->structure_initialization->accept(*this);
       
   643   }
       
   644   return NULL;
       
   645 }
       
   646 
       
   647 /* name_list ',' fb_name */
       
   648 void *visit(fb_name_list_c *symbol) {return print_list(symbol, "", ", ");}
       
   649 
       
   650 /* VAR_OUTPUT [RETAIN | NON_RETAIN] var_init_decl_list END_VAR */
       
   651 /* option -> may be NULL ! */
       
   652 void *visit(output_declarations_c *symbol) {
       
   653   s4o.print(s4o.indent_spaces); s4o.print("VAR_OUTPUT ");
       
   654   if (symbol->option != NULL)
       
   655     symbol->option->accept(*this);
       
   656   s4o.print("\n");
       
   657   s4o.indent_right();
       
   658   symbol->var_init_decl_list->accept(*this);
       
   659   s4o.indent_left();
       
   660   s4o.print(s4o.indent_spaces); s4o.print("END_VAR\n");
       
   661   return NULL;
       
   662 }
       
   663 
       
   664 /*  VAR_IN_OUT  END_VAR */
       
   665 void *visit(input_output_declarations_c *symbol) {
       
   666   s4o.print(s4o.indent_spaces); s4o.print("VAR_IN_OUT ");
       
   667   s4o.print("\n");
       
   668   s4o.indent_right();
       
   669   symbol->var_declaration_list->accept(*this);
       
   670   s4o.indent_left();
       
   671   s4o.print(s4o.indent_spaces); s4o.print("END_VAR\n");
       
   672   return NULL;
       
   673 }
       
   674 
       
   675 /* helper symbol for input_output_declarations */
       
   676 /* var_declaration_list var_declaration ';' */
       
   677 void *visit(var_declaration_list_c *symbol) {
       
   678   return print_list(symbol, s4o.indent_spaces, ";\n" + s4o.indent_spaces, ";\n");
       
   679 }
       
   680 
       
   681 /*  var1_list ':' array_specification */
       
   682 void *visit(array_var_declaration_c *symbol) {
       
   683   symbol->var1_list->accept(*this);
       
   684   s4o.print(" : ");
       
   685   symbol->array_specification->accept(*this);
       
   686   return NULL;
       
   687 }
       
   688 
       
   689 /*  var1_list ':' structure_type_name */
       
   690 void *visit(structured_var_declaration_c *symbol) {
       
   691   symbol->var1_list->accept(*this);
       
   692   s4o.print(" : ");
       
   693   symbol->structure_type_name->accept(*this);
       
   694   return NULL;
       
   695 }
       
   696 
       
   697 /* VAR [CONSTANT] var_init_decl_list END_VAR */
       
   698 /* option -> may be NULL ! */
       
   699 void *visit(var_declarations_c *symbol) {
       
   700   s4o.print(s4o.indent_spaces); s4o.print("VAR ");
       
   701   if (symbol->option != NULL)
       
   702     symbol->option->accept(*this);
       
   703   s4o.print("\n");
       
   704   s4o.indent_right();
       
   705   symbol->var_init_decl_list->accept(*this);
       
   706   s4o.indent_left();
       
   707   s4o.print(s4o.indent_spaces); s4o.print("END_VAR\n");
       
   708   return NULL;
       
   709 }
       
   710 
       
   711 /*  VAR RETAIN var_init_decl_list END_VAR */
       
   712 void *visit(retentive_var_declarations_c *symbol) {
       
   713   s4o.print(s4o.indent_spaces); s4o.print("VAR RETAIN ");
       
   714   s4o.print("\n");
       
   715   s4o.indent_right();
       
   716   symbol->var_init_decl_list->accept(*this);
       
   717   s4o.indent_left();
       
   718   s4o.print(s4o.indent_spaces); s4o.print("END_VAR\n");
       
   719   return NULL;
       
   720 }
       
   721 
       
   722 /*  VAR [CONSTANT|RETAIN|NON_RETAIN] located_var_decl_list END_VAR */
       
   723 /* option -> may be NULL ! */
       
   724 void *visit(located_var_declarations_c *symbol) {
       
   725   s4o.print(s4o.indent_spaces); s4o.print("VAR ");
       
   726   if (symbol->option != NULL)
       
   727     symbol->option->accept(*this);
       
   728   s4o.print("\n");
       
   729   s4o.indent_right();
       
   730   symbol->located_var_decl_list->accept(*this);
       
   731   s4o.indent_left();
       
   732   s4o.print(s4o.indent_spaces); s4o.print("END_VAR\n");
       
   733   return NULL;
       
   734 }
       
   735 
       
   736 /* helper symbol for located_var_declarations */
       
   737 /* located_var_decl_list located_var_decl ';' */
       
   738 void *visit(located_var_decl_list_c *symbol) {
       
   739   return print_list(symbol, s4o.indent_spaces, ";\n" + s4o.indent_spaces, ";\n");
       
   740 }
       
   741 
       
   742 /*  [variable_name] location ':' located_var_spec_init */
       
   743 /* variable_name -> may be NULL ! */
       
   744 void *visit(located_var_decl_c *symbol) {
       
   745   if (symbol->variable_name != NULL) {
       
   746     symbol->variable_name->accept(*this);
       
   747     s4o.print(" ");
       
   748   }
       
   749   symbol->location->accept(*this);
       
   750   s4o.print(" : ");
       
   751   symbol->located_var_spec_init->accept(*this);
       
   752   return NULL;
       
   753 }
       
   754 
       
   755 
       
   756 /*| VAR_EXTERNAL [CONSTANT] external_declaration_list END_VAR */
       
   757 /* option -> may be NULL ! */
       
   758 void *visit(external_var_declarations_c *symbol) {
       
   759   s4o.print(s4o.indent_spaces); s4o.print("VAR_EXTERNAL ");
       
   760   if (symbol->option != NULL)
       
   761     symbol->option->accept(*this);
       
   762   s4o.print("\n");
       
   763   s4o.indent_right();
       
   764   symbol->external_declaration_list->accept(*this);
       
   765   s4o.indent_left();
       
   766   s4o.print(s4o.indent_spaces); s4o.print("END_VAR\n");
       
   767   return NULL;
       
   768 }
       
   769 
       
   770 /* helper symbol for external_var_declarations */
       
   771 /*| external_declaration_list external_declaration';' */
       
   772 void *visit(external_declaration_list_c *symbol) {
       
   773   return print_list(symbol, s4o.indent_spaces, ";\n" + s4o.indent_spaces, ";\n");
       
   774 }
       
   775 
       
   776 /*  global_var_name ':' (simple_specification|subrange_specification|enumerated_specification|array_specification|prev_declared_structure_type_name|function_block_type_name) */
       
   777 void *visit(external_declaration_c *symbol) {
       
   778   symbol->global_var_name->accept(*this);
       
   779   s4o.print(" : ");
       
   780   symbol->specification->accept(*this);
       
   781   return NULL;
       
   782 }
       
   783 
       
   784 /*| VAR_GLOBAL [CONSTANT|RETAIN] global_var_decl_list END_VAR */
       
   785 /* option -> may be NULL ! */
       
   786 void *visit(global_var_declarations_c *symbol) {
       
   787   s4o.print(s4o.indent_spaces); s4o.print("VAR_GLOBAL ");
       
   788   if (symbol->option != NULL)
       
   789     symbol->option->accept(*this);
       
   790   s4o.print("\n");
       
   791   s4o.indent_right();
       
   792   symbol->global_var_decl_list->accept(*this);
       
   793   s4o.indent_left();
       
   794   s4o.print(s4o.indent_spaces); s4o.print("END_VAR\n");
       
   795   return NULL;
       
   796 }
       
   797 
       
   798 /* helper symbol for global_var_declarations */
       
   799 /*| global_var_decl_list global_var_decl ';' */
       
   800 void *visit(global_var_decl_list_c *symbol) {
       
   801   return print_list(symbol, s4o.indent_spaces, ";\n" + s4o.indent_spaces, ";\n");
       
   802 }
       
   803 
       
   804 /*| global_var_spec ':' [located_var_spec_init|function_block_type_name] */
       
   805 /* type_specification ->may be NULL ! */
       
   806 void *visit(global_var_decl_c *symbol) {
       
   807   symbol->global_var_spec->accept(*this);
       
   808   s4o.print(" : ");
       
   809   if (symbol->type_specification != NULL)
       
   810     symbol->type_specification->accept(*this);
       
   811   return NULL;
       
   812 }
       
   813 
       
   814 /*| global_var_name location */
       
   815 void *visit(global_var_spec_c *symbol) {
       
   816   symbol->global_var_name->accept(*this);
       
   817   s4o.print(" ");
       
   818   symbol->location->accept(*this);
       
   819   return NULL;
       
   820 }
       
   821 
       
   822 /*  AT direct_variable */
       
   823 void *visit(location_c *symbol) {
       
   824   s4o.print("AT ");
       
   825   symbol->direct_variable->accept(*this);
       
   826   return NULL;
       
   827 }
       
   828 
       
   829 /*| global_var_list ',' global_var_name */
       
   830 void *visit(global_var_list_c *symbol) {return print_list(symbol, "", ", ");}
       
   831 
       
   832 /*  var1_list ':' single_byte_string_spec */
       
   833 void *visit(single_byte_string_var_declaration_c *symbol) {
       
   834   symbol->var1_list->accept(*this);
       
   835   s4o.print(" : ");
       
   836   symbol->single_byte_string_spec->accept(*this);
       
   837   return NULL;
       
   838 }
       
   839 
       
   840 /*  STRING ['[' integer ']'] [ASSIGN single_byte_character_string] */
       
   841 /* integer ->may be NULL ! */
       
   842 /* single_byte_character_string ->may be NULL ! */
       
   843 void *visit(single_byte_string_spec_c *symbol) {
       
   844   s4o.print("STRING [");
       
   845   if (symbol->integer != NULL)
       
   846     symbol->integer->accept(*this);
       
   847   s4o.print("]");
       
   848   if (symbol->single_byte_character_string != NULL) {
       
   849     s4o.print(" := ");
       
   850     symbol->single_byte_character_string->accept(*this);
       
   851   }
       
   852   return NULL;
       
   853 }
       
   854 
       
   855 /*  var1_list ':' double_byte_string_spec */
       
   856 void *visit(double_byte_string_var_declaration_c *symbol) {
       
   857   symbol->var1_list->accept(*this);
       
   858   s4o.print(" : ");
       
   859   symbol->double_byte_string_spec->accept(*this);
       
   860   return NULL;
       
   861 }
       
   862 
       
   863 /*  WSTRING ['[' integer ']'] [ASSIGN double_byte_character_string] */
       
   864 /* integer ->may be NULL ! */
       
   865 /* double_byte_character_string ->may be NULL ! */
       
   866 void *visit(double_byte_string_spec_c *symbol) {
       
   867   s4o.print("WSTRING [");
       
   868   if (symbol->integer != NULL)
       
   869     symbol->integer->accept(*this);
       
   870   s4o.print("]");
       
   871   if (symbol->double_byte_character_string != NULL) {
       
   872     s4o.print(" := ");
       
   873     symbol->double_byte_character_string->accept(*this);
       
   874   }
       
   875   return NULL;
       
   876 }
       
   877 
       
   878 /*| VAR [RETAIN|NON_RETAIN] incompl_located_var_decl_list END_VAR */
       
   879 /* option ->may be NULL ! */
       
   880 void *visit(incompl_located_var_declarations_c *symbol) {
       
   881   s4o.print(s4o.indent_spaces); s4o.print("VAR ");
       
   882   if (symbol->option != NULL)
       
   883     symbol->option->accept(*this);
       
   884   s4o.print("\n");
       
   885   s4o.indent_right();
       
   886   symbol->incompl_located_var_decl_list->accept(*this);
       
   887   s4o.indent_left();
       
   888   s4o.print(s4o.indent_spaces); s4o.print("END_VAR\n");
       
   889   return NULL;
       
   890 }
       
   891 
       
   892 /* helper symbol for incompl_located_var_declarations */
       
   893 /*| incompl_located_var_decl_list incompl_located_var_decl ';' */
       
   894 void *visit(incompl_located_var_decl_list_c *symbol) {
       
   895   return print_list(symbol, s4o.indent_spaces, ";\n" + s4o.indent_spaces, ";\n");
       
   896 }
       
   897 
       
   898 /*  variable_name incompl_location ':' var_spec */
       
   899 void *visit(incompl_located_var_decl_c *symbol) {
       
   900   symbol->variable_name->accept(*this);
       
   901   s4o.print(" ");
       
   902   symbol->incompl_location->accept(*this);
       
   903   s4o.print(" : ");
       
   904   symbol->var_spec->accept(*this);
       
   905   return NULL;
       
   906 }
       
   907 
       
   908 
       
   909 /*  AT incompl_location_token */
       
   910 void *visit(incompl_location_c *symbol) {
       
   911   s4o.print(" AT ");
       
   912   return print_token(symbol);;
       
   913 }
       
   914 
       
   915 
       
   916 /* intermediate helper symbol for:
       
   917  *  - non_retentive_var_decls
       
   918  *  - output_declarations
       
   919  */
       
   920 /* | var_init_decl_list var_init_decl ';' */
       
   921 void *visit(var_init_decl_list_c *symbol) {
       
   922   return print_list(symbol, s4o.indent_spaces, ";\n" + s4o.indent_spaces, ";\n");
       
   923 }
       
   924 
       
   925 
       
   926 /***********************/
       
   927 /* B 1.5.1 - Functions */
       
   928 /***********************/
       
   929 void *visit(function_declaration_c *symbol) {
       
   930   s4o.print("FUNCTION ");
       
   931   symbol->derived_function_name->accept(*this);
       
   932   s4o.print(" : ");
       
   933   symbol->type_name->accept(*this);
       
   934   s4o.print("\n");
       
   935   s4o.indent_right();
       
   936   symbol->var_declarations_list->accept(*this);
       
   937   s4o.print("\n");
       
   938   symbol->function_body->accept(*this);
       
   939   s4o.indent_left();
       
   940   s4o.print(s4o.indent_spaces + "END_FUNCTION\n\n\n");
       
   941   return NULL;
       
   942 }
       
   943 
       
   944 /* intermediate helper symbol for function_declaration */
       
   945 void *visit(var_declarations_list_c *symbol) {return print_list(symbol);}
       
   946 
       
   947 void *visit(function_var_decls_c *symbol) {
       
   948   s4o.print(s4o.indent_spaces); s4o.print("VAR ");
       
   949   if (symbol->option != NULL)
       
   950     symbol->option->accept(*this);
       
   951   s4o.print("\n");
       
   952   s4o.indent_right();
       
   953   symbol->decl_list->accept(*this);
       
   954   s4o.indent_left();
       
   955   s4o.print(s4o.indent_spaces); s4o.print("END_VAR\n");
       
   956   return NULL;
       
   957 }
       
   958 
       
   959 /* intermediate helper symbol for function_var_decls */
       
   960 void *visit(var2_init_decl_list_c *symbol) {
       
   961   print_list(symbol, s4o.indent_spaces, ";\n" + s4o.indent_spaces, ";\n");
       
   962   return NULL;
       
   963 }
       
   964 
       
   965 /*****************************/
       
   966 /* B 1.5.2 - Function Blocks */
       
   967 /*****************************/
       
   968 /*  FUNCTION_BLOCK derived_function_block_name io_OR_other_var_declarations function_block_body END_FUNCTION_BLOCK */
       
   969 void *visit(function_block_declaration_c *symbol) {
       
   970   s4o.print("FUNCTION_BLOCK ");
       
   971   symbol->fblock_name->accept(*this);
       
   972   s4o.print("\n");
       
   973   s4o.indent_right();
       
   974   symbol->var_declarations->accept(*this);
       
   975   s4o.print("\n");
       
   976   symbol->fblock_body->accept(*this);
       
   977   s4o.indent_left();
       
   978   s4o.print(s4o.indent_spaces + "END_FUNCTION_BLOCK\n\n\n");
       
   979   return NULL;
       
   980 }
       
   981 
       
   982 /*  VAR_TEMP temp_var_decl_list END_VAR */
       
   983 void *visit(temp_var_decls_c *symbol) {
       
   984   s4o.print("VAR_TEMP\n");
       
   985   s4o.indent_right();
       
   986   symbol->var_decl_list->accept(*this);
       
   987   s4o.indent_left();
       
   988   s4o.print("END_VAR\n");
       
   989   return NULL;
       
   990 }
       
   991 
       
   992 /* intermediate helper symbol for temp_var_decls */
       
   993 void *visit(temp_var_decls_list_c *symbol) {return print_list(symbol);}
       
   994 
       
   995 /*  VAR NON_RETAIN var_init_decl_list END_VAR */
       
   996 void *visit(non_retentive_var_decls_c *symbol) {
       
   997   s4o.print("VAR NON_RETAIN\n");
       
   998   s4o.indent_right();
       
   999   symbol->var_decl_list->accept(*this);
       
  1000   s4o.indent_left();
       
  1001   s4o.print("END_VAR\n");
       
  1002   return NULL;
       
  1003 }
       
  1004 
       
  1005 
       
  1006 /**********************/
       
  1007 /* B 1.5.3 - Programs */
       
  1008 /**********************/
       
  1009 /*  PROGRAM program_type_name program_var_declarations_list function_block_body END_PROGRAM */
       
  1010 void *visit(program_declaration_c *symbol) {
       
  1011   s4o.print("PROGRAM ");
       
  1012   symbol->program_type_name->accept(*this);
       
  1013   s4o.print("\n");
       
  1014   s4o.indent_right();
       
  1015   symbol->var_declarations->accept(*this);
       
  1016   s4o.print("\n");
       
  1017   symbol->function_block_body->accept(*this);
       
  1018   s4o.indent_left();
       
  1019   s4o.print(s4o.indent_spaces + "END_PROGRAM\n\n\n");
       
  1020   return NULL;
       
  1021 }
       
  1022 
       
  1023 
       
  1024 
       
  1025 /********************************/
       
  1026 /* B 1.7 Configuration elements */
       
  1027 /********************************/
       
  1028 /*
       
  1029 CONFIGURATION configuration_name
       
  1030    optional_global_var_declarations
       
  1031    (resource_declaration_list | single_resource_declaration)
       
  1032    optional_access_declarations
       
  1033    optional_instance_specific_initializations
       
  1034 END_CONFIGURATION
       
  1035 */
       
  1036 void *visit(configuration_declaration_c *symbol) {
       
  1037   s4o.print("CONFIGURATION ");
       
  1038   symbol->configuration_name->accept(*this);
       
  1039   s4o.print("\n");
       
  1040   s4o.indent_right();
       
  1041   if (symbol->global_var_declarations != NULL)
       
  1042     symbol->global_var_declarations->accept(*this);
       
  1043   symbol->resource_declarations->accept(*this);
       
  1044   if (symbol->access_declarations != NULL)
       
  1045     symbol->access_declarations->accept(*this);
       
  1046   if (symbol->instance_specific_initializations != NULL)
       
  1047     symbol->instance_specific_initializations->accept(*this);
       
  1048   s4o.indent_left();
       
  1049   s4o.print(s4o.indent_spaces + "END_CONFIGURATION\n\n\n");
       
  1050   return NULL;
       
  1051 }
       
  1052 
       
  1053 
       
  1054 /* helper symbol for configuration_declaration */
       
  1055 /*| resource_declaration_list resource_declaration */
       
  1056 void *visit(resource_declaration_list_c *symbol) {return print_list(symbol);}
       
  1057 
       
  1058 
       
  1059 /*
       
  1060 RESOURCE resource_name ON resource_type_name
       
  1061    optional_global_var_declarations
       
  1062    single_resource_declaration
       
  1063 END_RESOURCE
       
  1064 */
       
  1065 void *visit(resource_declaration_c *symbol) {
       
  1066   s4o.print(s4o.indent_spaces + "RESOURCE ");
       
  1067   symbol->resource_name->accept(*this);
       
  1068   s4o.print(" ON ");
       
  1069   symbol->resource_type_name->accept(*this);
       
  1070   s4o.print("\n");
       
  1071   s4o.indent_right();
       
  1072   if (symbol->global_var_declarations != NULL)
       
  1073     symbol->global_var_declarations->accept(*this);
       
  1074   symbol->resource_declaration->accept(*this);
       
  1075   s4o.indent_left();
       
  1076   s4o.print(s4o.indent_spaces + "END_RESOURCE\n");
       
  1077   return NULL;
       
  1078 }
       
  1079 
       
  1080 
       
  1081 /* task_configuration_list program_configuration_list */
       
  1082 void *visit(single_resource_declaration_c *symbol) {
       
  1083   symbol->task_configuration_list->accept(*this);
       
  1084   symbol->program_configuration_list->accept(*this);
       
  1085   return NULL;
       
  1086 }
       
  1087 
       
  1088 /* helper symbol for single_resource_declaration */
       
  1089 /*| task_configuration_list task_configuration ';'*/
       
  1090 void *visit(task_configuration_list_c *symbol) {
       
  1091   return print_list(symbol, s4o.indent_spaces, ";\n" + s4o.indent_spaces, ";\n");
       
  1092 }
       
  1093 
       
  1094 
       
  1095 /* helper symbol for single_resource_declaration */
       
  1096 /*| program_configuration_list program_configuration ';'*/
       
  1097 void *visit(program_configuration_list_c *symbol) {
       
  1098   return print_list(symbol, s4o.indent_spaces, ";\n" + s4o.indent_spaces, ";\n");
       
  1099 }
       
  1100 
       
  1101 
       
  1102 /* helper symbol for
       
  1103  *  - access_path
       
  1104  *  - instance_specific_init
       
  1105  */
       
  1106 /* | any_fb_name_list any_identifier '.'*/
       
  1107 void *visit(any_fb_name_list_c *symbol) {return print_list(symbol, ".", ".");}
       
  1108 
       
  1109 
       
  1110 /*  [resource_name '.'] global_var_name ['.' structure_element_name] */
       
  1111 void *visit(global_var_reference_c *symbol) {
       
  1112   if (symbol->resource_name != NULL) {
       
  1113     symbol->resource_name->accept(*this);
       
  1114     s4o.print(".");
       
  1115   }
       
  1116   symbol->global_var_name->accept(*this);
       
  1117   if (symbol->structure_element_name != NULL) {
       
  1118     s4o.print(".");
       
  1119     symbol->structure_element_name->accept(*this);
       
  1120   }
       
  1121   return NULL;
       
  1122 }
       
  1123 
       
  1124 /* program_name '.' symbolic_variable */
       
  1125 void *visit(program_output_reference_c *symbol) {
       
  1126   symbol->program_name->accept(*this);
       
  1127   s4o.print(".");
       
  1128   symbol->symbolic_variable->accept(*this);
       
  1129   return NULL;
       
  1130 }
       
  1131 
       
  1132 /*  TASK task_name task_initialization */
       
  1133 void *visit(task_configuration_c *symbol) {
       
  1134   s4o.print("TASK ");
       
  1135   symbol->task_name->accept(*this);
       
  1136   s4o.print(" ");
       
  1137   symbol->task_initialization->accept(*this);
       
  1138   return NULL;
       
  1139 }
       
  1140 
       
  1141 /*  '(' [SINGLE ASSIGN data_source ','] [INTERVAL ASSIGN data_source ','] PRIORITY ASSIGN integer ')' */
       
  1142 void *visit(task_initialization_c *symbol) {
       
  1143   s4o.print("(");
       
  1144   if (symbol->single_data_source != NULL) {
       
  1145     s4o.print("SINGLE := ");
       
  1146     symbol->single_data_source->accept(*this);
       
  1147     s4o.print(", ");
       
  1148   }
       
  1149   if (symbol->interval_data_source != NULL) {
       
  1150     s4o.print("INTERVAL := ");
       
  1151     symbol->interval_data_source->accept(*this);
       
  1152     s4o.print(", ");
       
  1153   }
       
  1154   s4o.print("PRIORITY := ");
       
  1155   symbol->priority_data_source->accept(*this);
       
  1156   s4o.print(")");
       
  1157   return NULL;
       
  1158 }
       
  1159 
       
  1160 /*  PROGRAM [RETAIN | NON_RETAIN] program_name [WITH task_name] ':' program_type_name ['(' prog_conf_elements ')'] */
       
  1161 void *visit(program_configuration_c *symbol) {
       
  1162   s4o.print("PROGRAM ");
       
  1163   if (symbol->retain_option != NULL)
       
  1164     symbol->retain_option->accept(*this);
       
  1165   symbol->program_name->accept(*this);
       
  1166   if (symbol->task_name != NULL) {
       
  1167     s4o.print(" WITH ");
       
  1168     symbol->task_name->accept(*this);
       
  1169   }
       
  1170   s4o.print(" : ");
       
  1171   symbol->program_type_name->accept(*this);
       
  1172   if (symbol->prog_conf_elements != NULL) {
       
  1173     s4o.print("(");
       
  1174     symbol->prog_conf_elements->accept(*this);
       
  1175     s4o.print(")");
       
  1176   }
       
  1177   return NULL;
       
  1178 }
       
  1179 
       
  1180 
       
  1181 /* prog_conf_elements ',' prog_conf_element */
       
  1182 void *visit(prog_conf_elements_c *symbol) {return print_list(symbol, "", ", ");}
       
  1183 
       
  1184 /*  fb_name WITH task_name */
       
  1185 void *visit(fb_task_c *symbol) {
       
  1186   symbol->fb_name->accept(*this);
       
  1187   s4o.print(" WITH ");
       
  1188   symbol->task_name->accept(*this);
       
  1189   return NULL;
       
  1190 }
       
  1191 
       
  1192 /*  any_symbolic_variable ASSIGN prog_data_source */
       
  1193 void *visit(prog_cnxn_assign_c *symbol) {
       
  1194   symbol->symbolic_variable->accept(*this);
       
  1195   s4o.print(" := ");
       
  1196   symbol->prog_data_source->accept(*this);
       
  1197   return NULL;
       
  1198 }
       
  1199 
       
  1200 /* any_symbolic_variable SENDTO data_sink */
       
  1201 void *visit(prog_cnxn_sendto_c *symbol) {
       
  1202   symbol->symbolic_variable->accept(*this);
       
  1203   s4o.print(" => ");
       
  1204   symbol->prog_data_source->accept(*this);
       
  1205   return NULL;
       
  1206 }
       
  1207 
       
  1208 /* VAR_CONFIG instance_specific_init_list END_VAR */
       
  1209 void *visit(instance_specific_initializations_c *symbol) {
       
  1210   s4o.print(s4o.indent_spaces + "VAR_CONFIG\n");
       
  1211   s4o.indent_right();
       
  1212   symbol->instance_specific_init_list->accept(*this);
       
  1213   s4o.indent_left();
       
  1214   s4o.print(s4o.indent_spaces + "END_VAR\n");
       
  1215   return NULL;
       
  1216 }
       
  1217 
       
  1218 /* helper symbol for instance_specific_initializations */
       
  1219 /*| instance_specific_init_list instance_specific_init ';'*/
       
  1220 void *visit(instance_specific_init_list_c *symbol) {
       
  1221   return print_list(symbol, s4o.indent_spaces, ";\n" + s4o.indent_spaces, ";\n");
       
  1222 }
       
  1223 
       
  1224 /* resource_name '.' program_name '.' optional_fb_name_list '.'
       
  1225     ((variable_name [location] ':' located_var_spec_init) | (fb_name ':' fb_initialization))
       
  1226 */
       
  1227 void *visit(instance_specific_init_c *symbol) {
       
  1228   symbol->resource_name->accept(*this);
       
  1229   s4o.print(".");
       
  1230   symbol->program_name->accept(*this);
       
  1231   symbol->any_fb_name_list->accept(*this);
       
  1232   if (symbol->variable_name != NULL) {
       
  1233     s4o.print(".");
       
  1234     symbol->variable_name->accept(*this);
       
  1235   }
       
  1236   if (symbol->location != NULL) {
       
  1237     s4o.print(" ");
       
  1238     symbol->location->accept(*this);
       
  1239   }
       
  1240   s4o.print(" : ");
       
  1241   symbol->initialization->accept(*this);
       
  1242   return NULL;
       
  1243 }
       
  1244 
       
  1245 /* helper symbol for instance_specific_init */
       
  1246 /* function_block_type_name ':=' structure_initialization */
       
  1247 void *visit(fb_initialization_c *symbol) {
       
  1248   symbol->function_block_type_name->accept(*this);
       
  1249   s4o.print(" := ");
       
  1250   symbol->structure_initialization->accept(*this);
       
  1251   return NULL;
       
  1252 }
       
  1253 
       
  1254 
       
  1255 /***********************************/
       
  1256 /* B 2.1 Instructions and Operands */
       
  1257 /***********************************/
       
  1258 /*| instruction_list il_instruction */
       
  1259 void *visit(instruction_list_c *symbol) {
       
  1260   return print_list(symbol, s4o.indent_spaces, "\n" + s4o.indent_spaces, "\n");
       
  1261 }
       
  1262 
       
  1263 /* | label ':' [il_incomplete_instruction] eol_list */
       
  1264 void *visit(il_instruction_c *symbol) {
       
  1265   if (symbol->label != NULL) {
       
  1266     symbol->label->accept(*this);
       
  1267     s4o.print(": ");
       
  1268   }
       
  1269   symbol->il_instruction->accept(*this);
       
  1270   return NULL;
       
  1271 }
       
  1272 
       
  1273 
       
  1274 /* | il_simple_operator [il_operand] */
       
  1275 void *visit(il_simple_operation_c *symbol) {
       
  1276   symbol->il_simple_operator->accept(*this);
       
  1277   if (symbol->il_operand != NULL)
       
  1278     symbol->il_operand->accept(*this);
       
  1279   return NULL;
       
  1280 }
       
  1281 
       
  1282 /* | function_name [il_operand_list] */
       
  1283 void *visit(il_function_call_c *symbol) {
       
  1284   symbol->function_name->accept(*this);
       
  1285   s4o.print(" ");
       
  1286   if (symbol->il_operand_list != NULL)
       
  1287     symbol->il_operand_list->accept(*this);
       
  1288   return NULL;
       
  1289 }
       
  1290 
       
  1291 
       
  1292 /* | il_expr_operator '(' [il_operand] eol_list [simple_instr_list] ')' */
       
  1293 void *visit(il_expression_c *symbol) {
       
  1294   symbol->il_expr_operator->accept(*this);
       
  1295   s4o.print("(");
       
  1296   if (symbol->il_operand != NULL)
       
  1297     symbol->il_operand->accept(*this);
       
  1298   if (symbol->simple_instr_list != NULL) {
       
  1299     s4o.print("\n");
       
  1300     s4o.indent_right();
       
  1301     symbol->simple_instr_list->accept(*this);
       
  1302     s4o.indent_left();
       
  1303   }
       
  1304   s4o.print(")");
       
  1305   return NULL;
       
  1306 }
       
  1307 
       
  1308 /*  il_jump_operator label */
       
  1309 void *visit(il_jump_operation_c *symbol) {
       
  1310   symbol->il_jump_operator->accept(*this);
       
  1311   symbol->label->accept(*this);
       
  1312   return NULL;
       
  1313 }
       
  1314 
       
  1315 /*   il_call_operator prev_declared_fb_name
       
  1316  * | il_call_operator prev_declared_fb_name '(' ')'
       
  1317  * | il_call_operator prev_declared_fb_name '(' eol_list ')'
       
  1318  * | il_call_operator prev_declared_fb_name '(' il_operand_list ')'
       
  1319  * | il_call_operator prev_declared_fb_name '(' eol_list il_param_list ')'
       
  1320  */
       
  1321 void *visit(il_fb_call_c *symbol) {
       
  1322   symbol->il_call_operator->accept(*this);
       
  1323   symbol->fb_name->accept(*this);
       
  1324   s4o.print("(");
       
  1325   if (symbol->il_operand_list != NULL)
       
  1326     symbol->il_operand_list->accept(*this);
       
  1327   if (symbol->il_param_list != NULL) {
       
  1328     s4o.print("\n");
       
  1329     s4o.indent_right();
       
  1330     symbol->il_param_list->accept(*this);
       
  1331     s4o.indent_left();
       
  1332   }
       
  1333   s4o.print(")");
       
  1334   return NULL;
       
  1335 }
       
  1336 
       
  1337 
       
  1338 /* | function_name '(' eol_list [il_param_list] ')' */
       
  1339 void *visit(il_formal_funct_call_c *symbol) {
       
  1340   symbol->function_name->accept(*this);
       
  1341   s4o.print("(");
       
  1342   if (symbol->il_param_list != NULL) {
       
  1343     s4o.print("\n");
       
  1344     s4o.indent_right();
       
  1345     symbol->il_param_list->accept(*this);
       
  1346     s4o.print(")");
       
  1347   }
       
  1348   return NULL;
       
  1349 }
       
  1350 
       
  1351 
       
  1352 /* | il_operand_list ',' il_operand */
       
  1353 void *visit(il_operand_list_c *symbol) {return print_list(symbol, "", ", ");}
       
  1354 
       
  1355 /* | simple_instr_list il_simple_instruction */
       
  1356 void *visit(simple_instr_list_c *symbol) {
       
  1357   return print_list(symbol,  s4o.indent_spaces, "\n" + s4o.indent_spaces, "\n" + s4o.indent_spaces);
       
  1358 }
       
  1359 
       
  1360 /* | il_initial_param_list il_param_instruction */
       
  1361 void *visit(il_param_list_c *symbol) {return print_list(symbol);}
       
  1362 
       
  1363 /*  il_assign_operator il_operand
       
  1364  * | il_assign_operator '(' eol_list simple_instr_list ')'
       
  1365  */
       
  1366 void *visit(il_param_assignment_c *symbol) {
       
  1367   symbol->il_assign_operator->accept(*this);
       
  1368   s4o.print(" ");
       
  1369   if (symbol->il_operand != NULL)
       
  1370     symbol->il_operand->accept(*this);
       
  1371   if (symbol->simple_instr_list != NULL) {
       
  1372     s4o.print("(\n");
       
  1373     s4o.indent_right();
       
  1374     symbol->simple_instr_list->accept(*this);
       
  1375     s4o.indent_left();
       
  1376     s4o.print(")");
       
  1377   }
       
  1378   return NULL;
       
  1379 }
       
  1380 
       
  1381 /*  il_assign_out_operator variable */
       
  1382 void *visit(il_param_out_assignment_c *symbol) {
       
  1383   symbol->il_assign_out_operator->accept(*this);
       
  1384   symbol->variable->accept(*this);
       
  1385   return NULL;
       
  1386 }
       
  1387 
       
  1388 
       
  1389 /*******************/
       
  1390 /* B 2.2 Operators */
       
  1391 /*******************/
       
  1392 void *visit(LD_operator_c *symbol) {s4o.print("LD "); return NULL;}
       
  1393 void *visit(LDN_operator_c *symbol) {s4o.print("LDN "); return NULL;}
       
  1394 void *visit(ST_operator_c *symbol) {s4o.print("ST "); return NULL;}
       
  1395 void *visit(STN_operator_c *symbol) {s4o.print("STN "); return NULL;}
       
  1396 void *visit(NOT_operator_c *symbol) {s4o.print("NOT "); return NULL;}
       
  1397 void *visit(S_operator_c *symbol) {s4o.print("S "); return NULL;}
       
  1398 void *visit(R_operator_c *symbol) {s4o.print("R "); return NULL;}
       
  1399 void *visit(S1_operator_c *symbol) {s4o.print("S1 "); return NULL;}
       
  1400 void *visit(R1_operator_c *symbol) {s4o.print("R1 "); return NULL;}
       
  1401 void *visit(CLK_operator_c *symbol) {s4o.print("CLK "); return NULL;}
       
  1402 void *visit(CU_operator_c *symbol) {s4o.print("CU "); return NULL;}
       
  1403 void *visit(CD_operator_c *symbol) {s4o.print("CD "); return NULL;}
       
  1404 void *visit(PV_operator_c *symbol) {s4o.print("PV "); return NULL;}
       
  1405 void *visit(IN_operator_c *symbol) {s4o.print("IN "); return NULL;}
       
  1406 void *visit(PT_operator_c *symbol) {s4o.print("PT "); return NULL;}
       
  1407 void *visit(AND_operator_c *symbol) {s4o.print("AND "); return NULL;}
       
  1408 void *visit(OR_operator_c *symbol) {s4o.print("OR "); return NULL;}
       
  1409 void *visit(XOR_operator_c *symbol) {s4o.print("XOR "); return NULL;}
       
  1410 void *visit(ANDN_operator_c *symbol) {s4o.print("ANDN "); return NULL;}
       
  1411 void *visit(ORN_operator_c *symbol) {s4o.print("ORN "); return NULL;}
       
  1412 void *visit(XORN_operator_c *symbol) {s4o.print("XORN "); return NULL;}
       
  1413 void *visit(ADD_operator_c *symbol) {s4o.print("ADD "); return NULL;}
       
  1414 void *visit(SUB_operator_c *symbol) {s4o.print("SUB "); return NULL;}
       
  1415 void *visit(MUL_operator_c *symbol) {s4o.print("MUL "); return NULL;}
       
  1416 void *visit(DIV_operator_c *symbol) {s4o.print("DIV "); return NULL;}
       
  1417 void *visit(MOD_operator_c *symbol) {s4o.print("MOD "); return NULL;}
       
  1418 void *visit(GT_operator_c *symbol) {s4o.print("GT "); return NULL;}
       
  1419 void *visit(GE_operator_c *symbol) {s4o.print("GE "); return NULL;}
       
  1420 void *visit(EQ_operator_c *symbol) {s4o.print("EQ "); return NULL;}
       
  1421 void *visit(LT_operator_c *symbol) {s4o.print("LT "); return NULL;}
       
  1422 void *visit(LE_operator_c *symbol) {s4o.print("LE "); return NULL;}
       
  1423 void *visit(NE_operator_c *symbol) {s4o.print("NE "); return NULL;}
       
  1424 void *visit(CAL_operator_c *symbol) {s4o.print("CAL "); return NULL;}
       
  1425 void *visit(CALC_operator_c *symbol) {s4o.print("CALC "); return NULL;}
       
  1426 void *visit(CALCN_operator_c *symbol) {s4o.print("CALCN "); return NULL;}
       
  1427 void *visit(RET_operator_c *symbol) {s4o.print("RET "); return NULL;}
       
  1428 void *visit(RETC_operator_c *symbol) {s4o.print("RETC "); return NULL;}
       
  1429 void *visit(RETCN_operator_c *symbol) {s4o.print("RETCN "); return NULL;}
       
  1430 void *visit(JMP_operator_c *symbol) {s4o.print("JMP "); return NULL;}
       
  1431 void *visit(JMPC_operator_c *symbol) {s4o.print("JMPC "); return NULL;}
       
  1432 void *visit(JMPCN_operator_c *symbol) {s4o.print("JMPCN "); return NULL;}
       
  1433 
       
  1434 /*| [NOT] any_identifier SENDTO */
       
  1435 void *visit(il_assign_out_operator_c *symbol) {
       
  1436   if (symbol->option != NULL)
       
  1437     symbol->option->accept(*this);
       
  1438   symbol->variable_name->accept(*this);
       
  1439   s4o.print(" => ");
       
  1440   return NULL;
       
  1441 }
       
  1442 
       
  1443 
       
  1444 /***********************/
       
  1445 /* B 3.1 - Expressions */
       
  1446 /***********************/
       
  1447 void *visit(or_expression_c *symbol) {return print_binary_expression(symbol->l_exp, symbol->r_exp, " OR ");}
       
  1448 void *visit(xor_expression_c *symbol) {return print_binary_expression(symbol->l_exp, symbol->r_exp, " XOR ");}
       
  1449 void *visit(and_expression_c *symbol) {return print_binary_expression(symbol->l_exp, symbol->r_exp, " AND ");}
       
  1450 void *visit(equ_expression_c *symbol) {return print_binary_expression(symbol->l_exp, symbol->r_exp, " = ");}
       
  1451 void *visit(notequ_expression_c *symbol) {return print_binary_expression(symbol->l_exp, symbol->r_exp, " <> ");}
       
  1452 void *visit(lt_expression_c *symbol) {return print_binary_expression(symbol->l_exp, symbol->r_exp, " < ");}
       
  1453 void *visit(gt_expression_c *symbol) {return print_binary_expression(symbol->l_exp, symbol->r_exp, " > ");}
       
  1454 void *visit(le_expression_c *symbol) {return print_binary_expression(symbol->l_exp, symbol->r_exp, " <= ");}
       
  1455 void *visit(ge_expression_c *symbol) {return print_binary_expression(symbol->l_exp, symbol->r_exp, " >= ");}
       
  1456 void *visit(add_expression_c *symbol) {return print_binary_expression(symbol->l_exp, symbol->r_exp, " + ");}
       
  1457 void *visit(sub_expression_c *symbol) {return print_binary_expression(symbol->l_exp, symbol->r_exp, " - ");}
       
  1458 void *visit(mul_expression_c *symbol) {return print_binary_expression(symbol->l_exp, symbol->r_exp, " * ");}
       
  1459 void *visit(div_expression_c *symbol) {return print_binary_expression(symbol->l_exp, symbol->r_exp, " / ");}
       
  1460 void *visit(mod_expression_c *symbol) {return print_binary_expression(symbol->l_exp, symbol->r_exp, " MOD ");}
       
  1461 void *visit(power_expression_c *symbol) {return print_binary_expression(symbol->l_exp, symbol->r_exp, " ** ");}
       
  1462 void *visit(neg_expression_c *symbol) {return print_unary_expression(symbol->exp, "-");}
       
  1463 void *visit(not_expression_c *symbol) {return print_unary_expression(symbol->exp, "NOT ");}
       
  1464 
       
  1465 void *visit(function_invocation_c *symbol) {
       
  1466   symbol->function_name->accept(*this);
       
  1467   s4o.print("(");
       
  1468   symbol->parameter_assignment_list->accept(*this);
       
  1469   s4o.print(")");
       
  1470   return NULL;
       
  1471 }
       
  1472 
       
  1473 /********************/
       
  1474 /* B 3.2 Statements */
       
  1475 /********************/
       
  1476 void *visit(statement_list_c *symbol) {
       
  1477   return print_list(symbol, s4o.indent_spaces, ";\n" + s4o.indent_spaces, ";\n");
       
  1478 }
       
  1479 
       
  1480 /*********************************/
       
  1481 /* B 3.2.1 Assignment Statements */
       
  1482 /*********************************/
       
  1483 void *visit( assignment_statement_c *symbol) {
       
  1484   symbol->l_exp->accept(*this);
       
  1485   s4o.print(" := ");
       
  1486   symbol->r_exp->accept(*this);
       
  1487   return NULL;
       
  1488 }
       
  1489 
       
  1490 /*****************************************/
       
  1491 /* B 3.2.2 Subprogram Control Statements */
       
  1492 /*****************************************/
       
  1493 /*  RETURN */
       
  1494 void *visit(return_statement_c *symbol) {
       
  1495   s4o.print("RETURN");
       
  1496   return NULL;
       
  1497 }
       
  1498 
       
  1499 
       
  1500 /* fb_name '(' [param_assignment_list] ')' */
       
  1501 void *visit(fb_invocation_c *symbol) {
       
  1502   symbol->fb_name->accept(*this);
       
  1503   s4o.print("(");
       
  1504   if (symbol->param_assignment_list != NULL)
       
  1505     symbol->param_assignment_list->accept(*this);
       
  1506   s4o.print(")");
       
  1507   return NULL;
       
  1508 }
       
  1509 
       
  1510 
       
  1511 /* helper symbol for fb_invocation */
       
  1512 /* param_assignment_list ',' param_assignment */
       
  1513 void *visit(param_assignment_list_c *symbol) {return print_list(symbol, "", ", ");}
       
  1514 
       
  1515 
       
  1516 void *visit(input_variable_param_assignment_c *symbol) {
       
  1517   symbol->variable_name->accept(*this);
       
  1518   s4o.print(" := ");
       
  1519   symbol->expression->accept(*this);
       
  1520   return NULL;
       
  1521 }
       
  1522 
       
  1523 
       
  1524 void *visit(output_variable_param_assignment_c *symbol) {
       
  1525   if (symbol->not_param != NULL)
       
  1526     symbol->not_param->accept(*this);
       
  1527   symbol->variable_name->accept(*this);
       
  1528   s4o.print(" => ");
       
  1529   symbol->variable->accept(*this);
       
  1530   return NULL;
       
  1531 }
       
  1532 
       
  1533 
       
  1534 void *visit(not_paramassign_c *symbol) {
       
  1535   s4o.print("NOT ");
       
  1536   return NULL;
       
  1537 }
       
  1538 
       
  1539 
       
  1540 /********************************/
       
  1541 /* B 3.2.3 Selection Statements */
       
  1542 /********************************/
       
  1543 void *visit(if_statement_c *symbol) {
       
  1544   s4o.print("IF ");
       
  1545   symbol->expression->accept(*this);
       
  1546   s4o.print(" THEN\n");
       
  1547   s4o.indent_right();
       
  1548   symbol->statement_list->accept(*this);
       
  1549   s4o.indent_left();
       
  1550   symbol->elseif_statement_list->accept(*this);
       
  1551 
       
  1552   if (symbol->else_statement_list != NULL) {
       
  1553     s4o.print(s4o.indent_spaces); s4o.print("ELSE\n");
       
  1554     s4o.indent_right();
       
  1555     symbol->else_statement_list->accept(*this);
       
  1556     s4o.indent_left();
       
  1557   }
       
  1558   s4o.print(s4o.indent_spaces); s4o.print("END_IF");
       
  1559   return NULL;
       
  1560 }
       
  1561 
       
  1562 /* helper symbol for if_statement */
       
  1563 void *visit(elseif_statement_list_c *symbol) {return print_list(symbol);}
       
  1564 
       
  1565 /* helper symbol for elseif_statement_list */
       
  1566 void *visit(elseif_statement_c *symbol) {
       
  1567   s4o.print(s4o.indent_spaces); s4o.print("ELSIF ");
       
  1568   symbol->expression->accept(*this);
       
  1569   s4o.print(s4o.indent_spaces); s4o.print("THEN\n");
       
  1570   s4o.indent_right();
       
  1571   symbol->statement_list->accept(*this);
       
  1572   s4o.indent_left();
       
  1573   return NULL;
       
  1574 }
       
  1575 
       
  1576 void *visit(case_statement_c *symbol) {
       
  1577   s4o.print("CASE ");
       
  1578   symbol->expression->accept(*this);
       
  1579   s4o.print(" OF\n");
       
  1580   s4o.indent_right();
       
  1581   symbol->case_element_list->accept(*this);
       
  1582   if (symbol->statement_list != NULL) {
       
  1583     s4o.print(s4o.indent_spaces + "ELSE\n");
       
  1584     s4o.indent_right();
       
  1585     symbol->statement_list->accept(*this);
       
  1586     s4o.indent_left();
       
  1587   }
       
  1588   s4o.indent_left();
       
  1589   s4o.print(s4o.indent_spaces + "END_CASE");
       
  1590   return NULL;
       
  1591 }
       
  1592 
       
  1593 /* helper symbol for case_statement */
       
  1594 void *visit(case_element_list_c *symbol) {
       
  1595   return print_list(symbol);
       
  1596 }
       
  1597 
       
  1598 void *visit(case_element_c *symbol) {
       
  1599   s4o.print(s4o.indent_spaces);
       
  1600   symbol->case_list->accept(*this);
       
  1601   s4o.print(":\n");
       
  1602   s4o.indent_right();
       
  1603   symbol->statement_list->accept(*this);
       
  1604   s4o.indent_left();
       
  1605   return NULL;
       
  1606 }
       
  1607 
       
  1608 void *visit(case_list_c *symbol) {return print_list(symbol, "", ", ");}
       
  1609 
       
  1610 /********************************/
       
  1611 /* B 3.2.4 Iteration Statements */
       
  1612 /********************************/
       
  1613 void *visit(for_statement_c *symbol) {
       
  1614   s4o.print("FOR ");
       
  1615   symbol->control_variable->accept(*this);
       
  1616   s4o.print(" := ");
       
  1617   symbol->beg_expression->accept(*this);
       
  1618   s4o.print(" TO ");
       
  1619   symbol->end_expression->accept(*this);
       
  1620   if (symbol->by_expression != NULL) {
       
  1621     s4o.print(" BY ");
       
  1622     symbol->by_expression->accept(*this);
       
  1623   }
       
  1624   s4o.print(" DO\n");
       
  1625   s4o.indent_right();
       
  1626   symbol->statement_list->accept(*this);
       
  1627   s4o.indent_left();
       
  1628   s4o.print(s4o.indent_spaces); s4o.print("END_FOR");
       
  1629   return NULL;
       
  1630 }
       
  1631 
       
  1632 void *visit(while_statement_c *symbol) {
       
  1633   s4o.print("WHILE ");
       
  1634   symbol->expression->accept(*this);
       
  1635   s4o.print(" DO\n");
       
  1636   s4o.indent_right();
       
  1637   symbol->statement_list->accept(*this);
       
  1638   s4o.indent_left();
       
  1639   s4o.print(s4o.indent_spaces); s4o.print("END_WHILE");
       
  1640   return NULL;
       
  1641 }
       
  1642 
       
  1643 void *visit(repeat_statement_c *symbol) {
       
  1644   s4o.print("REPEAT\n");
       
  1645   s4o.indent_right();
       
  1646   symbol->statement_list->accept(*this);
       
  1647   s4o.indent_left();
       
  1648   s4o.print(s4o.indent_spaces); s4o.print("UNTIL ");
       
  1649   symbol->expression->accept(*this);
       
  1650   s4o.print("\n" + s4o.indent_spaces + "END_REPEAT");
       
  1651   return NULL;
       
  1652 }
       
  1653 
       
  1654 void *visit(exit_statement_c *symbol) {
       
  1655   s4o.print("EXIT");
       
  1656   return NULL;
       
  1657 }
       
  1658 
       
  1659 
       
  1660 }; /* class generate_iec_c */
       
  1661 
       
  1662 
       
  1663 
       
  1664 /***********************************************************************/
       
  1665 /***********************************************************************/
       
  1666 /***********************************************************************/
       
  1667 /***********************************************************************/
       
  1668 /***********************************************************************/
       
  1669 /***********************************************************************/
       
  1670 /***********************************************************************/
       
  1671 /***********************************************************************/
       
  1672 
       
  1673 
       
  1674 
       
  1675 
       
  1676 visitor_c *new_code_generator(stage4out_c *s4o)  {return new generate_iec_c(s4o);}
       
  1677 void delete_code_generator(visitor_c *code_generator) {delete code_generator;}
       
  1678 
       
  1679 
       
  1680 
       
  1681 
       
  1682 
       
  1683 
       
  1684 
       
  1685 
       
  1686 
       
  1687 
       
  1688 
       
  1689 
       
  1690 
       
  1691 
       
  1692