lbessard@70: /* Edouard@279: * matiec - a compiler for the programming languages defined in IEC 61131-3 Edouard@279: * Edouard@279: * Copyright (C) 2003-2011 Mario de Sousa (msousa@fe.up.pt) Edouard@279: * Copyright (C) 2007-2011 Laurent Bessard and Edouard Tisserant Edouard@279: * Edouard@279: * This program is free software: you can redistribute it and/or modify Edouard@279: * it under the terms of the GNU General Public License as published by Edouard@279: * the Free Software Foundation, either version 3 of the License, or Edouard@279: * (at your option) any later version. Edouard@279: * Edouard@279: * This program is distributed in the hope that it will be useful, Edouard@279: * but WITHOUT ANY WARRANTY; without even the implied warranty of Edouard@279: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Edouard@279: * GNU General Public License for more details. Edouard@279: * Edouard@279: * You should have received a copy of the GNU General Public License Edouard@279: * along with this program. If not, see . Edouard@279: * lbessard@70: * lbessard@70: * This code is made available on the understanding that it will not be lbessard@70: * used in safety-critical situations without a full and competent review. lbessard@70: */ etisserant@139: #include lbessard@70: lbessard@70: class generate_c_typedecl_c: public generate_c_base_c { lbessard@70: lbessard@121: protected: lbessard@121: stage4out_c &s4o_incl; lbessard@121: lbessard@98: private: lbessard@98: symbol_c* current_type_name; laurent@309: bool array_is_derived; lbessard@98: search_base_type_c search_base_type; laurent@328: search_constant_type_c search_constant_type; lbessard@98: lbessard@121: generate_c_base_c *basedecl; lbessard@121: lbessard@70: public: lbessard@121: generate_c_typedecl_c(stage4out_c *s4o_ptr, stage4out_c *s4o_incl_ptr): generate_c_base_c(s4o_ptr), s4o_incl(*s4o_incl_ptr) { lbessard@98: current_typedefinition = none_td; lbessard@98: current_basetypedeclaration = none_bd; laurent@328: current_type_name = NULL; lbessard@121: basedecl = new generate_c_base_c(&s4o_incl); lbessard@98: } lbessard@121: generate_c_typedecl_c(stage4out_c *s4o_ptr): generate_c_base_c(s4o_ptr), s4o_incl(*s4o_ptr) { lbessard@121: current_typedefinition = none_td; lbessard@121: current_basetypedeclaration = none_bd; laurent@328: current_type_name = NULL; lbessard@121: basedecl = new generate_c_base_c(&s4o_incl); lbessard@121: } lbessard@121: ~generate_c_typedecl_c(void) { lbessard@121: delete basedecl; lbessard@121: } lbessard@70: lbessard@98: typedef enum { lbessard@98: none_td, laurent@310: enumerated_td, lbessard@98: subrange_td, laurent@310: array_td, laurent@310: struct_td, lbessard@98: } typedefinition_t; lbessard@98: lbessard@98: typedefinition_t current_typedefinition; lbessard@98: lbessard@98: typedef enum { lbessard@98: none_bd, lbessard@98: subrangebasetype_bd, lbessard@98: subrangetest_bd, laurent@309: arrayderiveddeclaration_bd, lbessard@98: arraybasetype_bd, lbessard@121: arraybasetypeincl_bd, laurent@377: arraysubrange_bd lbessard@98: } basetypedeclaration_t; laurent@377: lbessard@98: basetypedeclaration_t current_basetypedeclaration; lbessard@98: lbessard@121: void *print_list_incl(list_c *list, lbessard@121: std::string pre_elem_str = "", lbessard@121: std::string inter_elem_str = "", lbessard@121: std::string post_elem_str = "", lbessard@121: visitor_c *visitor = NULL) { lbessard@121: if (visitor == NULL) visitor = this; lbessard@121: lbessard@121: if (list->n > 0) { lbessard@121: //std::cout << "generate_c_base_c::print_list(n = " << list->n << ") 000\n"; lbessard@121: s4o_incl.print(pre_elem_str); lbessard@121: list->elements[0]->accept(*visitor); lbessard@121: } lbessard@121: lbessard@121: for(int i = 1; i < list->n; i++) { lbessard@121: //std::cout << "generate_c_base_c::print_list " << i << "\n"; lbessard@121: s4o_incl.print(inter_elem_str); lbessard@121: list->elements[i]->accept(*visitor); lbessard@121: } lbessard@121: lbessard@121: if (list->n > 0) lbessard@121: s4o_incl.print(post_elem_str); lbessard@121: lbessard@121: return NULL; lbessard@121: } lbessard@121: Laurent@706: bool type_is_fb(symbol_c* type_decl) { Laurent@706: return search_base_type.type_is_fb(type_decl); Laurent@706: } lbessard@121: lbessard@70: /***************************/ lbessard@70: /* B 0 - Programming Model */ lbessard@70: /***************************/ lbessard@70: /* leave for derived classes... */ lbessard@70: lbessard@70: /*************************/ lbessard@70: /* B.1 - Common elements */ lbessard@70: /*************************/ lbessard@70: /*******************************************/ lbessard@70: /* B 1.1 - Letters, digits and identifiers */ lbessard@70: /*******************************************/ lbessard@70: /* done in base class(es) */ lbessard@70: lbessard@70: /*********************/ lbessard@70: /* B 1.2 - Constants */ lbessard@70: /*********************/ lbessard@70: /* originally empty... */ lbessard@70: lbessard@70: /******************************/ lbessard@70: /* B 1.2.1 - Numeric Literals */ lbessard@70: /******************************/ lbessard@70: /* done in base class(es) */ lbessard@70: lbessard@70: /*******************************/ lbessard@70: /* B.1.2.2 Character Strings */ lbessard@70: /*******************************/ lbessard@70: /* done in base class(es) */ lbessard@70: lbessard@70: /***************************/ lbessard@70: /* B 1.2.3 - Time Literals */ lbessard@70: /***************************/ lbessard@70: /************************/ lbessard@70: /* B 1.2.3.1 - Duration */ lbessard@70: /************************/ lbessard@70: /* done in base class(es) */ lbessard@70: lbessard@70: /************************************/ lbessard@70: /* B 1.2.3.2 - Time of day and Date */ lbessard@70: /************************************/ lbessard@70: /* done in base class(es) */ lbessard@70: lbessard@70: /**********************/ lbessard@70: /* B.1.3 - Data types */ lbessard@70: /**********************/ lbessard@70: /***********************************/ lbessard@70: /* B 1.3.1 - Elementary Data Types */ lbessard@70: /***********************************/ lbessard@70: /* done in base class(es) */ lbessard@70: lbessard@70: /********************************/ lbessard@70: /* B.1.3.2 - Generic data types */ lbessard@70: /********************************/ lbessard@70: /* originally empty... */ lbessard@70: lbessard@70: /********************************/ lbessard@70: /* B 1.3.3 - Derived data types */ lbessard@70: /********************************/ lbessard@98: /* subrange_type_name ':' subrange_spec_init */ lbessard@98: void *visit(subrange_type_declaration_c *symbol) { lbessard@98: TRACE("subrange_type_declaration_c"); lbessard@98: laurent@310: current_typedefinition = subrange_td; laurent@328: current_type_name = symbol->subrange_type_name; laurent@310: laurent@221: s4o_incl.print("__DECLARE_DERIVED_TYPE("); laurent@328: current_type_name->accept(*basedecl); laurent@327: s4o_incl.print(","); lbessard@98: current_basetypedeclaration = subrangebasetype_bd; lbessard@98: symbol->subrange_spec_init->accept(*this); lbessard@98: current_basetypedeclaration = none_bd; laurent@221: s4o_incl.print(")\n"); lbessard@98: lbessard@98: current_basetypedeclaration = subrangetest_bd; lbessard@98: symbol->subrange_spec_init->accept(*this); lbessard@98: current_basetypedeclaration = none_bd; lbessard@98: laurent@328: current_type_name = NULL; laurent@310: current_typedefinition = none_td; laurent@310: lbessard@98: return NULL; lbessard@98: } lbessard@98: lbessard@98: /* subrange_specification ASSIGN signed_integer */ lbessard@70: void *visit(subrange_spec_init_c *symbol) { lbessard@70: TRACE("subrange_spec_init_c"); lbessard@98: symbol->subrange_specification->accept(*this); lbessard@98: return NULL; lbessard@98: } lbessard@98: lbessard@98: /* integer_type_name '(' subrange')' */ lbessard@98: void *visit(subrange_specification_c *symbol) { laurent@310: if (current_typedefinition == subrange_td) { laurent@310: switch (current_basetypedeclaration) { laurent@310: case subrangebasetype_bd: laurent@310: symbol->integer_type_name->accept(*basedecl); laurent@310: break; laurent@310: case subrangetest_bd: laurent@310: if (symbol->subrange != NULL) { laurent@310: current_type_name->accept(*this); laurent@310: s4o.print(" __CHECK_"); laurent@310: current_type_name->accept(*this); laurent@310: s4o.print("("); laurent@310: current_type_name->accept(*this); laurent@310: s4o.print(" value) {\n"); laurent@310: s4o.indent_right(); laurent@310: laurent@310: if (search_base_type.type_is_subrange(symbol->integer_type_name)) { laurent@310: s4o.print(s4o.indent_spaces + "value = __CHECK_"); laurent@310: symbol->integer_type_name->accept(*this); laurent@310: s4o.print("(value);\n"); laurent@310: } laurent@310: laurent@310: symbol->subrange->accept(*this); laurent@310: laurent@310: s4o.indent_left(); laurent@310: s4o.print("}\n"); laurent@310: } laurent@310: else { laurent@310: s4o.print("#define __CHECK_"); laurent@310: current_type_name->accept(*this); laurent@310: s4o.print(" __CHECK_"); lbessard@98: symbol->integer_type_name->accept(*this); laurent@310: s4o.print("\n"); lbessard@98: } laurent@310: break; laurent@310: default: laurent@310: break; laurent@310: } laurent@310: } laurent@310: else { laurent@310: symbol->integer_type_name->accept(*basedecl); lbessard@98: } lbessard@98: return NULL; lbessard@98: } lbessard@98: lbessard@98: /* signed_integer DOTDOT signed_integer */ lbessard@98: void *visit(subrange_c *symbol) { lbessard@98: int dimension; lbessard@98: switch (current_typedefinition) { lbessard@98: case array_td: lbessard@98: if (current_basetypedeclaration == arraysubrange_bd) { lbessard@121: s4o_incl.print("["); msousa@594: s4o_incl.print(symbol->dimension); lbessard@121: s4o_incl.print("]"); lbessard@98: } lbessard@98: else lbessard@98: symbol->lower_limit->accept(*this); lbessard@98: break; lbessard@98: case subrange_td: lbessard@98: s4o.print(s4o.indent_spaces + "if (value < "); lbessard@98: symbol->lower_limit->accept(*this); lbessard@98: s4o.print(")\n"); lbessard@98: s4o.indent_right(); lbessard@98: s4o.print(s4o.indent_spaces + "return "); lbessard@98: symbol->lower_limit->accept(*this); lbessard@98: s4o.print(";\n"); lbessard@98: s4o.indent_left(); lbessard@98: s4o.print(s4o.indent_spaces + "else if (value > "); lbessard@98: symbol->upper_limit->accept(*this); lbessard@98: s4o.print(")\n"); lbessard@98: s4o.indent_right(); lbessard@98: s4o.print(s4o.indent_spaces + "return "); lbessard@98: symbol->upper_limit->accept(*this); lbessard@98: s4o.print(";\n"); lbessard@98: s4o.indent_left(); lbessard@98: s4o.print(s4o.indent_spaces + "else\n"); lbessard@98: s4o.indent_right(); lbessard@98: s4o.print(s4o.indent_spaces + "return value;\n"); lbessard@98: s4o.indent_left(); lbessard@98: default: lbessard@98: break; lbessard@98: } lbessard@98: return NULL; lbessard@98: } lbessard@98: lbessard@98: /* enumerated_type_name ':' enumerated_spec_init */ lbessard@98: void *visit(enumerated_type_declaration_c *symbol) { lbessard@98: TRACE("enumerated_type_declaration_c"); lbessard@98: laurent@310: current_typedefinition = enumerated_td; laurent@328: current_type_name = symbol->enumerated_type_name; laurent@310: laurent@327: s4o_incl.print("__DECLARE_ENUMERATED_TYPE("); laurent@328: current_type_name->accept(*basedecl); laurent@327: s4o_incl.print(",\n"); lbessard@121: s4o_incl.indent_right(); lbessard@98: symbol->enumerated_spec_init->accept(*this); lbessard@121: s4o_incl.indent_left(); laurent@327: s4o_incl.print(")\n"); laurent@310: laurent@328: current_type_name = NULL; laurent@310: current_typedefinition = none_td; laurent@310: lbessard@70: return NULL; lbessard@70: } lbessard@70: laurent@328: /* enumerated_specification ASSIGN enumerated_value */ lbessard@70: void *visit(enumerated_spec_init_c *symbol) { lbessard@70: TRACE("enumerated_spec_init_c"); laurent@310: if (current_typedefinition == enumerated_td) laurent@310: symbol->enumerated_specification->accept(*this); laurent@310: else laurent@310: symbol->enumerated_specification->accept(*basedecl); lbessard@98: return NULL; lbessard@98: } lbessard@98: lbessard@98: /* helper symbol for enumerated_specification->enumerated_spec_init */ lbessard@98: /* enumerated_value_list ',' enumerated_value */ lbessard@98: void *visit(enumerated_value_list_c *symbol) { lbessard@121: print_list_incl(symbol, s4o_incl.indent_spaces, ",\n"+s4o_incl.indent_spaces, "\n"); lbessard@98: return NULL; lbessard@98: } lbessard@98: lbessard@98: /* enumerated_type_name '#' identifier */ lbessard@98: void *visit(enumerated_value_c *symbol) { laurent@328: symbol_c *value_type; laurent@328: if (current_typedefinition == enumerated_td) laurent@328: current_type_name->accept(*basedecl); laurent@328: else { laurent@328: value_type = (symbol_c *)symbol->accept(search_constant_type); laurent@328: if (value_type == NULL) ERROR; laurent@328: laurent@328: value_type->accept(*basedecl); laurent@328: } laurent@329: s4o_incl.print("__"); lbessard@121: symbol->value->accept(*basedecl); lbessard@98: return NULL; lbessard@98: } lbessard@98: lbessard@98: /* identifier ':' array_spec_init */ lbessard@98: void *visit(array_type_declaration_c *symbol) { lbessard@98: TRACE("array_type_declaration_c"); lbessard@98: laurent@310: current_typedefinition = array_td; laurent@328: current_type_name = symbol->identifier; laurent@310: laurent@309: array_is_derived = false; laurent@309: current_basetypedeclaration = arrayderiveddeclaration_bd; laurent@309: symbol->array_spec_init->accept(*this); laurent@309: current_basetypedeclaration = none_bd; laurent@309: laurent@309: if (array_is_derived) Laurent@706: s4o_incl.print("__DECLARE_DERIVED_TYPE("); laurent@309: else Laurent@706: s4o_incl.print("__DECLARE_ARRAY_TYPE("); laurent@328: current_type_name->accept(*basedecl); laurent@327: s4o_incl.print(","); lbessard@121: current_basetypedeclaration = arraybasetypeincl_bd; lbessard@98: symbol->array_spec_init->accept(*this); lbessard@98: current_basetypedeclaration = none_bd; laurent@309: if (!array_is_derived) { Laurent@706: s4o_incl.print(","); Laurent@706: current_basetypedeclaration = arraysubrange_bd; Laurent@706: symbol->array_spec_init->accept(*this); Laurent@706: current_basetypedeclaration = none_bd; laurent@309: } laurent@221: s4o_incl.print(")\n"); laurent@322: laurent@328: current_type_name = NULL; laurent@310: current_typedefinition = none_td; laurent@310: lbessard@98: return NULL; lbessard@98: } lbessard@98: lbessard@160: /* array_specification [ASSIGN array_initialization] */ lbessard@98: /* array_initialization may be NULL ! */ lbessard@98: void *visit(array_spec_init_c *symbol) { lbessard@98: TRACE("array_spec_init_c"); lbessard@160: laurent@322: if (current_typedefinition == array_td) { laurent@322: switch (current_basetypedeclaration) { Laurent@706: case arrayderiveddeclaration_bd: Laurent@706: array_is_derived = dynamic_cast(symbol->array_specification) != NULL; Laurent@706: break; Laurent@706: default: Laurent@706: if (array_is_derived) Laurent@706: symbol->array_specification->accept(*basedecl); Laurent@706: else Laurent@706: symbol->array_specification->accept(*this); Laurent@706: break; laurent@322: } laurent@322: } laurent@322: else { Laurent@706: symbol->array_specification->accept(*basedecl); lbessard@160: } lbessard@98: return NULL; lbessard@98: } lbessard@98: lbessard@98: /* ARRAY '[' array_subrange_list ']' OF non_generic_type_name */ lbessard@98: void *visit(array_specification_c *symbol) { lbessard@98: switch (current_basetypedeclaration) { lbessard@98: case arraybasetype_bd: lbessard@98: symbol->non_generic_type_name->accept(*this); lbessard@98: break; lbessard@121: case arraybasetypeincl_bd: lbessard@121: symbol->non_generic_type_name->accept(*basedecl); lbessard@121: break; lbessard@98: case arraysubrange_bd: lbessard@98: symbol->array_subrange_list->accept(*this); lbessard@98: break; lbessard@98: default: lbessard@98: break; lbessard@98: } lbessard@98: return NULL; lbessard@98: } lbessard@98: lbessard@98: /* helper symbol for array_specification */ lbessard@98: /* array_subrange_list ',' subrange */ lbessard@98: void *visit(array_subrange_list_c *symbol) { laurent@377: print_list(symbol); lbessard@70: return NULL; lbessard@70: } lbessard@70: lbessard@70: /* TYPE type_declaration_list END_TYPE */ lbessard@70: void *visit(data_type_declaration_c *symbol) { lbessard@70: TRACE("data_type_declaration_c"); lbessard@70: symbol->type_declaration_list->accept(*this); lbessard@70: s4o.print("\n\n"); lbessard@70: return NULL; lbessard@70: } lbessard@70: lbessard@70: /* helper symbol for data_type_declaration */ lbessard@70: void *visit(type_declaration_list_c *symbol) { lbessard@70: TRACE("type_declaration_list_c"); lbessard@160: return print_list_incl(symbol, "", "\n", "\n"); lbessard@70: } lbessard@70: lbessard@70: /* simple_type_name ':' simple_spec_init */ lbessard@70: void *visit(simple_type_declaration_c *symbol) { lbessard@70: TRACE("simple_type_declaration_c"); lbessard@70: msousa@307: s4o_incl.print("__DECLARE_DERIVED_TYPE("); laurent@327: symbol->simple_type_name->accept(*basedecl); laurent@327: s4o_incl.print(","); lbessard@70: symbol->simple_spec_init->accept(*this); laurent@309: s4o_incl.print(")\n"); laurent@377: laurent@377: if (search_base_type.type_is_subrange(symbol->simple_type_name)) { Laurent@706: s4o.print("#define __CHECK_"); Laurent@706: current_type_name->accept(*this); Laurent@706: s4o.print(" __CHECK_"); Laurent@706: symbol->simple_spec_init->accept(*this); Laurent@706: s4o.print("\n"); laurent@377: } laurent@377: lbessard@70: return NULL; lbessard@70: } lbessard@70: lbessard@70: /* simple_specification [ASSIGN constant] */ lbessard@70: //SYM_REF2(simple_spec_init_c, simple_specification, constant) lbessard@70: // may be NULL lbessard@70: void *visit(simple_spec_init_c *symbol) { lbessard@70: TRACE("simple_spec_init_c"); lbessard@121: symbol->simple_specification->accept(*basedecl); lbessard@70: return NULL; lbessard@70: } lbessard@70: lbessard@70: #if 0 lbessard@70: /* subrange_type_name ':' subrange_spec_init */ lbessard@70: SYM_REF2(subrange_type_declaration_c, subrange_type_name, subrange_spec_init) lbessard@70: lbessard@70: /* subrange_specification ASSIGN signed_integer */ lbessard@70: SYM_REF2(subrange_spec_init_c, subrange_specification, signed_integer) lbessard@70: lbessard@70: /* integer_type_name '(' subrange')' */ lbessard@70: SYM_REF2(subrange_specification_c, integer_type_name, subrange) lbessard@70: lbessard@70: /* signed_integer DOTDOT signed_integer */ lbessard@70: SYM_REF2(subrange_c, lower_limit, upper_limit) lbessard@70: lbessard@70: /* enumerated_type_name ':' enumerated_spec_init */ lbessard@70: SYM_REF2(enumerated_type_declaration_c, enumerated_type_name, enumerated_spec_init) lbessard@70: lbessard@70: /* enumerated_specification ASSIGN enumerated_value */ lbessard@70: SYM_REF2(enumerated_spec_init_c, enumerated_specification, enumerated_value) lbessard@70: lbessard@70: /* helper symbol for enumerated_specification->enumerated_spec_init */ lbessard@70: /* enumerated_value_list ',' enumerated_value */ lbessard@70: SYM_LIST(enumerated_value_list_c) lbessard@70: lbessard@70: /* enumerated_type_name '#' identifier */ lbessard@70: SYM_REF2(enumerated_value_c, type, value) lbessard@70: lbessard@70: /* identifier ':' array_spec_init */ lbessard@70: SYM_REF2(array_type_declaration_c, identifier, array_spec_init) lbessard@70: lbessard@70: /* array_specification [ASSIGN array_initialization} */ lbessard@70: /* array_initialization may be NULL ! */ lbessard@70: SYM_REF2(array_spec_init_c, array_specification, array_initialization) lbessard@70: lbessard@70: /* ARRAY '[' array_subrange_list ']' OF non_generic_type_name */ lbessard@70: SYM_REF2(array_specification_c, array_subrange_list, non_generic_type_name) lbessard@70: lbessard@70: /* helper symbol for array_specification */ lbessard@70: /* array_subrange_list ',' subrange */ lbessard@70: SYM_LIST(array_subrange_list_c) lbessard@70: lbessard@70: /* array_initialization: '[' array_initial_elements_list ']' */ lbessard@70: /* helper symbol for array_initialization */ lbessard@70: /* array_initial_elements_list ',' array_initial_elements */ lbessard@70: SYM_LIST(array_initial_elements_list_c) lbessard@70: lbessard@70: /* integer '(' [array_initial_element] ')' */ lbessard@70: /* array_initial_element may be NULL ! */ lbessard@70: SYM_REF2(array_initial_elements_c, integer, array_initial_element) lbessard@70: #endif lbessard@70: lbessard@70: /* structure_type_name ':' structure_specification */ lbessard@70: //SYM_REF2(structure_type_declaration_c, structure_type_name, structure_specification) lbessard@70: void *visit(structure_type_declaration_c *symbol) { lbessard@70: TRACE("structure_type_declaration_c"); lbessard@70: laurent@310: current_typedefinition = struct_td; laurent@310: laurent@221: s4o_incl.print("__DECLARE_STRUCT_TYPE("); laurent@327: symbol->structure_type_name->accept(*basedecl); laurent@327: s4o_incl.print(","); lbessard@70: symbol->structure_specification->accept(*this); laurent@327: s4o_incl.print(")\n"); laurent@310: laurent@310: current_typedefinition = none_td; laurent@310: lbessard@70: return NULL; lbessard@70: } lbessard@70: lbessard@70: /* structure_type_name ASSIGN structure_initialization */ lbessard@70: /* structure_initialization may be NULL ! */ lbessard@70: //SYM_REF2(initialized_structure_c, structure_type_name, structure_initialization) lbessard@70: void *visit(initialized_structure_c *symbol) { lbessard@70: TRACE("initialized_structure_c"); lbessard@164: lbessard@164: symbol->structure_type_name->accept(*basedecl); lbessard@164: lbessard@70: return NULL; lbessard@70: } lbessard@70: lbessard@70: /* helper symbol for structure_declaration */ lbessard@70: /* structure_declaration: STRUCT structure_element_declaration_list END_STRUCT */ lbessard@70: /* structure_element_declaration_list structure_element_declaration ';' */ lbessard@70: //SYM_LIST(structure_element_declaration_list_c) lbessard@70: void *visit(structure_element_declaration_list_c *symbol) { lbessard@70: TRACE("structure_element_declaration_list_c"); laurent@327: s4o_incl.print("\n"); lbessard@160: s4o_incl.indent_right(); lbessard@160: s4o_incl.print(s4o_incl.indent_spaces); lbessard@160: lbessard@160: print_list_incl(symbol, "", s4o_incl.indent_spaces, ""); lbessard@160: lbessard@160: s4o_incl.indent_left(); lbessard@160: s4o_incl.print(s4o_incl.indent_spaces); lbessard@70: return NULL; lbessard@70: } lbessard@70: lbessard@70: /* structure_element_name ':' spec_init */ lbessard@70: //SYM_REF2(structure_element_declaration_c, structure_element_name, spec_init) lbessard@70: void *visit(structure_element_declaration_c *symbol) { lbessard@70: TRACE("structure_element_declaration_c"); lbessard@70: lbessard@70: symbol->spec_init->accept(*this); lbessard@160: s4o_incl.print(" "); lbessard@160: symbol->structure_element_name->accept(*basedecl); lbessard@160: s4o_incl.print(";\n"); lbessard@160: s4o_incl.print(s4o.indent_spaces); lbessard@70: lbessard@70: return NULL; lbessard@70: } lbessard@70: lbessard@70: /* helper symbol for structure_initialization */ lbessard@70: /* structure_initialization: '(' structure_element_initialization_list ')' */ lbessard@70: /* structure_element_initialization_list ',' structure_element_initialization */ lbessard@70: //SYM_LIST(structure_element_initialization_list_c) lbessard@70: void *visit(structure_element_initialization_list_c *symbol) { lbessard@70: TRACE("structure_element_initialization_list_c"); lbessard@70: lbessard@70: // TODO ??? lbessard@160: //ERROR; lbessard@70: return NULL; lbessard@70: } lbessard@70: lbessard@70: /* structure_element_name ASSIGN value */ lbessard@70: //SYM_REF2(structure_element_initialization_c, structure_element_name, value) lbessard@70: void *visit(structure_element_initialization_c *symbol) { lbessard@70: TRACE("structure_element_initialization_c"); lbessard@70: lbessard@70: // TODO ??? lbessard@160: //ERROR; lbessard@70: return NULL; lbessard@70: } lbessard@70: lbessard@70: #if 0 lbessard@70: /* string_type_name ':' elementary_string_type_name string_type_declaration_size string_type_declaration_init */ lbessard@70: /* lbessard@70: * NOTE: lbessard@70: * (Summary: Contrary to what is expected, the lbessard@70: * string_type_declaration_c is not used to store lbessard@70: * simple string type declarations that do not include lbessard@70: * size limits. lbessard@70: * For e.g.: lbessard@70: * str1_type: STRING := "hello!" lbessard@70: * will be stored in a simple_type_declaration_c lbessard@70: * instead of a string_type_declaration_c. lbessard@70: * The following: lbessard@70: * str2_type: STRING [64] := "hello!" lbessard@70: * will be stored in a sring_type_declaration_c lbessard@70: * lbessard@70: * Read on for why this is done... lbessard@70: * End Summary) lbessard@70: * lbessard@70: * According to the spec, the valid construct lbessard@70: * TYPE new_str_type : STRING := "hello!"; END_TYPE lbessard@70: * has two possible routes to type_declaration... lbessard@70: * lbessard@70: * Route 1: lbessard@70: * type_declaration: single_element_type_declaration lbessard@70: * single_element_type_declaration: simple_type_declaration lbessard@70: * simple_type_declaration: identifier ':' simple_spec_init lbessard@70: * simple_spec_init: simple_specification ASSIGN constant lbessard@70: * (shift: identifier <- 'new_str_type') lbessard@70: * simple_specification: elementary_type_name lbessard@70: * elementary_type_name: STRING lbessard@70: * (shift: elementary_type_name <- STRING) lbessard@70: * (reduce: simple_specification <- elementary_type_name) lbessard@70: * (shift: constant <- "hello!") lbessard@70: * (reduce: simple_spec_init: simple_specification ASSIGN constant) lbessard@70: * (reduce: ...) lbessard@70: * lbessard@70: * lbessard@70: * Route 2: lbessard@70: * type_declaration: string_type_declaration lbessard@70: * string_type_declaration: identifier ':' elementary_string_type_name string_type_declaration_size string_type_declaration_init lbessard@70: * (shift: identifier <- 'new_str_type') lbessard@70: * elementary_string_type_name: STRING lbessard@70: * (shift: elementary_string_type_name <- STRING) lbessard@70: * (shift: string_type_declaration_size <- empty ) lbessard@70: * string_type_declaration_init: ASSIGN character_string lbessard@70: * (shift: character_string <- "hello!") lbessard@70: * (reduce: string_type_declaration_init <- ASSIGN character_string) lbessard@70: * (reduce: string_type_declaration <- identifier ':' elementary_string_type_name string_type_declaration_size string_type_declaration_init ) lbessard@70: * (reduce: type_declaration <- string_type_declaration) lbessard@70: * lbessard@70: * lbessard@70: * At first glance it seems that removing route 1 would make lbessard@70: * the most sense. Unfortunately the construct 'simple_spec_init' lbessard@70: * shows up multiple times in other rules, so changing this construct lbessard@70: * would also mean changing all the rules in which it appears. lbessard@70: * I (Mario) therefore chose to remove route 2 instead. This means lbessard@70: * that the above declaration gets stored in a lbessard@70: * simple_type_declaration_c, and not in a string_type_declaration_c lbessard@70: * as would be expected! lbessard@70: */ lbessard@70: /* string_type_name ':' elementary_string_type_name string_type_declaration_size string_type_declaration_init */ lbessard@70: SYM_REF4(string_type_declaration_c, string_type_name, lbessard@70: elementary_string_type_name, lbessard@70: string_type_declaration_size, lbessard@70: string_type_declaration_init) /* may be == NULL! */ lbessard@70: #endif lbessard@70: lbessard@70: /*********************/ lbessard@70: /* B 1.4 - Variables */ lbessard@70: /*********************/ lbessard@70: /* done in base class(es) */ lbessard@70: lbessard@70: /********************************************/ lbessard@70: /* B.1.4.1 Directly Represented Variables */ lbessard@70: /********************************************/ lbessard@70: // direct_variable: direct_variable_token {$$ = new direct_variable_c($1);}; lbessard@70: void *visit(direct_variable_c *symbol) { lbessard@70: TRACE("direct_variable_c"); lbessard@70: /* Do not use print_token() as it will change everything into uppercase */ lbessard@70: if (strlen(symbol->value) == 0) ERROR; lbessard@70: return s4o.printlocation(symbol->value + 1); lbessard@70: } lbessard@70: lbessard@70: lbessard@70: /*************************************/ lbessard@70: /* B.1.4.2 Multi-element Variables */ lbessard@70: /*************************************/ lbessard@70: /* done in base class(es) */ lbessard@70: lbessard@70: /******************************************/ lbessard@70: /* B 1.4.3 - Declaration & Initialisation */ lbessard@70: /******************************************/ lbessard@70: /* leave for derived classes... */ lbessard@70: lbessard@70: /**************************************/ lbessard@70: /* B.1.5 - Program organization units */ lbessard@70: /**************************************/ lbessard@70: /***********************/ lbessard@70: /* B 1.5.1 - Functions */ lbessard@70: /***********************/ lbessard@70: /* leave for derived classes... */ lbessard@70: lbessard@70: /*****************************/ lbessard@70: /* B 1.5.2 - Function Blocks */ lbessard@70: /*****************************/ lbessard@70: /* leave for derived classes... */ lbessard@70: lbessard@70: /**********************/ lbessard@70: /* B 1.5.3 - Programs */ lbessard@70: /**********************/ lbessard@70: /* leave for derived classes... */ lbessard@70: lbessard@70: /*********************************************/ lbessard@70: /* B.1.6 Sequential function chart elements */ lbessard@70: /*********************************************/ lbessard@70: lbessard@70: /********************************/ lbessard@70: /* B 1.7 Configuration elements */ lbessard@70: /********************************/ lbessard@70: /* leave for derived classes... */ lbessard@70: lbessard@70: /****************************************/ lbessard@70: /* B.2 - Language IL (Instruction List) */ lbessard@70: /****************************************/ lbessard@70: /***********************************/ lbessard@70: /* B 2.1 Instructions and Operands */ lbessard@70: /***********************************/ lbessard@70: /* leave for derived classes... */ lbessard@70: lbessard@70: /*******************/ lbessard@70: /* B 2.2 Operators */ lbessard@70: /*******************/ lbessard@70: /* leave for derived classes... */ lbessard@70: lbessard@70: lbessard@70: /***************************************/ lbessard@70: /* B.3 - Language ST (Structured Text) */ lbessard@70: /***************************************/ lbessard@70: /***********************/ lbessard@70: /* B 3.1 - Expressions */ lbessard@70: /***********************/ lbessard@70: /* leave for derived classes... */ lbessard@70: lbessard@70: /********************/ lbessard@70: /* B 3.2 Statements */ lbessard@70: /********************/ lbessard@70: /* leave for derived classes... */ lbessard@70: lbessard@70: /*********************************/ lbessard@70: /* B 3.2.1 Assignment Statements */ lbessard@70: /*********************************/ lbessard@70: /* leave for derived classes... */ lbessard@70: lbessard@70: /*****************************************/ lbessard@70: /* B 3.2.2 Subprogram Control Statements */ lbessard@70: /*****************************************/ lbessard@70: /* leave for derived classes... */ lbessard@70: lbessard@70: /********************************/ lbessard@70: /* B 3.2.3 Selection Statements */ lbessard@70: /********************************/ lbessard@70: /* leave for derived classes... */ lbessard@70: lbessard@70: /********************************/ lbessard@70: /* B 3.2.4 Iteration Statements */ lbessard@70: /********************************/ lbessard@70: /* leave for derived classes... */ lbessard@70: lbessard@70: lbessard@70: lbessard@70: lbessard@70: }; /* generate_c_typedecl_c */ lbessard@70: lbessard@70: lbessard@70: