stage4/generate_c/generate_c_typedecl.cc
changeset 870 9c6c588fd708
parent 860 7669a8d43c11
child 909 8b2a31dea131
equal deleted inserted replaced
822:a7d9e0b8636b 870:9c6c588fd708
    29     stage4out_c &s4o_incl;
    29     stage4out_c &s4o_incl;
    30 
    30 
    31   private:
    31   private:
    32     symbol_c* current_type_name;
    32     symbol_c* current_type_name;
    33     bool array_is_derived;
    33     bool array_is_derived;
    34 
       
    35     generate_c_base_c *basedecl;
    34     generate_c_base_c *basedecl;
    36 
    35 
    37   public:
    36   public:
    38     generate_c_typedecl_c(stage4out_c *s4o_ptr, stage4out_c *s4o_incl_ptr): generate_c_base_c(s4o_ptr), s4o_incl(*s4o_incl_ptr) {
       
    39       current_typedefinition = none_td;
       
    40       current_basetypedeclaration = none_bd;
       
    41       current_type_name = NULL;
       
    42       basedecl = new generate_c_base_c(&s4o_incl);
       
    43     }
       
    44     generate_c_typedecl_c(stage4out_c *s4o_ptr): generate_c_base_c(s4o_ptr), s4o_incl(*s4o_ptr) {
    37     generate_c_typedecl_c(stage4out_c *s4o_ptr): generate_c_base_c(s4o_ptr), s4o_incl(*s4o_ptr) {
    45       current_typedefinition = none_td;
    38       current_typedefinition = none_td;
    46       current_basetypedeclaration = none_bd;
    39       current_basetypedeclaration = none_bd;
    47       current_type_name = NULL;
    40       current_type_name = NULL;
    48       basedecl = new generate_c_base_c(&s4o_incl);
    41       basedecl = new generate_c_base_c(&s4o_incl);
    96         s4o_incl.print(post_elem_str);
    89         s4o_incl.print(post_elem_str);
    97 
    90 
    98       return NULL;
    91       return NULL;
    99     }
    92     }
   100 
    93 
   101     bool type_is_fb(symbol_c* type_decl) {
       
   102       return search_base_type_c::type_is_fb(type_decl);
       
   103     }
       
   104 
    94 
   105 /***************************/
    95 /***************************/
   106 /* B 0 - Programming Model */
    96 /* B 0 - Programming Model */
   107 /***************************/
    97 /***************************/
   108   /* leave for derived classes... */
    98   /* leave for derived classes... */
   191   return NULL;
   181   return NULL;
   192 }
   182 }
   193 
   183 
   194 /*  integer_type_name '(' subrange')' */
   184 /*  integer_type_name '(' subrange')' */
   195 void *visit(subrange_specification_c *symbol) {
   185 void *visit(subrange_specification_c *symbol) {
       
   186   TRACE("subrange_specification_c");
   196   if (current_typedefinition == subrange_td) {
   187   if (current_typedefinition == subrange_td) {
   197     switch (current_basetypedeclaration) {
   188     switch (current_basetypedeclaration) {
   198       case subrangebasetype_bd:
   189       case subrangebasetype_bd:
   199         symbol->integer_type_name->accept(*basedecl);
   190         symbol->integer_type_name->accept(*basedecl);
   200         break;
   191         break;
   201       case subrangetest_bd:
   192       case subrangetest_bd:
   202         if (symbol->subrange != NULL) {
   193         if (symbol->subrange != NULL) {
   203           current_type_name->accept(*this);
   194           s4o_incl.print("static inline ");
   204           s4o.print(" __CHECK_");
   195           current_type_name->accept(*basedecl);
   205           current_type_name->accept(*this);
   196           s4o_incl.print(" __CHECK_");
   206           s4o.print("(");
   197           current_type_name->accept(*basedecl);
   207           current_type_name->accept(*this);
   198           s4o_incl.print("(");
   208           s4o.print(" value) {\n");
   199           current_type_name->accept(*basedecl);
   209           s4o.indent_right();
   200           s4o_incl.print(" value) {\n");
   210 
   201           s4o_incl.indent_right();
   211           if (search_base_type_c::type_is_subrange(symbol->integer_type_name)) {
   202 
   212             s4o.print(s4o.indent_spaces + "value = __CHECK_");
   203           /* NOTE: IEC 61131-3 v2 syntax mandates that the integer type name be one of SINT, ..., LINT, USINT, ... ULIT */
       
   204           /*       For this reason, the following condition will always be false, and therefore this is a block
       
   205            *       of dead code. However, let's not delete it for now. It might come in useful for IEC 61131-3 v3.
       
   206            *       For the moment, we just comment it out!
       
   207            */
       
   208           /*
       
   209           if (get_datatype_info_c::is_subrange(symbol->integer_type_name)) {
       
   210             s4o_incl.print(s4o_incl.indent_spaces + "value = __CHECK_");
   213             symbol->integer_type_name->accept(*this);
   211             symbol->integer_type_name->accept(*this);
   214             s4o.print("(value);\n");
   212             s4o_incl.print("(value);\n");
   215           }
   213           }
       
   214           */
   216 
   215 
   217           symbol->subrange->accept(*this);
   216           symbol->subrange->accept(*this);
   218 
   217 
   219           s4o.indent_left();
   218           s4o_incl.indent_left();
   220           s4o.print("}\n");
   219           s4o_incl.print("}\n");
   221         }
   220         }
   222         else {
   221         else {
   223           s4o.print("#define __CHECK_");
   222           s4o_incl.print("#define __CHECK_");
   224           current_type_name->accept(*this);
   223           current_type_name->accept(*basedecl);
   225           s4o.print(" __CHECK_");
   224           s4o_incl.print(" __CHECK_");
   226           symbol->integer_type_name->accept(*this);
   225           symbol->integer_type_name->accept(*basedecl);
   227           s4o.print("\n");
   226           s4o_incl.print("\n");
   228         }
   227         }
   229         break;
   228         break;
   230       default:
   229       default:
   231         break;
   230         break;
   232     }
   231     }
   233   }
   232   }
   234   else {
   233   return NULL;
   235     symbol->integer_type_name->accept(*basedecl);
   234 }
   236   }
   235 
   237   return NULL;
       
   238 }
       
   239 
   236 
   240 /*  signed_integer DOTDOT signed_integer */
   237 /*  signed_integer DOTDOT signed_integer */
   241 void *visit(subrange_c *symbol) {
   238 void *visit(subrange_c *symbol) {
       
   239   TRACE("subrange_c");
   242   int dimension;
   240   int dimension;
   243   switch (current_typedefinition) {
   241   switch (current_typedefinition) {
   244     case array_td:
   242     case array_td:
   245       if (current_basetypedeclaration == arraysubrange_bd) {
   243       if (current_basetypedeclaration == arraysubrange_bd) {
   246         s4o_incl.print("[");
   244         s4o_incl.print("[");
   249       }
   247       }
   250       else
   248       else
   251         symbol->lower_limit->accept(*this);
   249         symbol->lower_limit->accept(*this);
   252       break;
   250       break;
   253     case subrange_td:
   251     case subrange_td:
   254       s4o.print(s4o.indent_spaces + "if (value < ");
   252       s4o_incl.print(s4o_incl.indent_spaces + "if (value < ");
   255       symbol->lower_limit->accept(*this);
   253       symbol->lower_limit->accept(*basedecl);
   256       s4o.print(")\n");
   254       s4o_incl.print(")\n");
   257       s4o.indent_right();
   255       s4o_incl.indent_right();
   258       s4o.print(s4o.indent_spaces + "return ");
   256       s4o_incl.print(s4o_incl.indent_spaces + "return ");
   259       symbol->lower_limit->accept(*this);
   257       symbol->lower_limit->accept(*basedecl);
   260       s4o.print(";\n");
   258       s4o_incl.print(";\n");
   261       s4o.indent_left();
   259       s4o_incl.indent_left();
   262       s4o.print(s4o.indent_spaces + "else if (value > ");
   260       s4o_incl.print(s4o_incl.indent_spaces + "else if (value > ");
   263       symbol->upper_limit->accept(*this);
   261       symbol->upper_limit->accept(*basedecl);
   264       s4o.print(")\n");
   262       s4o_incl.print(")\n");
   265       s4o.indent_right();
   263       s4o_incl.indent_right();
   266       s4o.print(s4o.indent_spaces + "return ");
   264       s4o_incl.print(s4o_incl.indent_spaces + "return ");
   267       symbol->upper_limit->accept(*this);
   265       symbol->upper_limit->accept(*basedecl);
   268       s4o.print(";\n");
   266       s4o_incl.print(";\n");
   269       s4o.indent_left();
   267       s4o_incl.indent_left();
   270       s4o.print(s4o.indent_spaces + "else\n");
   268       s4o_incl.print(s4o_incl.indent_spaces + "else\n");
   271       s4o.indent_right();
   269       s4o_incl.indent_right();
   272       s4o.print(s4o.indent_spaces + "return value;\n");
   270       s4o_incl.print(s4o_incl.indent_spaces + "return value;\n");
   273       s4o.indent_left();
   271       s4o_incl.indent_left();
   274     default:
   272     default:
   275       break;
   273       break;
   276   }
   274   }
   277   return NULL;
   275   return NULL;
   278 }
   276 }
   309 }
   307 }
   310 
   308 
   311 /* helper symbol for enumerated_specification->enumerated_spec_init */
   309 /* helper symbol for enumerated_specification->enumerated_spec_init */
   312 /* enumerated_value_list ',' enumerated_value */
   310 /* enumerated_value_list ',' enumerated_value */
   313 void *visit(enumerated_value_list_c *symbol) {
   311 void *visit(enumerated_value_list_c *symbol) {
       
   312   TRACE("enumerated_value_list_c");
   314   print_list_incl(symbol, s4o_incl.indent_spaces, ",\n"+s4o_incl.indent_spaces, "\n");
   313   print_list_incl(symbol, s4o_incl.indent_spaces, ",\n"+s4o_incl.indent_spaces, "\n");
   315   return NULL;
   314   return NULL;
   316 }
   315 }
   317 
   316 
   318 /* enumerated_type_name '#' identifier */
   317 /* enumerated_type_name '#' identifier */
   319 void *visit(enumerated_value_c *symbol) {
   318 /* Handled by generate_c_base_c class!!
   320   if (current_typedefinition == enumerated_td)
   319 void *visit(enumerated_value_c *symbol) {}
   321     current_type_name->accept(*basedecl);
   320 */
   322   else {
       
   323     if (NULL == symbol->datatype) {
       
   324       debug_c::print(symbol);
       
   325       ERROR;
       
   326     }
       
   327     symbol_c *type_name = get_datatype_info_c::get_id(symbol->datatype);
       
   328     if (NULL == type_name) {
       
   329 //       ERROR_MSG("generate_c does not support anonymous enumerated data types.");
       
   330     } else
       
   331     type_name->accept(*basedecl);
       
   332   }
       
   333   s4o_incl.print("__");
       
   334   symbol->value->accept(*basedecl);
       
   335   return NULL;
       
   336 }
       
   337 
   321 
   338 /*  identifier ':' array_spec_init */
   322 /*  identifier ':' array_spec_init */
   339 void *visit(array_type_declaration_c *symbol) {
   323 void *visit(array_type_declaration_c *symbol) {
   340   TRACE("array_type_declaration_c");
   324   TRACE("array_type_declaration_c");
   341   
   325   
   394   return NULL;
   378   return NULL;
   395 }
   379 }
   396 
   380 
   397 /* ARRAY '[' array_subrange_list ']' OF non_generic_type_name */
   381 /* ARRAY '[' array_subrange_list ']' OF non_generic_type_name */
   398 void *visit(array_specification_c *symbol) {
   382 void *visit(array_specification_c *symbol) {
       
   383   TRACE("array_specification_c");
   399   switch (current_basetypedeclaration) {
   384   switch (current_basetypedeclaration) {
   400     case arraybasetype_bd:
   385     case arraybasetype_bd:
   401       symbol->non_generic_type_name->accept(*this);
   386       symbol->non_generic_type_name->accept(*this);
   402       break;
   387       break;
   403     case arraybasetypeincl_bd:
   388     case arraybasetypeincl_bd:
   410       break;
   395       break;
   411   }
   396   }
   412   return NULL;
   397   return NULL;
   413 }
   398 }
   414 
   399 
   415 /* helper symbol for array_specification */
       
   416 /* array_subrange_list ',' subrange */
       
   417 void *visit(array_subrange_list_c *symbol) {
       
   418   print_list(symbol);
       
   419   return NULL;
       
   420 }
       
   421 
   400 
   422 /*  TYPE type_declaration_list END_TYPE */
   401 /*  TYPE type_declaration_list END_TYPE */
   423 void *visit(data_type_declaration_c *symbol) {
   402 void *visit(data_type_declaration_c *symbol) {
   424   TRACE("data_type_declaration_c");
   403   TRACE("data_type_declaration_c");
   425   symbol->type_declaration_list->accept(*this);
   404   symbol->type_declaration_list->accept(*this);
   426   s4o.print("\n\n");
   405   s4o_incl.print("\n\n");
   427   return NULL;
   406   return NULL;
   428 }
   407 }
   429 
   408 
   430 /* helper symbol for data_type_declaration */
   409 /* helper symbol for data_type_declaration */
   431 void *visit(type_declaration_list_c *symbol) {
   410 void *visit(type_declaration_list_c *symbol) {
   441   symbol->simple_type_name->accept(*basedecl);
   420   symbol->simple_type_name->accept(*basedecl);
   442   s4o_incl.print(",");
   421   s4o_incl.print(",");
   443   symbol->simple_spec_init->accept(*this);
   422   symbol->simple_spec_init->accept(*this);
   444   s4o_incl.print(")\n");
   423   s4o_incl.print(")\n");
   445 
   424 
   446   if (search_base_type_c::type_is_subrange(symbol->simple_type_name)) {
   425   if (get_datatype_info_c::is_subrange(symbol->simple_type_name)) {
   447     s4o.print("#define __CHECK_");
   426     s4o_incl.print("#define __CHECK_");
   448     current_type_name->accept(*this);
   427     current_type_name->accept(*basedecl);
   449     s4o.print(" __CHECK_");
   428     s4o_incl.print(" __CHECK_");
   450     symbol->simple_spec_init->accept(*this);
   429     symbol->simple_spec_init->accept(*this);
   451     s4o.print("\n");
   430     s4o_incl.print("\n");
   452   }
   431   }
   453 
   432 
   454   return NULL;
   433   return NULL;
   455 }
   434 }
   456 
   435 
   566 
   545 
   567   symbol->spec_init->accept(*this);
   546   symbol->spec_init->accept(*this);
   568   s4o_incl.print(" ");
   547   s4o_incl.print(" ");
   569   symbol->structure_element_name->accept(*basedecl);
   548   symbol->structure_element_name->accept(*basedecl);
   570   s4o_incl.print(";\n");
   549   s4o_incl.print(";\n");
   571   s4o_incl.print(s4o.indent_spaces);
   550   s4o_incl.print(s4o_incl.indent_spaces);
   572 
   551 
   573   return NULL;
   552   return NULL;
   574 }
   553 }
   575 
   554 
   576 /* helper symbol for structure_initialization */
   555 /* helper symbol for structure_initialization */