stage4/generate_c/generate_c_st.cc
changeset 999 dd50a82ae8da
parent 945 477393b00f95
child 1011 76175defb87b
equal deleted inserted replaced
998:694127983aa4 999:dd50a82ae8da
    52       complextype_base_vg,
    52       complextype_base_vg,
    53       complextype_suffix_vg,
    53       complextype_suffix_vg,
    54       fparam_output_vg
    54       fparam_output_vg
    55     } variablegeneration_t;
    55     } variablegeneration_t;
    56 
    56 
    57     typedef enum {
       
    58       single_cg,
       
    59       subrange_cg,
       
    60       none_cg
       
    61     } casegeneration_t;
       
    62 
       
    63   private:
    57   private:
    64     /* When calling a function block, we must first find it's type,
    58     /* When calling a function block, we must first find it's type,
    65      * by searching through the declarations of the variables currently
    59      * by searching through the declarations of the variables currently
    66      * in scope.
    60      * in scope.
    67      * This class does just that...
    61      * This class does just that...
    87     symbol_c *fbname;
    81     symbol_c *fbname;
    88 
    82 
    89     bool first_subrange_case_list;
    83     bool first_subrange_case_list;
    90 
    84 
    91     variablegeneration_t wanted_variablegeneration;
    85     variablegeneration_t wanted_variablegeneration;
    92     casegeneration_t wanted_casegeneration;
       
    93 
    86 
    94   public:
    87   public:
    95     generate_c_st_c(stage4out_c *s4o_ptr, symbol_c *name, symbol_c *scope, const char *variable_prefix = NULL)
    88     generate_c_st_c(stage4out_c *s4o_ptr, symbol_c *name, symbol_c *scope, const char *variable_prefix = NULL)
    96     : generate_c_base_and_typeid_c(s4o_ptr) {
    89     : generate_c_base_and_typeid_c(s4o_ptr) {
    97       search_fb_instance_decl    = new search_fb_instance_decl_c   (scope);
    90       search_fb_instance_decl    = new search_fb_instance_decl_c   (scope);
   103       current_array_type = NULL;
    96       current_array_type = NULL;
   104       current_param_type = NULL;
    97       current_param_type = NULL;
   105       fcall_number = 0;
    98       fcall_number = 0;
   106       fbname = name;
    99       fbname = name;
   107       wanted_variablegeneration = expression_vg;
   100       wanted_variablegeneration = expression_vg;
   108       wanted_casegeneration = none_cg;
       
   109     }
   101     }
   110 
   102 
   111     virtual ~generate_c_st_c(void) {
   103     virtual ~generate_c_st_c(void) {
   112       delete search_fb_instance_decl;
   104       delete search_fb_instance_decl;
   113       delete search_varfb_instance_type;
   105       delete search_varfb_instance_type;
   232 /* B 1.3.3 - Derived data types */
   224 /* B 1.3.3 - Derived data types */
   233 /********************************/
   225 /********************************/
   234 
   226 
   235 /*  signed_integer DOTDOT signed_integer */
   227 /*  signed_integer DOTDOT signed_integer */
   236 void *visit(subrange_c *symbol) {
   228 void *visit(subrange_c *symbol) {
   237   switch (wanted_casegeneration) {
   229   symbol->lower_limit->accept(*this);
   238     case subrange_cg:
       
   239       s4o.print("__case_expression >= ");
       
   240       symbol->lower_limit->accept(*this);
       
   241       s4o.print(" && __case_expression <= ");
       
   242       symbol->upper_limit->accept(*this);
       
   243       break;
       
   244     default:
       
   245       symbol->lower_limit->accept(*this);
       
   246       break;
       
   247   }
       
   248   return NULL;
   230   return NULL;
   249 }
   231 }
   250 
   232 
   251 /* ARRAY '[' array_subrange_list ']' OF non_generic_type_name */
   233 /* ARRAY '[' array_subrange_list ']' OF non_generic_type_name */
   252 void *visit(array_specification_c *symbol) {
   234 void *visit(array_specification_c *symbol) {
  1221            get_datatype_info_c::lreal_type_name.accept(*this);
  1203            get_datatype_info_c::lreal_type_name.accept(*this);
  1222   else
  1204   else
  1223     expression_type->accept(*this);
  1205     expression_type->accept(*this);
  1224   s4o.print(" __case_expression = ");
  1206   s4o.print(" __case_expression = ");
  1225   symbol->expression->accept(*this);
  1207   symbol->expression->accept(*this);
  1226   s4o.print(";\n" + s4o.indent_spaces + "switch (__case_expression) {\n");
  1208   s4o.print(";\n");
  1227   s4o.indent_right();
       
  1228   wanted_casegeneration = single_cg;
       
  1229   symbol->case_element_list->accept(*this);
       
  1230   wanted_casegeneration = subrange_cg;
       
  1231   s4o.print(s4o.indent_spaces + "default:\n");
       
  1232   s4o.indent_right();
       
  1233   first_subrange_case_list = true;
       
  1234   symbol->case_element_list->accept(*this);
  1209   symbol->case_element_list->accept(*this);
  1235   if (symbol->statement_list != NULL) {
  1210   if (symbol->statement_list != NULL) {
  1236     if (!first_subrange_case_list) {
  1211     s4o.print(s4o.indent_spaces + "else {\n");
  1237       s4o.print(s4o.indent_spaces + "else {\n");
  1212     s4o.indent_right();
  1238       s4o.indent_right();
       
  1239     }
       
  1240     symbol->statement_list->accept(*this);
  1213     symbol->statement_list->accept(*this);
  1241     if (!first_subrange_case_list) {
  1214     s4o.indent_left();
  1242       s4o.indent_left();
  1215     s4o.print(s4o.indent_spaces + "}\n");
  1243       s4o.print(s4o.indent_spaces + "}\n");
  1216   }
  1244     }
       
  1245   }
       
  1246   s4o.print(s4o.indent_spaces + "break;\n");
       
  1247   s4o.indent_left();
  1217   s4o.indent_left();
  1248   wanted_casegeneration = none_cg;
  1218   s4o.print(s4o.indent_spaces + "}");
       
  1219   return NULL;
       
  1220 }
       
  1221 
       
  1222 
       
  1223 /* helper symbol for case_statement */
       
  1224 void *visit(case_element_list_c *symbol) {return print_list(symbol, s4o.indent_spaces+"if ", s4o.indent_spaces+"else if ");}
       
  1225 
       
  1226 void *visit(case_element_c *symbol) {
       
  1227   symbol->case_list->accept(*this);
       
  1228   s4o.print(" {\n");
       
  1229   s4o.indent_right();
       
  1230   symbol->statement_list->accept(*this);
  1249   s4o.indent_left();
  1231   s4o.indent_left();
  1250   s4o.print(s4o.indent_spaces + "}\n");
  1232   s4o.print(s4o.indent_spaces + "}\n");
  1251   s4o.indent_left();
  1233   return NULL;
  1252   s4o.print(s4o.indent_spaces + "}");
  1234 }
  1253   return NULL;
  1235 
  1254 }
  1236 
  1255 
  1237 void *visit(case_list_c *symbol) {
  1256 /* helper symbol for case_statement */
  1238   s4o.print("(");
  1257 void *visit(case_element_list_c *symbol) {return print_list(symbol);}
  1239   for (int i =  0; i < symbol->n; i++) {
  1258 
  1240     /* if not the first element, then add an '||', a '\n', and add some spaces to get nice alignment */
  1259 void *visit(case_element_c *symbol) {
  1241     /* example of generated C code (codition) for 
  1260   case_element_iterator_c *case_element_iterator;
  1242      *   case XX of
  1261   symbol_c* element = NULL;
  1243      *     10..20,42,15..99:  <---- C code is for this line!
  1262   bool first_element = true;
  1244      * 
  1263 
  1245      *    else if ((__case_expression >= 10 && __case_expression <= 20) ||
  1264   switch (wanted_casegeneration) {
  1246      *             (__case_expression == 42) ||
  1265     case single_cg:
  1247      *             (__case_expression >= 15 && __case_expression <= 99)) {
  1266       case_element_iterator = new case_element_iterator_c(symbol->case_list, case_element_iterator_c::element_single);
  1248      */
  1267       for (element = case_element_iterator->next(); element != NULL; element = case_element_iterator->next()) {
  1249     if (0 != i)  s4o.print(" ||\n" + s4o.indent_spaces + "         ");
  1268         if (first_element) first_element = false;
  1250     s4o.print("(");
  1269         s4o.print(s4o.indent_spaces + "case ");
  1251     subrange_c *subrange = dynamic_cast<subrange_c *>(symbol->elements[i]);
  1270         element->accept(*this);
  1252     if (NULL == subrange) {
  1271         s4o.print(":\n");
  1253       s4o.print("__case_expression == ");
  1272       }
  1254       symbol->elements[i]->accept(*this);
  1273       delete case_element_iterator;
  1255     } else {
  1274       break;
  1256       s4o.print("__case_expression >= ");
  1275 
  1257       subrange->lower_limit->accept(*this);
  1276     case subrange_cg:
  1258       s4o.print(" && __case_expression <= ");
  1277       case_element_iterator = new case_element_iterator_c(symbol->case_list, case_element_iterator_c::element_subrange);
  1259       subrange->upper_limit->accept(*this);
  1278       for (element = case_element_iterator->next(); element != NULL; element = case_element_iterator->next()) {
  1260     }
  1279         if (first_element) {
  1261     s4o.print(")");
  1280           if (first_subrange_case_list) {
  1262   }
  1281             s4o.print(s4o.indent_spaces + "if (");
  1263   s4o.print(")");
  1282             first_subrange_case_list = false;
       
  1283           }
       
  1284           else {
       
  1285             s4o.print(s4o.indent_spaces + "else if (");
       
  1286           }
       
  1287           first_element = false;
       
  1288         }
       
  1289         else {
       
  1290           s4o.print(" && ");
       
  1291         }
       
  1292         element->accept(*this);
       
  1293       }
       
  1294       delete case_element_iterator;
       
  1295       if (!first_element) {
       
  1296         s4o.print(") {\n");
       
  1297       }
       
  1298       break;
       
  1299 
       
  1300     default:
       
  1301       break;
       
  1302   }
       
  1303 
       
  1304   if (!first_element) {
       
  1305     s4o.indent_right();
       
  1306     symbol->statement_list->accept(*this);
       
  1307     switch (wanted_casegeneration) {
       
  1308       case single_cg:
       
  1309         s4o.print(s4o.indent_spaces + "break;\n");
       
  1310         s4o.indent_left();
       
  1311         break;
       
  1312       case subrange_cg:
       
  1313         s4o.indent_left();
       
  1314         s4o.print(s4o.indent_spaces + "}\n");
       
  1315         break;
       
  1316       default:
       
  1317         break;
       
  1318     }
       
  1319   }
       
  1320   return NULL;
  1264   return NULL;
  1321 }
  1265 }
  1322 
  1266 
  1323 /********************************/
  1267 /********************************/
  1324 /* B 3.2.4 Iteration Statements */
  1268 /* B 3.2.4 Iteration Statements */