stage4/generate_cc/generate_cc_base.cc
changeset 0 fb772792efd1
child 16 e8b99f896416
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  * Conversion of basic abstract syntax constructs.
       
    28  *
       
    29  * This is part of the 4th stage that generates
       
    30  * a c++ source program equivalent to the IL and ST
       
    31  * code.
       
    32  */
       
    33 
       
    34 
       
    35 
       
    36 
       
    37 
       
    38 
       
    39 //#include <stdio.h>  /* required for NULL */
       
    40 //#include <string>
       
    41 //#include <iostream>
       
    42 
       
    43 //#include "../../util/symtable.hh"
       
    44 
       
    45 //#include "generate_cc.hh"
       
    46 
       
    47 
       
    48 
       
    49 
       
    50 
       
    51 
       
    52 
       
    53 
       
    54 
       
    55 
       
    56 
       
    57 
       
    58 
       
    59 class generate_cc_base_c: public iterator_visitor_c {
       
    60 
       
    61   protected:
       
    62     stage4out_c &s4o;
       
    63 
       
    64   private:
       
    65     /* Unlike programs that are mapped onto C++ classes, Function Blocks are mapped onto a data structure type
       
    66      * and a separate function conatining the code. This function is passed a pointer to an instance of the data
       
    67      * structure. This means that the code inside the functions must insert a pointer to the data structure whenever
       
    68      * it wishes to access a Function Block variable.
       
    69      * The variable_prefix_ variable will contain the correct string which needs to be prefixed to all variable accesses.
       
    70      * This string is set with the set_variable_prefix() member function.
       
    71      */
       
    72     const char *variable_prefix_;
       
    73 
       
    74 
       
    75 
       
    76   public:
       
    77     generate_cc_base_c(stage4out_c *s4o_ptr): s4o(*s4o_ptr) {variable_prefix_ = NULL;}
       
    78     ~generate_cc_base_c(void) {}
       
    79 
       
    80     void set_variable_prefix(const char *variable_prefix) {variable_prefix_ = variable_prefix;}
       
    81     void print_variable_prefix(void) {
       
    82       if (variable_prefix_ != NULL)
       
    83         s4o.print(variable_prefix_);
       
    84     }
       
    85 
       
    86     void *print_token(token_c *token, int offset = 0) {
       
    87       return s4o.printupper((token->value)+offset);
       
    88     }
       
    89 
       
    90     void *print_literal(symbol_c *type, symbol_c *value) {
       
    91       s4o.print("(");
       
    92       type->accept(*this);
       
    93       s4o.print(")");
       
    94       value->accept(*this);
       
    95       return NULL;
       
    96     }
       
    97 
       
    98     void *print_striped_token(token_c *token, int offset = 0) {
       
    99       std::string str = "";
       
   100       for (unsigned int i = offset; i < strlen(token->value); i++)
       
   101         if (token->value[i] != '_')
       
   102           str += token->value[i];
       
   103       return s4o.printupper(str);
       
   104     }
       
   105 
       
   106     void *print_striped_binary_token(token_c *token, unsigned int offset = 0) {
       
   107       /* convert the binary value to hexadecimal format... */
       
   108       unsigned char value, bit_mult;
       
   109       unsigned int i;
       
   110       int total_bits;
       
   111       char str[2] = {'A', '\0'};  /* since the s4o object is not prepared to print out one character at a time... */
       
   112 
       
   113       s4o.print("0x");
       
   114 
       
   115       total_bits = 0;
       
   116       for (i = offset; i < strlen(token->value); i++)
       
   117         if (token->value[i] != '_')
       
   118 	  total_bits++;
       
   119 
       
   120       value = 0;
       
   121       bit_mult = (unsigned char)1 << (((total_bits+3)%4)+1);
       
   122       for (i = offset; i < strlen(token->value); i++) {
       
   123         if (token->value[i] != '_') {
       
   124 	  bit_mult /= 2;
       
   125 	  value += bit_mult * ((token->value[i] == '0')? 0:1);
       
   126 	  if (bit_mult == 1) {
       
   127 	    str[0] = (value <= 9)? (char)'0' + value : (char)'A' + value;
       
   128 	    s4o.print(str);
       
   129             bit_mult = 0x10;
       
   130             value = 0;
       
   131 	  }
       
   132 	}
       
   133       }
       
   134 
       
   135       return NULL;
       
   136     }
       
   137 
       
   138     void *print_list(list_c *list,
       
   139 		     std::string pre_elem_str = "",
       
   140 		     std::string inter_elem_str = "",
       
   141 		     std::string post_elem_str = "",
       
   142 		     visitor_c *visitor = NULL) {
       
   143       if (visitor == NULL) visitor = this;
       
   144 
       
   145       if (list->n > 0) {
       
   146 //std::cout << "generate_cc_base_c::print_list(n = " << list->n << ")   000\n";
       
   147         s4o.print(pre_elem_str);
       
   148         list->elements[0]->accept(*visitor);
       
   149       }
       
   150 
       
   151       for(int i = 1; i < list->n; i++) {
       
   152 //std::cout << "generate_cc_base_c::print_list   " << i << "\n";
       
   153         s4o.print(inter_elem_str);
       
   154         list->elements[i]->accept(*visitor);
       
   155       }
       
   156 
       
   157       if (list->n > 0)
       
   158         s4o.print(post_elem_str);
       
   159 
       
   160       return NULL;
       
   161     }
       
   162 
       
   163 
       
   164     void *print_binary_expression(symbol_c *l_exp,
       
   165 				  symbol_c *r_exp,
       
   166 				  const char *operation) {
       
   167       s4o.print("(");
       
   168       l_exp->accept(*this);
       
   169       s4o.print(operation);
       
   170       r_exp->accept(*this);
       
   171       s4o.print(")");
       
   172       return NULL;
       
   173     }
       
   174 
       
   175 
       
   176     void *print_unary_expression(symbol_c *exp,
       
   177 				 const char *operation) {
       
   178       s4o.print(operation);
       
   179       s4o.print("(");
       
   180       exp->accept(*this);
       
   181       s4o.print(")");
       
   182       return NULL;
       
   183     }
       
   184 
       
   185 
       
   186 /***************************/
       
   187 /* 2.1.6 - Pragmas */
       
   188 /***************************/
       
   189     /* Do not use print_token() as it will change everything into uppercase */
       
   190     void *visit(pragma_c *symbol) {return s4o.print(symbol->value);}
       
   191 
       
   192 
       
   193 /***************************/
       
   194 /* B 0 - Programming Model */
       
   195 /***************************/
       
   196   /* leave for derived classes... */
       
   197 
       
   198 
       
   199 
       
   200 /*************************/
       
   201 /* B.1 - Common elements */
       
   202 /*************************/
       
   203 /*******************************************/
       
   204 /* B 1.1 - Letters, digits and identifiers */
       
   205 /*******************************************/
       
   206     void *visit(identifier_c *symbol) {return print_token(symbol);}
       
   207 
       
   208 /*********************/
       
   209 /* B 1.2 - Constants */
       
   210 /*********************/
       
   211   /* originally empty... */
       
   212 
       
   213 /******************************/
       
   214 /* B 1.2.1 - Numeric Literals */
       
   215 /******************************/
       
   216     void *visit(real_c *symbol) {return print_striped_token(symbol);}
       
   217     void *visit(integer_c *symbol) {return print_striped_token(symbol);}
       
   218     void *visit(binary_integer_c *symbol) {return print_striped_binary_token(symbol, 2);}
       
   219     void *visit(octal_integer_c *symbol) {s4o.print("0"); return print_striped_token(symbol, 2);}
       
   220     void *visit(hex_integer_c *symbol) {s4o.print("0x"); return print_striped_token(symbol, 3);}
       
   221 
       
   222     void *visit(numeric_literal_c *symbol) {return print_literal(symbol->type, symbol->value);}
       
   223     void *visit(integer_literal_c *symbol) {return print_literal(symbol->type, symbol->value);}
       
   224     void *visit(real_literal_c *symbol) {return print_literal(symbol->type, symbol->value);}
       
   225     void *visit(bit_string_literal_c *symbol) {return print_literal(symbol->type, symbol->value);}
       
   226     void *visit(boolean_literal_c *symbol) {return print_literal(symbol->type, symbol->value);}
       
   227 
       
   228     /* helper class for boolean_literal_c */
       
   229     void *visit(boolean_true_c *symbol) {s4o.print("TRUE"); return NULL;}
       
   230     void *visit(boolean_false_c *symbol) {s4o.print("FALSE"); return NULL;}
       
   231 
       
   232 /*******************************/
       
   233 /* B.1.2.2   Character Strings */
       
   234 /*******************************/
       
   235     void *visit(double_byte_character_string_c *symbol) {
       
   236       // TO DO ...
       
   237       ERROR;
       
   238       return print_token(symbol);
       
   239     }
       
   240 
       
   241     void *visit(single_byte_character_string_c *symbol) {
       
   242       std::string str = "";
       
   243 
       
   244       str += '"';
       
   245       /* we ignore the first and last bytes, they will be the character ' */
       
   246       for (unsigned int i = 1; i < strlen(symbol->value) - 1; i++) {
       
   247         char c = symbol->value[i];
       
   248         if ((c == '\\') || (c == '"'))
       
   249           {str += '\\'; str += c; continue;}
       
   250         if (c != '$')
       
   251           {str += c; continue;}
       
   252         /* this should be safe, since the code has passed the syntax parser!! */
       
   253         c = symbol->value[++i];
       
   254         switch (c) {
       
   255           case '$':
       
   256           case '\'':
       
   257             {str += c; continue;}
       
   258           case 'L':
       
   259           case 'l':
       
   260             {str += "\x0A"; /* LF */; continue;}
       
   261           case 'N':
       
   262           case 'n':
       
   263             {str += "\\x0A"; /* NL */; continue;}
       
   264           case 'P':
       
   265           case 'p':
       
   266             {str += "\\f"; /* FF */; continue;}
       
   267           case 'R':
       
   268           case 'r':
       
   269             {str += "\\r"; /* CR */; continue;}
       
   270           case 'T':
       
   271           case 't':
       
   272             {str += "\\t"; /* tab */; continue;}
       
   273           default: {
       
   274             if (isxdigit(c)) {
       
   275               /* this should be safe, since the code has passed the syntax parser!! */
       
   276 	      char c2 = symbol->value[++i];
       
   277 	      if (isxdigit(c2)) {
       
   278 	        str += '\\'; str += 'x'; str += c; str += c2;
       
   279 	        continue;
       
   280 	      }
       
   281 	    }
       
   282           }
       
   283           /* otherwise we have an invalid string!! */
       
   284           /* This should not have got through the syntax parser! */
       
   285           ERROR;
       
   286         } /* switch() */
       
   287       } /* for() */
       
   288 
       
   289       str += '"';
       
   290 
       
   291       s4o.print(str);
       
   292       return NULL;
       
   293     }
       
   294 
       
   295 
       
   296 /***************************/
       
   297 /* B 1.2.3 - Time Literals */
       
   298 /***************************/
       
   299 
       
   300 /************************/
       
   301 /* B 1.2.3.1 - Duration */
       
   302 /************************/
       
   303 /* The following output is actually the parameters to the constructor of the TIME class! */
       
   304 
       
   305 /* SYM_REF0(neg_time_c) */
       
   306 void *visit(neg_time_c *symbol) {s4o.print("-1"); /* negative time value */; return NULL;}
       
   307 
       
   308 
       
   309 /* SYM_REF2(duration_c, neg, interval) */
       
   310 void *visit(duration_c *symbol) {
       
   311   TRACE("duration_c");
       
   312   s4o.print("TIME(");
       
   313   if (NULL == symbol->neg)
       
   314     s4o.print("1");  /* positive time value */
       
   315   else
       
   316     symbol->neg->accept(*this);  /* this will print '-1'   :-) */
       
   317 
       
   318   s4o.print(", ");
       
   319 
       
   320   symbol->interval->accept(*this);
       
   321   s4o.print(")");
       
   322   return NULL;
       
   323 }
       
   324 
       
   325 
       
   326 /* SYM_TOKEN(fixed_point_c) */
       
   327 void *visit(fixed_point_c *symbol) {return print_token(symbol);}
       
   328 
       
   329 
       
   330 /* SYM_REF2(days_c, days, hours) */
       
   331 void *visit(days_c *symbol) {
       
   332   TRACE("days_c");
       
   333   if (NULL == symbol->hours)
       
   334     s4o.print("0, 0, 0, 0");  /* milliseconds, seconds, minutes, hours */
       
   335   else
       
   336     symbol->hours->accept(*this);
       
   337 
       
   338   s4o.print(", ");
       
   339 
       
   340   symbol->days->accept(*this);
       
   341   return NULL;
       
   342 }
       
   343 
       
   344 
       
   345 /* SYM_REF2(hours_c, hours, minutes) */
       
   346 void *visit(hours_c *symbol) {
       
   347   TRACE("hours_c");
       
   348   if (NULL == symbol->minutes)
       
   349     s4o.print("0, 0, 0");  /* milliseconds, seconds, minutes */
       
   350   else
       
   351     symbol->minutes->accept(*this);
       
   352 
       
   353   s4o.print(", ");
       
   354 
       
   355   symbol->hours->accept(*this);
       
   356   return NULL;
       
   357 }
       
   358 
       
   359 
       
   360 /* SYM_REF2(minutes_c, minutes, seconds) */
       
   361 void *visit(minutes_c *symbol) {
       
   362   TRACE("minutes_c");
       
   363   if (NULL == symbol->seconds)
       
   364     s4o.print("0, 0");  /* milliseconds, seconds */
       
   365   else
       
   366     symbol->seconds->accept(*this);
       
   367 
       
   368   s4o.print(", ");
       
   369 
       
   370   symbol->minutes->accept(*this);
       
   371   return NULL;
       
   372 }
       
   373 
       
   374 
       
   375 /* SYM_REF2(seconds_c, seconds, milliseconds) */
       
   376 void *visit(seconds_c *symbol) {
       
   377   TRACE("seconds_c");
       
   378   if (NULL == symbol->milliseconds)
       
   379     s4o.print("0");  /* milliseconds */
       
   380   else
       
   381     symbol->milliseconds->accept(*this);
       
   382 
       
   383   s4o.print(", ");
       
   384 
       
   385   symbol->seconds->accept(*this);
       
   386   return NULL;
       
   387 }
       
   388 
       
   389 
       
   390 /* SYM_REF2(milliseconds_c, milliseconds, unused) */
       
   391 void *visit(milliseconds_c *symbol) {
       
   392   TRACE("milliseconds_c");
       
   393   symbol->milliseconds->accept(*this);
       
   394   return NULL;
       
   395 }
       
   396 
       
   397 /************************************/
       
   398 /* B 1.2.3.2 - Time of day and Date */
       
   399 /************************************/
       
   400 
       
   401 /* SYM_REF2(time_of_day_c, daytime, unused) */
       
   402 void *visit(time_of_day_c *symbol) {
       
   403   TRACE("time_of_day_c");
       
   404   s4o.print("TOD(");
       
   405   symbol->daytime->accept(*this);
       
   406   s4o.print(")");
       
   407   return NULL;
       
   408 }
       
   409 
       
   410 
       
   411 /* SYM_REF4(daytime_c, day_hour, day_minute, day_second, unused) */
       
   412 void *visit(daytime_c *symbol) {
       
   413   TRACE("daytime_c");
       
   414   symbol->day_second->accept(*this);
       
   415   s4o.print(", ");
       
   416   symbol->day_minute->accept(*this);
       
   417   s4o.print(", ");
       
   418   symbol->day_hour->accept(*this);
       
   419   return NULL;
       
   420 }
       
   421 
       
   422 
       
   423 /* SYM_REF2(date_c, date_literal, unused) */
       
   424 void *visit(date_c *symbol) {
       
   425   TRACE("date_c");
       
   426   s4o.print("DATE(");
       
   427   symbol->date_literal->accept(*this);
       
   428   s4o.print(")");
       
   429   return NULL;
       
   430 }
       
   431 
       
   432 
       
   433 /* SYM_REF4(date_literal_c, year, month, day, unused) */
       
   434 void *visit(date_literal_c *symbol) {
       
   435   TRACE("date_literal_c");
       
   436   symbol->day->accept(*this);
       
   437   s4o.print(", ");
       
   438   symbol->month->accept(*this);
       
   439   s4o.print(", ");
       
   440   symbol->year->accept(*this);
       
   441   return NULL;
       
   442 }
       
   443 
       
   444 
       
   445 /* SYM_REF2(date_and_time_c, date_literal, daytime) */
       
   446 void *visit(date_and_time_c *symbol) {
       
   447   TRACE("date_and_time_c");
       
   448   s4o.print("DT(");
       
   449   symbol->daytime->accept(*this);
       
   450   s4o.print(", ");
       
   451   symbol->date_literal->accept(*this);
       
   452   s4o.print(")");
       
   453   return NULL;
       
   454 }
       
   455 
       
   456 
       
   457 /**********************/
       
   458 /* B.1.3 - Data types */
       
   459 /**********************/
       
   460 /***********************************/
       
   461 /* B 1.3.1 - Elementary Data Types */
       
   462 /***********************************/
       
   463     void *visit(time_type_name_c *symbol) {s4o.print("TIME"); return NULL;}
       
   464     void *visit(bool_type_name_c *symbol) {s4o.print("BOOL"); return NULL;}
       
   465     void *visit(sint_type_name_c *symbol) {s4o.print("SINT"); return NULL;}
       
   466     void *visit(int_type_name_c *symbol) {s4o.print("INT"); return NULL;}
       
   467     void *visit(dint_type_name_c *symbol) {s4o.print("DINT"); return NULL;}
       
   468     void *visit(lint_type_name_c *symbol) {s4o.print("LINT"); return NULL;}
       
   469     void *visit(usint_type_name_c *symbol) {s4o.print("USINT"); return NULL;}
       
   470     void *visit(uint_type_name_c *symbol) {s4o.print("UINT"); return NULL;}
       
   471     void *visit(udint_type_name_c *symbol) {s4o.print("UDINT"); return NULL;}
       
   472     void *visit(ulint_type_name_c *symbol) {s4o.print("ULINT"); return NULL;}
       
   473     void *visit(real_type_name_c *symbol) {s4o.print("REAL"); return NULL;}
       
   474     void *visit(lreal_type_name_c *symbol) {s4o.print("LREAL"); return NULL;}
       
   475     void *visit(date_type_name_c *symbol) {s4o.print("DATE"); return NULL;}
       
   476     void *visit(tod_type_name_c *symbol) {s4o.print("TOD"); return NULL;}
       
   477     void *visit(dt_type_name_c *symbol) {s4o.print("DT"); return NULL;}
       
   478     void *visit(byte_type_name_c *symbol) {s4o.print("BYTE"); return NULL;}
       
   479     void *visit(word_type_name_c *symbol) {s4o.print("WORD"); return NULL;}
       
   480     void *visit(lword_type_name_c *symbol) {s4o.print("LWORD"); return NULL;}
       
   481     void *visit(dword_type_name_c *symbol) {s4o.print("DWORD"); return NULL;}
       
   482     void *visit(string_type_name_c *symbol) {s4o.print("STRING"); return NULL;}
       
   483     void *visit(wstring_type_name_c *symbol) {s4o.print("WSTRING"); return NULL;}
       
   484 
       
   485 /********************************/
       
   486 /* B.1.3.2 - Generic data types */
       
   487 /********************************/
       
   488   /* originally empty... */
       
   489 
       
   490 /********************************/
       
   491 /* B 1.3.3 - Derived data types */
       
   492 /********************************/
       
   493   /* leave for derived classes... */
       
   494 
       
   495 /*********************/
       
   496 /* B 1.4 - Variables */
       
   497 /*********************/
       
   498 void *visit(symbolic_variable_c *symbol) {
       
   499   TRACE("symbolic_variable_c");
       
   500   this->print_variable_prefix();
       
   501   symbol->var_name->accept(*this);
       
   502   return NULL;
       
   503 }
       
   504 
       
   505 /********************************************/
       
   506 /* B.1.4.1   Directly Represented Variables */
       
   507 /********************************************/
       
   508 void *visit(direct_variable_c *symbol) {
       
   509   TRACE("direct_variable_c");
       
   510   /* Do not use print_token() as it will change everything into uppercase */
       
   511   return s4o.print(symbol->value);
       
   512 }
       
   513 
       
   514 
       
   515 
       
   516 /*************************************/
       
   517 /* B.1.4.2   Multi-element Variables */
       
   518 /*************************************/
       
   519 #if 0
       
   520 /*  subscripted_variable '[' subscript_list ']' */
       
   521 SYM_REF2(array_variable_c, subscripted_variable, subscript_list)
       
   522 
       
   523 /* subscript_list ',' subscript */
       
   524 SYM_LIST(subscript_list_c)
       
   525 #endif
       
   526 
       
   527 /*  record_variable '.' field_selector */
       
   528 /*  WARNING: input and/or output variables of function blocks
       
   529  *           may be accessed as fields of a structured variable!
       
   530  *           Code handling a structured_variable_c must take
       
   531  *           this into account!
       
   532  */
       
   533 // SYM_REF2(structured_variable_c, record_variable, field_selector)
       
   534 void *visit(structured_variable_c *symbol) {
       
   535   TRACE("structured_variable_c");
       
   536 
       
   537   symbol->record_variable->accept(*this);
       
   538   s4o.print(".");
       
   539   symbol->field_selector->accept(*this);
       
   540   return NULL;
       
   541 }
       
   542 
       
   543 /******************************************/
       
   544 /* B 1.4.3 - Declaration & Initialisation */
       
   545 /******************************************/
       
   546   /* leave for derived classes... */
       
   547 
       
   548 /**************************************/
       
   549 /* B.1.5 - Program organization units */
       
   550 /**************************************/
       
   551 /***********************/
       
   552 /* B 1.5.1 - Functions */
       
   553 /***********************/
       
   554   /* leave for derived classes... */
       
   555 
       
   556 /*****************************/
       
   557 /* B 1.5.2 - Function Blocks */
       
   558 /*****************************/
       
   559   /* leave for derived classes... */
       
   560 
       
   561 /**********************/
       
   562 /* B 1.5.3 - Programs */
       
   563 /**********************/
       
   564   /* leave for derived classes... */
       
   565 
       
   566 /*********************************************/
       
   567 /* B.1.6  Sequential function chart elements */
       
   568 /*********************************************/
       
   569 
       
   570 /********************************/
       
   571 /* B 1.7 Configuration elements */
       
   572 /********************************/
       
   573   /* leave for derived classes... */
       
   574 
       
   575 /****************************************/
       
   576 /* B.2 - Language IL (Instruction List) */
       
   577 /****************************************/
       
   578 /***********************************/
       
   579 /* B 2.1 Instructions and Operands */
       
   580 /***********************************/
       
   581   /* leave for derived classes... */
       
   582 
       
   583 /*******************/
       
   584 /* B 2.2 Operators */
       
   585 /*******************/
       
   586   /* leave for derived classes... */
       
   587 
       
   588 
       
   589 /***************************************/
       
   590 /* B.3 - Language ST (Structured Text) */
       
   591 /***************************************/
       
   592 /***********************/
       
   593 /* B 3.1 - Expressions */
       
   594 /***********************/
       
   595   /* leave for derived classes... */
       
   596 
       
   597 /********************/
       
   598 /* B 3.2 Statements */
       
   599 /********************/
       
   600   /* leave for derived classes... */
       
   601 
       
   602 /*********************************/
       
   603 /* B 3.2.1 Assignment Statements */
       
   604 /*********************************/
       
   605   /* leave for derived classes... */
       
   606 
       
   607 /*****************************************/
       
   608 /* B 3.2.2 Subprogram Control Statements */
       
   609 /*****************************************/
       
   610   /* leave for derived classes... */
       
   611 
       
   612 /********************************/
       
   613 /* B 3.2.3 Selection Statements */
       
   614 /********************************/
       
   615   /* leave for derived classes... */
       
   616 
       
   617 /********************************/
       
   618 /* B 3.2.4 Iteration Statements */
       
   619 /********************************/
       
   620   /* leave for derived classes... */
       
   621 
       
   622 }; /* class generate_cc_basic_c */
       
   623 
       
   624 
       
   625 
       
   626 
       
   627 
       
   628 
       
   629 
       
   630 
       
   631 
       
   632 
       
   633 
       
   634 
       
   635 
       
   636