stage4/generate_cc/generate_cc_typedecl.cc
changeset 0 fb772792efd1
child 26 fd67f54e64e1
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 type declaration 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 
       
    46 
       
    47 
       
    48 
       
    49 class generate_cc_typedecl_c: public generate_cc_base_c {
       
    50 
       
    51   public:
       
    52     generate_cc_typedecl_c(stage4out_c *s4o_ptr): generate_cc_base_c(s4o_ptr) {}
       
    53     ~generate_cc_typedecl_c(void) {}
       
    54 
       
    55 
       
    56 /***************************/
       
    57 /* B 0 - Programming Model */
       
    58 /***************************/
       
    59   /* leave for derived classes... */
       
    60 
       
    61 /*************************/
       
    62 /* B.1 - Common elements */
       
    63 /*************************/
       
    64 /*******************************************/
       
    65 /* B 1.1 - Letters, digits and identifiers */
       
    66 /*******************************************/
       
    67   /* done in base class(es) */
       
    68 
       
    69 /*********************/
       
    70 /* B 1.2 - Constants */
       
    71 /*********************/
       
    72   /* originally empty... */
       
    73 
       
    74 /******************************/
       
    75 /* B 1.2.1 - Numeric Literals */
       
    76 /******************************/
       
    77   /* done in base class(es) */
       
    78 
       
    79 /*******************************/
       
    80 /* B.1.2.2   Character Strings */
       
    81 /*******************************/
       
    82   /* done in base class(es) */
       
    83 
       
    84 /***************************/
       
    85 /* B 1.2.3 - Time Literals */
       
    86 /***************************/
       
    87 /************************/
       
    88 /* B 1.2.3.1 - Duration */
       
    89 /************************/
       
    90   /* done in base class(es) */
       
    91 
       
    92 /************************************/
       
    93 /* B 1.2.3.2 - Time of day and Date */
       
    94 /************************************/
       
    95   /* done in base class(es) */
       
    96 
       
    97 /**********************/
       
    98 /* B.1.3 - Data types */
       
    99 /**********************/
       
   100 /***********************************/
       
   101 /* B 1.3.1 - Elementary Data Types */
       
   102 /***********************************/
       
   103   /* done in base class(es) */
       
   104 
       
   105 /********************************/
       
   106 /* B.1.3.2 - Generic data types */
       
   107 /********************************/
       
   108   /* originally empty... */
       
   109 
       
   110 /********************************/
       
   111 /* B 1.3.3 - Derived data types */
       
   112 /********************************/
       
   113 void *visit(subrange_spec_init_c *symbol) {
       
   114   TRACE("subrange_spec_init_c");
       
   115   // TODO...
       
   116   ERROR;
       
   117   return NULL;
       
   118 }
       
   119 
       
   120 void *visit(enumerated_spec_init_c *symbol) {
       
   121   TRACE("enumerated_spec_init_c");
       
   122   // TODO...
       
   123   ERROR;
       
   124   return NULL;
       
   125 }
       
   126 
       
   127 /*  TYPE type_declaration_list END_TYPE */
       
   128 void *visit(data_type_declaration_c *symbol) {
       
   129   TRACE("data_type_declaration_c");
       
   130   symbol->type_declaration_list->accept(*this);
       
   131   s4o.print("\n\n");
       
   132   return NULL;
       
   133 }
       
   134 
       
   135 /* helper symbol for data_type_declaration */
       
   136 void *visit(type_declaration_list_c *symbol) {
       
   137   TRACE("type_declaration_list_c");
       
   138   return print_list(symbol);
       
   139 }
       
   140 
       
   141 /*  simple_type_name ':' simple_spec_init */
       
   142 void *visit(simple_type_declaration_c *symbol) {
       
   143   TRACE("simple_type_declaration_c");
       
   144   /* add this type declaration to the type symbol table... */
       
   145   type_symtable.insert(symbol->simple_type_name, symbol->simple_spec_init);
       
   146 
       
   147   s4o.print("typedef ");
       
   148   symbol->simple_spec_init->accept(*this);
       
   149   s4o.print(" ");
       
   150   symbol->simple_type_name->accept(*this);
       
   151   s4o.print(";\n");
       
   152   return NULL;
       
   153 }
       
   154 
       
   155 /* simple_specification [ASSIGN constant] */
       
   156 //SYM_REF2(simple_spec_init_c, simple_specification, constant)
       
   157 // <constant> may be NULL
       
   158 void *visit(simple_spec_init_c *symbol) {
       
   159   TRACE("simple_spec_init_c");
       
   160   symbol->simple_specification->accept(*this);
       
   161   return NULL;
       
   162 }
       
   163 
       
   164 #if 0
       
   165 /*  subrange_type_name ':' subrange_spec_init */
       
   166 SYM_REF2(subrange_type_declaration_c, subrange_type_name, subrange_spec_init)
       
   167 
       
   168 /* subrange_specification ASSIGN signed_integer */
       
   169 SYM_REF2(subrange_spec_init_c, subrange_specification, signed_integer)
       
   170 
       
   171 /*  integer_type_name '(' subrange')' */
       
   172 SYM_REF2(subrange_specification_c, integer_type_name, subrange)
       
   173 
       
   174 /*  signed_integer DOTDOT signed_integer */
       
   175 SYM_REF2(subrange_c, lower_limit, upper_limit)
       
   176 
       
   177 /*  enumerated_type_name ':' enumerated_spec_init */
       
   178 SYM_REF2(enumerated_type_declaration_c, enumerated_type_name, enumerated_spec_init)
       
   179 
       
   180 /* enumerated_specification ASSIGN enumerated_value */
       
   181 SYM_REF2(enumerated_spec_init_c, enumerated_specification, enumerated_value)
       
   182 
       
   183 /* helper symbol for enumerated_specification->enumerated_spec_init */
       
   184 /* enumerated_value_list ',' enumerated_value */
       
   185 SYM_LIST(enumerated_value_list_c)
       
   186 
       
   187 /* enumerated_type_name '#' identifier */
       
   188 SYM_REF2(enumerated_value_c, type, value)
       
   189 
       
   190 /*  identifier ':' array_spec_init */
       
   191 SYM_REF2(array_type_declaration_c, identifier, array_spec_init)
       
   192 
       
   193 /* array_specification [ASSIGN array_initialization} */
       
   194 /* array_initialization may be NULL ! */
       
   195 SYM_REF2(array_spec_init_c, array_specification, array_initialization)
       
   196 
       
   197 /* ARRAY '[' array_subrange_list ']' OF non_generic_type_name */
       
   198 SYM_REF2(array_specification_c, array_subrange_list, non_generic_type_name)
       
   199 
       
   200 /* helper symbol for array_specification */
       
   201 /* array_subrange_list ',' subrange */
       
   202 SYM_LIST(array_subrange_list_c)
       
   203 
       
   204 /* array_initialization:  '[' array_initial_elements_list ']' */
       
   205 /* helper symbol for array_initialization */
       
   206 /* array_initial_elements_list ',' array_initial_elements */
       
   207 SYM_LIST(array_initial_elements_list_c)
       
   208 
       
   209 /* integer '(' [array_initial_element] ')' */
       
   210 /* array_initial_element may be NULL ! */
       
   211 SYM_REF2(array_initial_elements_c, integer, array_initial_element)
       
   212 #endif
       
   213 
       
   214 /*  structure_type_name ':' structure_specification */
       
   215 //SYM_REF2(structure_type_declaration_c, structure_type_name, structure_specification)
       
   216 void *visit(structure_type_declaration_c *symbol) {
       
   217   TRACE("structure_type_declaration_c");
       
   218   /* add this type declaration to the type symbol table... */
       
   219   type_symtable.insert(symbol->structure_type_name, symbol->structure_specification);
       
   220 
       
   221   s4o.print("typedef ");
       
   222   symbol->structure_specification->accept(*this);
       
   223   s4o.print(" ");
       
   224   symbol->structure_type_name->accept(*this);
       
   225   s4o.print(";\n");
       
   226   return NULL;
       
   227 }
       
   228 
       
   229 /* structure_type_name ASSIGN structure_initialization */
       
   230 /* structure_initialization may be NULL ! */
       
   231 //SYM_REF2(initialized_structure_c, structure_type_name, structure_initialization)
       
   232 void *visit(initialized_structure_c *symbol) {
       
   233   TRACE("initialized_structure_c");
       
   234   symbol->structure_type_name->accept(*this);
       
   235   return NULL;
       
   236 }
       
   237 
       
   238 /* helper symbol for structure_declaration */
       
   239 /* structure_declaration:  STRUCT structure_element_declaration_list END_STRUCT */
       
   240 /* structure_element_declaration_list structure_element_declaration ';' */
       
   241 //SYM_LIST(structure_element_declaration_list_c)
       
   242 void *visit(structure_element_declaration_list_c *symbol) {
       
   243   TRACE("structure_element_declaration_list_c");
       
   244   s4o.print("struct {\n");
       
   245   s4o.indent_right();
       
   246   s4o.print(s4o.indent_spaces);
       
   247 
       
   248   print_list(symbol);
       
   249 
       
   250   s4o.indent_left();
       
   251   s4o.print(s4o.indent_spaces);
       
   252   s4o.print("}");
       
   253   return NULL;
       
   254 }
       
   255 
       
   256 /*  structure_element_name ':' spec_init */
       
   257 //SYM_REF2(structure_element_declaration_c, structure_element_name, spec_init)
       
   258 void *visit(structure_element_declaration_c *symbol) {
       
   259   TRACE("structure_element_declaration_c");
       
   260 
       
   261   symbol->spec_init->accept(*this);
       
   262   s4o.print(" ");
       
   263   symbol->structure_element_name->accept(*this);
       
   264   s4o.print(";\n");
       
   265   s4o.print(s4o.indent_spaces);
       
   266 
       
   267   return NULL;
       
   268 }
       
   269 
       
   270 /* helper symbol for structure_initialization */
       
   271 /* structure_initialization: '(' structure_element_initialization_list ')' */
       
   272 /* structure_element_initialization_list ',' structure_element_initialization */
       
   273 //SYM_LIST(structure_element_initialization_list_c)
       
   274 void *visit(structure_element_initialization_list_c *symbol) {
       
   275   TRACE("structure_element_initialization_list_c");
       
   276 
       
   277   // TODO ???
       
   278   ERROR;
       
   279   return NULL;
       
   280 }
       
   281 
       
   282 /*  structure_element_name ASSIGN value */
       
   283 //SYM_REF2(structure_element_initialization_c, structure_element_name, value)
       
   284 void *visit(structure_element_initialization_c *symbol) {
       
   285   TRACE("structure_element_initialization_c");
       
   286 
       
   287   // TODO ???
       
   288   ERROR;
       
   289   return NULL;
       
   290 }
       
   291 
       
   292 #if 0
       
   293 /*  string_type_name ':' elementary_string_type_name string_type_declaration_size string_type_declaration_init */
       
   294 /*
       
   295  * NOTE:
       
   296  * (Summary: Contrary to what is expected, the
       
   297  *           string_type_declaration_c is not used to store
       
   298  *           simple string type declarations that do not include
       
   299  *           size limits.
       
   300  *           For e.g.:
       
   301  *             str1_type: STRING := "hello!"
       
   302  *           will be stored in a simple_type_declaration_c
       
   303  *           instead of a string_type_declaration_c.
       
   304  *           The following:
       
   305  *             str2_type: STRING [64] := "hello!"
       
   306  *           will be stored in a sring_type_declaration_c
       
   307  *
       
   308  *           Read on for why this is done...
       
   309  * End Summary)
       
   310  *
       
   311  * According to the spec, the valid construct
       
   312  * TYPE new_str_type : STRING := "hello!"; END_TYPE
       
   313  * has two possible routes to type_declaration...
       
   314  *
       
   315  * Route 1:
       
   316  * type_declaration: single_element_type_declaration
       
   317  * single_element_type_declaration: simple_type_declaration
       
   318  * simple_type_declaration: identifier ':' simple_spec_init
       
   319  * simple_spec_init: simple_specification ASSIGN constant
       
   320  * (shift:  identifier <- 'new_str_type')
       
   321  * simple_specification: elementary_type_name
       
   322  * elementary_type_name: STRING
       
   323  * (shift: elementary_type_name <- STRING)
       
   324  * (reduce: simple_specification <- elementary_type_name)
       
   325  * (shift: constant <- "hello!")
       
   326  * (reduce: simple_spec_init: simple_specification ASSIGN constant)
       
   327  * (reduce: ...)
       
   328  *
       
   329  *
       
   330  * Route 2:
       
   331  * type_declaration: string_type_declaration
       
   332  * string_type_declaration: identifier ':' elementary_string_type_name string_type_declaration_size string_type_declaration_init
       
   333  * (shift:  identifier <- 'new_str_type')
       
   334  * elementary_string_type_name: STRING
       
   335  * (shift: elementary_string_type_name <- STRING)
       
   336  * (shift: string_type_declaration_size <-  empty )
       
   337  * string_type_declaration_init: ASSIGN character_string
       
   338  * (shift: character_string <- "hello!")
       
   339  * (reduce: string_type_declaration_init <- ASSIGN character_string)
       
   340  * (reduce: string_type_declaration <- identifier ':' elementary_string_type_name string_type_declaration_size string_type_declaration_init )
       
   341  * (reduce: type_declaration <- string_type_declaration)
       
   342  *
       
   343  *
       
   344  * At first glance it seems that removing route 1 would make
       
   345  * the most sense. Unfortunately the construct 'simple_spec_init'
       
   346  * shows up multiple times in other rules, so changing this construct
       
   347  * would also mean changing all the rules in which it appears.
       
   348  * I (Mario) therefore chose to remove route 2 instead. This means
       
   349  * that the above declaration gets stored in a
       
   350  * simple_type_declaration_c, and not in a string_type_declaration_c
       
   351  * as would be expected!
       
   352  */
       
   353 /*  string_type_name ':' elementary_string_type_name string_type_declaration_size string_type_declaration_init */
       
   354 SYM_REF4(string_type_declaration_c,	string_type_name,
       
   355 					elementary_string_type_name,
       
   356 					string_type_declaration_size,
       
   357 					string_type_declaration_init) /* may be == NULL! */
       
   358 #endif
       
   359 
       
   360 /*********************/
       
   361 /* B 1.4 - Variables */
       
   362 /*********************/
       
   363   /* done in base class(es) */
       
   364 
       
   365 /********************************************/
       
   366 /* B.1.4.1   Directly Represented Variables */
       
   367 /********************************************/
       
   368 // direct_variable: direct_variable_token	{$$ = new direct_variable_c($1);};
       
   369 void *visit(direct_variable_c *symbol) {
       
   370   TRACE("direct_variable_c");
       
   371   /* Do not use print_token() as it will change everything into uppercase */
       
   372   if (strlen(symbol->value) == 0) ERROR;
       
   373   return s4o.print(symbol->value + 1);
       
   374 }
       
   375 
       
   376 
       
   377 /*************************************/
       
   378 /* B.1.4.2   Multi-element Variables */
       
   379 /*************************************/
       
   380   /* done in base class(es) */
       
   381 
       
   382 /******************************************/
       
   383 /* B 1.4.3 - Declaration & Initialisation */
       
   384 /******************************************/
       
   385   /* leave for derived classes... */
       
   386 
       
   387 /**************************************/
       
   388 /* B.1.5 - Program organization units */
       
   389 /**************************************/
       
   390 /***********************/
       
   391 /* B 1.5.1 - Functions */
       
   392 /***********************/
       
   393   /* leave for derived classes... */
       
   394 
       
   395 /*****************************/
       
   396 /* B 1.5.2 - Function Blocks */
       
   397 /*****************************/
       
   398   /* leave for derived classes... */
       
   399 
       
   400 /**********************/
       
   401 /* B 1.5.3 - Programs */
       
   402 /**********************/
       
   403   /* leave for derived classes... */
       
   404 
       
   405 /*********************************************/
       
   406 /* B.1.6  Sequential function chart elements */
       
   407 /*********************************************/
       
   408 
       
   409 /********************************/
       
   410 /* B 1.7 Configuration elements */
       
   411 /********************************/
       
   412   /* leave for derived classes... */
       
   413 
       
   414 /****************************************/
       
   415 /* B.2 - Language IL (Instruction List) */
       
   416 /****************************************/
       
   417 /***********************************/
       
   418 /* B 2.1 Instructions and Operands */
       
   419 /***********************************/
       
   420   /* leave for derived classes... */
       
   421 
       
   422 /*******************/
       
   423 /* B 2.2 Operators */
       
   424 /*******************/
       
   425   /* leave for derived classes... */
       
   426 
       
   427 
       
   428 /***************************************/
       
   429 /* B.3 - Language ST (Structured Text) */
       
   430 /***************************************/
       
   431 /***********************/
       
   432 /* B 3.1 - Expressions */
       
   433 /***********************/
       
   434   /* leave for derived classes... */
       
   435 
       
   436 /********************/
       
   437 /* B 3.2 Statements */
       
   438 /********************/
       
   439   /* leave for derived classes... */
       
   440 
       
   441 /*********************************/
       
   442 /* B 3.2.1 Assignment Statements */
       
   443 /*********************************/
       
   444   /* leave for derived classes... */
       
   445 
       
   446 /*****************************************/
       
   447 /* B 3.2.2 Subprogram Control Statements */
       
   448 /*****************************************/
       
   449   /* leave for derived classes... */
       
   450 
       
   451 /********************************/
       
   452 /* B 3.2.3 Selection Statements */
       
   453 /********************************/
       
   454   /* leave for derived classes... */
       
   455 
       
   456 /********************************/
       
   457 /* B 3.2.4 Iteration Statements */
       
   458 /********************************/
       
   459   /* leave for derived classes... */
       
   460 
       
   461 
       
   462 
       
   463 
       
   464 }; /* generate_cc_typedecl_c */
       
   465 
       
   466 
       
   467