# HG changeset patch # User laurent # Date 1316033919 -7200 # Node ID 60b012b7793f129e640208d1d8e876329c4b28a0 # Parent 7dcbd84187719495b927a1b306240359f5652aab Adding support for compiling direct array specification inside variable declaration diff -r 7dcbd8418771 -r 60b012b7793f absyntax_utils/Makefile.am --- a/absyntax_utils/Makefile.am Fri Sep 09 12:03:15 2011 +0200 +++ b/absyntax_utils/Makefile.am Wed Sep 14 22:58:39 2011 +0200 @@ -6,6 +6,7 @@ absyntax_utils.cc \ add_en_eno_param_decl.cc \ decompose_var_instance_name.cc \ + array_dimension_iterator.cc \ case_element_iterator.cc \ function_call_iterator.cc \ function_call_param_iterator.cc \ diff -r 7dcbd8418771 -r 60b012b7793f absyntax_utils/Makefile.in --- a/absyntax_utils/Makefile.in Fri Sep 09 12:03:15 2011 +0200 +++ b/absyntax_utils/Makefile.in Wed Sep 14 22:58:39 2011 +0200 @@ -73,6 +73,7 @@ am_libabsyntax_utils_a_OBJECTS = absyntax_utils.$(OBJEXT) \ add_en_eno_param_decl.$(OBJEXT) \ decompose_var_instance_name.$(OBJEXT) \ + array_dimension_iterator.$(OBJEXT) \ case_element_iterator.$(OBJEXT) \ function_call_iterator.$(OBJEXT) \ function_call_param_iterator.$(OBJEXT) \ @@ -205,6 +206,7 @@ absyntax_utils.cc \ add_en_eno_param_decl.cc \ decompose_var_instance_name.cc \ + array_dimension_iterator.cc \ case_element_iterator.cc \ function_call_iterator.cc \ function_call_param_iterator.cc \ @@ -304,6 +306,7 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/absyntax_utils.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/add_en_eno_param_decl.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/array_dimension_iterator.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/case_element_iterator.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/decompose_var_instance_name.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/function_call_iterator.Po@am__quote@ diff -r 7dcbd8418771 -r 60b012b7793f absyntax_utils/absyntax_utils.hh --- a/absyntax_utils/absyntax_utils.hh Fri Sep 09 12:03:15 2011 +0200 +++ b/absyntax_utils/absyntax_utils.hh Wed Sep 14 22:58:39 2011 +0200 @@ -102,6 +102,7 @@ /***********************************************************************/ #include "spec_init_separator.hh" +#include "array_dimension_iterator.hh" #include "case_element_iterator.hh" #include "function_param_iterator.hh" #include "function_call_iterator.hh" diff -r 7dcbd8418771 -r 60b012b7793f absyntax_utils/array_dimension_iterator.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/absyntax_utils/array_dimension_iterator.cc Wed Sep 14 22:58:39 2011 +0200 @@ -0,0 +1,139 @@ +/* + * matiec - a compiler for the programming languages defined in IEC 61131-3 + * + * Copyright (C) 2003-2011 Mario de Sousa (msousa@fe.up.pt) + * Copyright (C) 2007-2011 Laurent Bessard and Edouard Tisserant + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * + * This code is made available on the understanding that it will not be + * used in safety-critical situations without a full and competent review. + */ + +/* + * An IEC 61131-3 compiler. + * + * Based on the + * FINAL DRAFT - IEC 61131-3, 2nd Ed. (2001-12-10) + * + */ + + +/* + * Array dimension iterator. + * Iterate through the dimensions of array specification. + * + * This is part of the 4th stage that generates + * a c++ source program equivalent to the IL and ST + * code. + */ + +/* Given a array_specification_c, iterate through + * each subrange, returning the symbol of each subrange + * ...array_dimension_iterator_c + */ + + + + +#include "array_dimension_iterator.hh" + + +//#define DEBUG +#ifdef DEBUG +#define TRACE(classname) printf("\n____%s____\n",classname); +#else +#define TRACE(classname) +#endif + + +#define ERROR error_exit(__FILE__,__LINE__) +/* function defined in main.cc */ +extern void error_exit(const char *file_name, int line_no); + +void* array_dimension_iterator_c::iterate_list(list_c *list) { + void *res; + for (int i = 0; i < list->n; i++) { + res = list->elements[i]->accept(*this); + if (res != NULL) + return res; + } + return NULL; +} + +/* start off at the first case element once again... */ +void array_dimension_iterator_c::reset(void) { + current_array_dimension = NULL; +} + + +/* initialize the iterator object. + * We must be given a reference to a array_specification_c that will be analyzed... + */ +array_dimension_iterator_c::array_dimension_iterator_c(symbol_c *symbol) { + /* do some consistency check... */ + array_specification_c* array_spec = dynamic_cast(symbol); + + if (NULL == array_spec) ERROR; + + /* OK. Now initialize this object... */ + this->array_specification = symbol; + reset(); +} + + + +/* Skip to the next subrange. After object creation, + * the object references on subrange _before_ the first, so + * this function must be called once to get the object to + * reference the first subrange... + * + * Returns the subrange symbol! + */ +symbol_c *array_dimension_iterator_c::next(void) { + void *res = array_specification->accept(*this); + if (res == NULL) + return NULL; + + return current_array_dimension; +} + +/********************************/ +/* B 1.3.3 - Derived data types */ +/********************************/ +/* signed_integer DOTDOT signed_integer */ +void *array_dimension_iterator_c::visit(subrange_c *symbol) { + if (current_array_dimension == symbol) { + current_array_dimension = NULL; + } + else if (current_array_dimension == NULL) { + current_array_dimension = symbol; + return symbol; + } + + /* Not found! */ + return NULL; +} + +/* ARRAY '[' array_subrange_list ']' OF non_generic_type_name */ +void *array_dimension_iterator_c::visit(array_specification_c *symbol) { + return symbol->array_subrange_list->accept(*this); +} + +/* array_subrange_list ',' subrange */ +void *array_dimension_iterator_c::visit(array_subrange_list_c *symbol) { + return iterate_list(symbol); +} + diff -r 7dcbd8418771 -r 60b012b7793f absyntax_utils/array_dimension_iterator.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/absyntax_utils/array_dimension_iterator.hh Wed Sep 14 22:58:39 2011 +0200 @@ -0,0 +1,101 @@ +/* + * matiec - a compiler for the programming languages defined in IEC 61131-3 + * + * Copyright (C) 2003-2011 Mario de Sousa (msousa@fe.up.pt) + * Copyright (C) 2007-2011 Laurent Bessard and Edouard Tisserant + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * + * This code is made available on the understanding that it will not be + * used in safety-critical situations without a full and competent review. + */ + +/* + * An IEC 61131-3 compiler. + * + * Based on the + * FINAL DRAFT - IEC 61131-3, 2nd Ed. (2001-12-10) + * + */ + + +/* + * Array dimension iterator. + * Iterate through the dimensions of array specification. + * + * This is part of the 4th stage that generates + * a c++ source program equivalent to the IL and ST + * code. + */ + +/* Given a array_specification_c, iterate through + * each subrange, returning the symbol of each subrange + * ...array_dimension_iterator_c + */ + + +#include "../absyntax/visitor.hh" + + +class array_dimension_iterator_c : public null_visitor_c { + private: + /* a pointer to the array_specification_c currently being analyzed */ + symbol_c *array_specification; + /* used when called to iterate() for a parameter */ + symbol_c *current_array_dimension; + + private: + void* iterate_list(list_c *list); + + public: + /* start off at the first dimension once again... */ + void reset(void); + + /* initialize the iterator object. + * We must be given a reference to a case_list_c that will be analyzed... + */ + array_dimension_iterator_c(symbol_c *symbol); + + /* Skip to the next subrange. After object creation, + * the object references on subrange _before_ the first, so + * this function must be called once to get the object to + * reference the first subrange... + * + * Returns the subrange symbol! + */ + symbol_c *next(void); + + private: + + /********************************/ + /* B 1.3.3 - Derived data types */ + /********************************/ + /* signed_integer DOTDOT signed_integer */ + void *visit(subrange_c *symbol); + + /* ARRAY '[' array_subrange_list ']' OF non_generic_type_name */ + void *visit(array_specification_c *symbol); + + /* array_subrange_list ',' subrange */ + void *visit(array_subrange_list_c *symbol); + +}; // function_param_iterator_c + + + + + + + diff -r 7dcbd8418771 -r 60b012b7793f absyntax_utils/case_element_iterator.cc --- a/absyntax_utils/case_element_iterator.cc Fri Sep 09 12:03:15 2011 +0200 +++ b/absyntax_utils/case_element_iterator.cc Wed Sep 14 22:58:39 2011 +0200 @@ -93,8 +93,8 @@ } -/* initialise the iterator object. - * We must be given a reference to a case_list_c that will be analysed... +/* initialize the iterator object. + * We must be given a reference to a case_list_c that will be analyzed... */ case_element_iterator_c::case_element_iterator_c(symbol_c *list, case_element_t element_type) { /* do some consistency check... */ @@ -102,7 +102,7 @@ if (NULL == case_list) ERROR; - /* OK. Now initialise this object... */ + /* OK. Now initialize this object... */ this->case_list = list; this->wanted_element_type = element_type; reset(); diff -r 7dcbd8418771 -r 60b012b7793f absyntax_utils/case_element_iterator.hh --- a/absyntax_utils/case_element_iterator.hh Fri Sep 09 12:03:15 2011 +0200 +++ b/absyntax_utils/case_element_iterator.hh Wed Sep 14 22:58:39 2011 +0200 @@ -60,9 +60,7 @@ private: - /* a pointer to the function_block_declaration_c - * or function_declaration_c currently being analysed. - */ + /* a pointer to the case_list_c currently being analyzed */ symbol_c *case_list; /* used when called to iterate() for a parameter */ symbol_c *current_case_element; @@ -79,8 +77,8 @@ /* start off at the first case element once again... */ void reset(void); - /* initialise the iterator object. - * We must be given a reference to a case_list_c that will be analysed... + /* initialize the iterator object. + * We must be given a reference to a case_list_c that will be analyzed... */ case_element_iterator_c(symbol_c *list, case_element_t element_type); diff -r 7dcbd8418771 -r 60b012b7793f absyntax_utils/search_base_type.cc --- a/absyntax_utils/search_base_type.cc Fri Sep 09 12:03:15 2011 +0200 +++ b/absyntax_utils/search_base_type.cc Wed Sep 14 22:58:39 2011 +0200 @@ -227,7 +227,8 @@ /* ARRAY '[' array_subrange_list ']' OF non_generic_type_name */ void *search_base_type_c::visit(array_specification_c *symbol) { - if (NULL == this->current_type_name) ERROR; + if (NULL == this->current_type_name) + this->current_type_name = symbol->non_generic_type_name; return symbol->non_generic_type_name->accept(*this); } diff -r 7dcbd8418771 -r 60b012b7793f absyntax_utils/search_base_type.hh --- a/absyntax_utils/search_base_type.hh Fri Sep 09 12:03:15 2011 +0200 +++ b/absyntax_utils/search_base_type.hh Wed Sep 14 22:58:39 2011 +0200 @@ -52,6 +52,7 @@ private: symbol_c *current_type_name; + bool is_array; bool is_subrange; bool is_enumerated; diff -r 7dcbd8418771 -r 60b012b7793f absyntax_utils/search_varfb_instance_type.cc --- a/absyntax_utils/search_varfb_instance_type.cc Fri Sep 09 12:03:15 2011 +0200 +++ b/absyntax_utils/search_varfb_instance_type.cc Wed Sep 14 22:58:39 2011 +0200 @@ -269,20 +269,19 @@ /* identifier ':' array_spec_init */ void *search_varfb_instance_type_c::visit(array_type_declaration_c *symbol) { - this->is_complex = true; return symbol->array_spec_init->accept(*this); } /* array_specification [ASSIGN array_initialization] */ /* array_initialization may be NULL ! */ void *search_varfb_instance_type_c::visit(array_spec_init_c *symbol) { - this->is_complex = true; return symbol->array_specification->accept(*this); } /* ARRAY '[' array_subrange_list ']' OF non_generic_type_name */ void *search_varfb_instance_type_c::visit(array_specification_c *symbol) { this->is_complex = true; + this->current_typeid = symbol; return symbol->non_generic_type_name->accept(*this); } diff -r 7dcbd8418771 -r 60b012b7793f lib/accessor.h --- a/lib/accessor.h Fri Sep 09 12:03:15 2011 +0200 +++ b/lib/accessor.h Wed Sep 14 22:58:39 2011 +0200 @@ -1,6 +1,7 @@ #ifndef __ACCESSOR_H #define __ACCESSOR_H +#define __INITIAL_VALUE(...) __VA_ARGS__ // variable declaration macros #define __DECLARE_VAR(type, name)\ @@ -45,9 +46,12 @@ #define __INIT_VAR(name, initial, retained)\ name.value = initial;\ __INIT_RETAIN(name, retained) -#define __INIT_GLOBAL(name, initial, retained)\ - __INIT_GLOBAL_##name(initial);\ - __INIT_RETAIN((*GLOBAL__##name), retained) +#define __INIT_GLOBAL(type, name, initial, retained)\ + {\ + static const type temp = initial;\ + __INIT_GLOBAL_##name(temp);\ + __INIT_RETAIN((*GLOBAL__##name), retained)\ + } #define __INIT_GLOBAL_LOCATED(resource, name, location, retained)\ resource##__##name.value = location;\ __INIT_RETAIN(resource##__##name, retained) diff -r 7dcbd8418771 -r 60b012b7793f stage1_2/iec_bison.yy --- a/stage1_2/iec_bison.yy Fri Sep 09 12:03:15 2011 +0200 +++ b/stage1_2/iec_bison.yy Wed Sep 14 22:58:39 2011 +0200 @@ -3004,6 +3004,7 @@ array_initial_elements: array_initial_element | integer '(' ')' + {$$ = new array_initial_elements_c($1, NULL, locloc(@$));} | integer '(' array_initial_element ')' {$$ = new array_initial_elements_c($1, $3, locloc(@$));} /* ERROR_CHECK_BEGIN */ diff -r 7dcbd8418771 -r 60b012b7793f stage4/generate_c/generate_c.cc --- a/stage4/generate_c/generate_c.cc Fri Sep 09 12:03:15 2011 +0200 +++ b/stage4/generate_c/generate_c.cc Wed Sep 14 22:58:39 2011 +0200 @@ -27,6 +27,8 @@ #include #include #include +#include +#include #include #include "../../util/symtable.hh" @@ -111,7 +113,6 @@ #define INIT_LOCATED "__INIT_LOCATED" #define INIT_LOCATED_VALUE "__INIT_LOCATED_VALUE" - /* Variable getter symbol for accessor macros */ #define GET_VAR "__GET_VAR" #define GET_EXTERNAL "__GET_EXTERNAL" @@ -581,6 +582,370 @@ /***********************************************************************/ +class generate_c_datatypes_c: public generate_c_typedecl_c { + public: + typedef enum { + none_im, + arrayname_im, + arraydeclaration_im, + } inlinearray_mode_t; + + private: + stage4out_c *s4o_ptr; + std::map inline_array_defined; + std::string current_array_name; + inlinearray_mode_t current_mode; + + public: + generate_c_datatypes_c(stage4out_c *s4o_ptr, stage4out_c *s4o_incl_ptr) + : generate_c_typedecl_c(s4o_ptr, s4o_incl_ptr) { + generate_c_datatypes_c::s4o_ptr = s4o_ptr; + current_mode = none_im; + }; + virtual ~generate_c_datatypes_c(void) { + while (!inline_array_defined.empty()) { + inline_array_defined.erase(inline_array_defined.begin()); + } + } + + /*************************/ + /* B.1 - Common elements */ + /*************************/ + /*******************************************/ + /* B 1.1 - Letters, digits and identifiers */ + /*******************************************/ + void *visit(identifier_c *symbol) { + switch (current_mode) { + case arrayname_im: + current_array_name += symbol->value; + break; + case arraydeclaration_im: + s4o_incl.print(symbol->value); + break; + default: + return generate_c_base_c::visit(symbol); + break; + } + return NULL; + } + + /**********************/ + /* B.1.3 - Data types */ + /**********************/ + /***********************************/ + /* B 1.3.1 - Elementary Data Types */ + /***********************************/ + + #define HANDLE_ELEMENTARY_DATA_TYPE(datatype_symbol, datatype_name)\ + void *visit(datatype_symbol *symbol) {\ + switch (current_mode) {\ + case arrayname_im:\ + current_array_name += datatype_name;\ + break;\ + case arraydeclaration_im:\ + s4o_incl.print(datatype_name);\ + break;\ + default:\ + return generate_c_base_c::visit(symbol);\ + break;\ + }\ + return NULL;\ + } + + HANDLE_ELEMENTARY_DATA_TYPE(time_type_name_c, "TIME") + HANDLE_ELEMENTARY_DATA_TYPE(bool_type_name_c, "BOOL") + HANDLE_ELEMENTARY_DATA_TYPE(sint_type_name_c, "SINT") + HANDLE_ELEMENTARY_DATA_TYPE(int_type_name_c, "INT") + HANDLE_ELEMENTARY_DATA_TYPE(dint_type_name_c, "DINT") + HANDLE_ELEMENTARY_DATA_TYPE(lint_type_name_c, "LINT") + HANDLE_ELEMENTARY_DATA_TYPE(usint_type_name_c, "USINT") + HANDLE_ELEMENTARY_DATA_TYPE(uint_type_name_c, "UINT") + HANDLE_ELEMENTARY_DATA_TYPE(udint_type_name_c, "UDINT") + HANDLE_ELEMENTARY_DATA_TYPE(ulint_type_name_c, "ULINT") + HANDLE_ELEMENTARY_DATA_TYPE(real_type_name_c, "REAL") + HANDLE_ELEMENTARY_DATA_TYPE(lreal_type_name_c, "LREAL") + HANDLE_ELEMENTARY_DATA_TYPE(date_type_name_c, "DATE") + HANDLE_ELEMENTARY_DATA_TYPE(tod_type_name_c, "TOD") + HANDLE_ELEMENTARY_DATA_TYPE(dt_type_name_c, "DT") + HANDLE_ELEMENTARY_DATA_TYPE(byte_type_name_c, "BYTE") + HANDLE_ELEMENTARY_DATA_TYPE(word_type_name_c, "WORD") + HANDLE_ELEMENTARY_DATA_TYPE(dword_type_name_c, "DWORD") + HANDLE_ELEMENTARY_DATA_TYPE(lword_type_name_c, "LWORD") + HANDLE_ELEMENTARY_DATA_TYPE(string_type_name_c, "STRING") + HANDLE_ELEMENTARY_DATA_TYPE(wstring_type_name_c, "WSTRING") + + HANDLE_ELEMENTARY_DATA_TYPE(safetime_type_name_c, "TIME") + HANDLE_ELEMENTARY_DATA_TYPE(safebool_type_name_c, "BOOL") + HANDLE_ELEMENTARY_DATA_TYPE(safesint_type_name_c, "SINT") + HANDLE_ELEMENTARY_DATA_TYPE(safeint_type_name_c, "INT") + HANDLE_ELEMENTARY_DATA_TYPE(safedint_type_name_c, "DINT") + HANDLE_ELEMENTARY_DATA_TYPE(safelint_type_name_c, "LINT") + HANDLE_ELEMENTARY_DATA_TYPE(safeusint_type_name_c, "USINT") + HANDLE_ELEMENTARY_DATA_TYPE(safeuint_type_name_c, "UINT") + HANDLE_ELEMENTARY_DATA_TYPE(safeudint_type_name_c, "UDINT") + HANDLE_ELEMENTARY_DATA_TYPE(safeulint_type_name_c, "ULINT") + HANDLE_ELEMENTARY_DATA_TYPE(safereal_type_name_c, "REAL") + HANDLE_ELEMENTARY_DATA_TYPE(safelreal_type_name_c, "LREAL") + HANDLE_ELEMENTARY_DATA_TYPE(safedate_type_name_c, "DATE") + HANDLE_ELEMENTARY_DATA_TYPE(safetod_type_name_c, "TOD") + HANDLE_ELEMENTARY_DATA_TYPE(safedt_type_name_c, "DT") + HANDLE_ELEMENTARY_DATA_TYPE(safebyte_type_name_c, "BYTE") + HANDLE_ELEMENTARY_DATA_TYPE(safeword_type_name_c, "WORD") + HANDLE_ELEMENTARY_DATA_TYPE(safedword_type_name_c, "DWORD") + HANDLE_ELEMENTARY_DATA_TYPE(safelword_type_name_c, "LWORD") + HANDLE_ELEMENTARY_DATA_TYPE(safestring_type_name_c, "STRING") + HANDLE_ELEMENTARY_DATA_TYPE(safewstring_type_name_c, "WSTRING") + + /******************************************/ + /* B 1.4.3 - Declaration & Initialization */ + /******************************************/ + + void *visit(input_declarations_c *symbol) { + symbol->input_declaration_list->accept(*this); + return NULL; + } + + void *visit(edge_declaration_c *symbol) { + return NULL; + } + + void *visit(en_param_declaration_c *symbol) { + return NULL; + } + + void *visit(eno_param_declaration_c *symbol) { + return NULL; + } + + void *visit(var1_init_decl_c *symbol) { + return NULL; + } + + /* var1_list ':' array_spec_init */ + // SYM_REF2(array_var_init_decl_c, var1_list, array_spec_init) + void *visit(array_var_init_decl_c *symbol) { + current_mode = arrayname_im; + symbol->array_spec_init->accept(*this); + current_mode = none_im; + return NULL; + } + + /* array_specification [ASSIGN array_initialization] */ + /* array_initialization may be NULL ! */ + void *visit(array_spec_init_c *symbol) { + switch (current_mode) { + case arrayname_im: + { + array_specification_c *specification = dynamic_cast(symbol->array_specification); + if (specification != NULL) + symbol->array_specification->accept(*this); + } + break; + default: + return generate_c_typedecl_c::visit(symbol); + break; + } + return NULL; + } + + /* ARRAY '[' array_subrange_list ']' OF non_generic_type_name */ + void *visit(array_specification_c *symbol) { + switch (current_mode) { + case arrayname_im: + { + std::map::iterator definition; + current_array_name = "__"; + symbol->non_generic_type_name->accept(*this); + symbol->array_subrange_list->accept(*this); + + definition = inline_array_defined.find(current_array_name); + if (definition == inline_array_defined.end()) { + current_mode = arraydeclaration_im; + + s4o_incl.print("__DECLARE_ARRAY_TYPE("); + s4o_incl.print(current_array_name); + s4o_incl.print(","); + symbol->non_generic_type_name->accept(*this); + s4o_incl.print(","); + symbol->array_subrange_list->accept(*this); + s4o_incl.print(")\n\n"); + + inline_array_defined[current_array_name] = 0; + } + } + break; + default: + return generate_c_typedecl_c::visit(symbol); + break; + } + return NULL; + } + + /* signed_integer DOTDOT signed_integer */ + //SYM_REF2(subrange_c, lower_limit, upper_limit) + void *visit(subrange_c *symbol) { + int dimension = extract_integer(symbol->upper_limit) - extract_integer(symbol->lower_limit) + 1; + switch (current_mode) { + case arrayname_im: + current_array_name += "_"; + { + std::stringstream ss; + ss << dimension; + current_array_name += ss.str(); + } + break; + case arraydeclaration_im: + s4o_incl.print("["); + s4o_incl.print_integer(dimension); + s4o_incl.print("]"); + default: + generate_c_typedecl_c::visit(symbol); + break; + } + return NULL; + } + + /* var1_list ':' initialized_structure */ + // SYM_REF2(structured_var_init_decl_c, var1_list, initialized_structure) + void *visit(structured_var_init_decl_c *symbol) { + return NULL; + } + + /* fb_name_list ':' function_block_type_name ASSIGN structure_initialization */ + /* structure_initialization -> may be NULL ! */ + void *visit(fb_name_decl_c *symbol) { + return NULL; + } + + /* VAR_OUTPUT [RETAIN | NON_RETAIN] var_init_decl_list END_VAR */ + /* option -> may be NULL ! */ + void *visit(output_declarations_c *symbol) { + symbol->var_init_decl_list->accept(*this); + return NULL; + } + + /* VAR_IN_OUT var_declaration_list END_VAR */ + void *visit(input_output_declarations_c *symbol) { + symbol->var_declaration_list->accept(*this); + return NULL; + } + + /* var1_list ':' array_specification */ + //SYM_REF2(array_var_declaration_c, var1_list, array_specification) + void *visit(array_var_declaration_c *symbol) { + array_specification_c *specification = dynamic_cast(symbol->array_specification); + if (specification != NULL) { + current_mode = arrayname_im; + symbol->array_specification->accept(*this); + current_mode = none_im; + } + return NULL; + } + + /* VAR [CONSTANT] var_init_decl_list END_VAR */ + /* option -> may be NULL ! */ + /* helper symbol for input_declarations */ + void *visit(var_declarations_c *symbol) { + symbol->var_init_decl_list->accept(*this); + return NULL; + } + + /* VAR RETAIN var_init_decl_list END_VAR */ + void *visit(retentive_var_declarations_c *symbol) { + symbol->var_init_decl_list->accept(*this); + return NULL; + } + + /* VAR [CONSTANT|RETAIN|NON_RETAIN] located_var_decl_list END_VAR */ + /* option -> may be NULL ! */ + //SYM_REF2(located_var_declarations_c, option, located_var_decl_list) + void *visit(located_var_declarations_c *symbol) { + symbol->located_var_decl_list->accept(*this); + return NULL; + } + + /* [variable_name] location ':' located_var_spec_init */ + /* variable_name -> may be NULL ! */ + //SYM_REF4(located_var_decl_c, variable_name, location, located_var_spec_init, unused) + void *visit(located_var_decl_c *symbol) { + symbol->located_var_spec_init->accept(*this); + return NULL; + } + + /*| VAR_EXTERNAL [CONSTANT] external_declaration_list END_VAR */ + /* option -> may be NULL ! */ + //SYM_REF2(external_var_declarations_c, option, external_declaration_list) + void *visit(external_var_declarations_c *symbol) { + symbol->external_declaration_list->accept(*this); + return NULL; + } + + /* global_var_name ':' (simple_specification|subrange_specification|enumerated_specification|array_specification|prev_declared_structure_type_name|function_block_type_name */ + //SYM_REF2(external_declaration_c, global_var_name, specification) + void *visit(external_declaration_c *symbol) { + array_specification_c* array_specification = dynamic_cast(symbol->specification); + if (array_specification != NULL) { + current_mode = arrayname_im; + symbol->specification->accept(*this); + current_mode = none_im; + } + return NULL; + } + + /*| VAR_GLOBAL [CONSTANT|RETAIN] global_var_decl_list END_VAR */ + /* option -> may be NULL ! */ + // SYM_REF2(global_var_declarations_c, option, global_var_decl_list) + void *visit(global_var_declarations_c *symbol) { + symbol->global_var_decl_list->accept(*this); + return NULL; + } + + /*| global_var_spec ':' [located_var_spec_init|function_block_type_name] */ + /* type_specification ->may be NULL ! */ + // SYM_REF2(global_var_decl_c, global_var_spec, type_specification) + void *visit(global_var_decl_c *symbol) { + array_spec_init_c* array_spec_init = dynamic_cast(symbol->type_specification); + if (array_spec_init != NULL) { + current_mode = arrayname_im; + symbol->type_specification->accept(*this); + current_mode = none_im; + } + return NULL; + } + + void *visit(function_var_decls_c *symbol) { + symbol->decl_list->accept(*this); + return NULL; + } + + /*****************************/ + /* B 1.5.2 - Function Blocks */ + /*****************************/ + + /* VAR_TEMP temp_var_decl_list END_VAR */ + void *visit(temp_var_decls_c *symbol) { + symbol->var_decl_list->accept(*this); + return NULL; + } + + /* VAR NON_RETAIN var_init_decl_list END_VAR */ + void *visit(non_retentive_var_decls_c *symbol) { + symbol->var_decl_list->accept(*this); + return NULL; + } + +}; + + + + +/***********************************************************************/ +/***********************************************************************/ +/***********************************************************************/ +/***********************************************************************/ +/***********************************************************************/ + + class generate_c_pous_c: public generate_c_typedecl_c { private: stage4out_c *s4o_ptr; @@ -772,15 +1137,15 @@ structure_initialization->init_structure_values(default_value); delete structure_initialization; } - break; + break; case initialization_analyzer_c::array_it: { - generate_c_array_initialization_c *array_initialization = new generate_c_array_initialization_c(&s4o); - array_initialization->init_array_size(symbol->type_name); - array_initialization->init_array_values(default_value); - delete array_initialization; + generate_c_array_initialization_c *array_initialization = new generate_c_array_initialization_c(&s4o); + array_initialization->init_array_size(symbol->type_name); + array_initialization->init_array_values(default_value); + delete array_initialization; } - break; + break; default: default_value->accept(*this); break; @@ -1195,7 +1560,7 @@ : generate_c_typedecl_c(s4o_ptr) { generate_c_config_c::s4o_ptr = s4o_ptr; }; - + virtual ~generate_c_config_c(void) {} typedef enum { @@ -1240,6 +1605,7 @@ s4o.print("/*******************************************/\n\n"); s4o.print("#include \"iec_std_lib.h\"\n\n"); s4o.print("#include \"accessor.h\"\n\n"); + s4o.print("#include \"POUS.h\"\n\n"); /* (A) configuration declaration... */ /* (A.1) configuration name in comment */ @@ -1435,17 +1801,17 @@ unsigned int current_varqualifier; void *print_retain(void) { - s4o.print(","); + s4o.print(","); switch (current_varqualifier) { - case retain_vq: + case retain_vq: s4o.print("1"); break; case non_retain_vq: s4o.print("0"); break; - default: - s4o.print("retain"); - break; + default: + s4o.print("retain"); + break; } return NULL; } @@ -1631,7 +1997,7 @@ break; case init_dt: if (symbol->retain_option != NULL) - symbol->retain_option->accept(*this); + symbol->retain_option->accept(*this); s4o.print(s4o.indent_spaces); symbol->program_type_name->accept(*this); s4o.print(FB_INIT_SUFFIX); @@ -1876,12 +2242,20 @@ /***********************************************************************/ class generate_c_c: public iterator_visitor_c { + public: + typedef enum { + none_gm, + datatypes_gm, + pous_gm, + } generate_mode_t; + protected: stage4out_c &s4o; stage4out_c pous_s4o; stage4out_c pous_incl_s4o; stage4out_c located_variables_s4o; stage4out_c variables_s4o; + generate_c_datatypes_c generate_c_datatypes; generate_c_pous_c generate_c_pous; symbol_c *current_configuration; @@ -1891,6 +2265,8 @@ unsigned long long common_ticktime; + generate_mode_t current_mode; + public: generate_c_c(stage4out_c *s4o_ptr, const char *builddir): s4o(*s4o_ptr), @@ -1898,9 +2274,11 @@ pous_incl_s4o(builddir, "POUS", "h"), located_variables_s4o(builddir, "LOCATED_VARIABLES","h"), variables_s4o(builddir, "VARIABLES","csv"), + generate_c_datatypes(&pous_s4o, &pous_incl_s4o), generate_c_pous(&pous_s4o, &pous_incl_s4o) { current_builddir = builddir; current_configuration = NULL; + current_mode = none_gm; } ~generate_c_c(void) {} @@ -1934,9 +2312,17 @@ /***************************/ void *visit(library_c *symbol) { pous_incl_s4o.print("#ifndef __POUS_H\n#define __POUS_H\n\n#include \"accessor.h\"\n\n"); + + current_mode = datatypes_gm; for(int i = 0; i < symbol->n; i++) { symbol->elements[i]->accept(*this); } + + current_mode = pous_gm; + for(int i = 0; i < symbol->n; i++) { + symbol->elements[i]->accept(*this); + } + pous_incl_s4o.print("#endif //__POUS_H\n"); generate_var_list_c generate_var_list(&variables_s4o, symbol); @@ -1955,8 +2341,8 @@ /* B 1.1 - Letters, digits and identifiers */ /*******************************************/ void *visit(identifier_c *symbol) { - current_name = symbol->value; - return NULL; + current_name = symbol->value; + return NULL; } /********************************/ @@ -1964,7 +2350,13 @@ /********************************/ /* TYPE type_declaration_list END_TYPE */ void *visit(data_type_declaration_c *symbol) { - symbol->accept(generate_c_pous); + switch (current_mode) { + case datatypes_gm: + symbol->accept(generate_c_datatypes); + break; + default: + break; + } return NULL; } @@ -1975,24 +2367,51 @@ /* B 1.5.1 - Functions */ /***********************/ void *visit(function_declaration_c *symbol) { - symbol->accept(generate_c_pous); - return NULL; + switch (current_mode) { + case datatypes_gm: + symbol->var_declarations_list->accept(generate_c_datatypes); + break; + case pous_gm: + symbol->accept(generate_c_pous); + break; + default: + break; + } + return NULL; } /*****************************/ /* B 1.5.2 - Function Blocks */ /*****************************/ void *visit(function_block_declaration_c *symbol) { - symbol->accept(generate_c_pous); - return NULL; + switch (current_mode) { + case datatypes_gm: + symbol->var_declarations->accept(generate_c_datatypes); + break; + case pous_gm: + symbol->accept(generate_c_pous); + break; + default: + break; + } + return NULL; } /**********************/ /* B 1.5.3 - Programs */ /**********************/ void *visit(program_declaration_c *symbol) { - symbol->accept(generate_c_pous); - return NULL; + switch (current_mode) { + case datatypes_gm: + symbol->var_declarations->accept(generate_c_datatypes); + break; + case pous_gm: + symbol->accept(generate_c_pous); + break; + default: + break; + } + return NULL; } @@ -2000,54 +2419,88 @@ /* B 1.7 Configuration elements */ /********************************/ void *visit(configuration_declaration_c *symbol) { - static int configuration_count = 0; - - if (configuration_count++) { - /* the first configuration is the one we will use!! */ - ERROR; + switch (current_mode) { + case datatypes_gm: + if (symbol->global_var_declarations != NULL) + symbol->global_var_declarations->accept(generate_c_datatypes); + break; + + case pous_gm: + static int configuration_count = 0; + + if (configuration_count++) { + /* the first configuration is the one we will use!! */ + ERROR; + } + + current_configuration = symbol; + + { + calculate_common_ticktime_c calculate_common_ticktime; + symbol->accept(calculate_common_ticktime); + common_ticktime = calculate_common_ticktime.get_common_ticktime(); + if (common_ticktime == 0) { + fprintf(stderr, "\nYou must at least define a periodic task to set cycle period!"); + ERROR; + } + + symbol->configuration_name->accept(*this); + + stage4out_c config_s4o(current_builddir, current_name, "c"); + generate_c_config_c generate_c_config(&config_s4o); + symbol->accept(generate_c_config); + + config_s4o.print("unsigned long long common_ticktime__ = "); + config_s4o.print_long_long_integer(common_ticktime); + config_s4o.print("; /*ns*/\n"); + config_s4o.print("unsigned long greatest_tick_count__ = "); + config_s4o.print_long_integer(calculate_common_ticktime.get_greatest_tick_count()); + config_s4o.print("; /*tick*/\n"); + } + + symbol->resource_declarations->accept(*this); + + current_configuration = NULL; + break; + + default: + break; } - - current_configuration = symbol; - - calculate_common_ticktime_c calculate_common_ticktime; - symbol->accept(calculate_common_ticktime); - common_ticktime = calculate_common_ticktime.get_common_ticktime(); - if (common_ticktime == 0) { - fprintf(stderr, "\nYou must at least define a periodic task to set cycle period!"); - ERROR; + return NULL; + } + + void *visit(resource_declaration_c *symbol) { + switch (current_mode) { + case datatypes_gm: + if (symbol->global_var_declarations != NULL) + symbol->global_var_declarations->accept(generate_c_datatypes); + break; + case pous_gm: + symbol->resource_name->accept(*this); + { + stage4out_c resources_s4o(current_builddir, current_name, "c"); + generate_c_resources_c generate_c_resources(&resources_s4o, current_configuration, symbol, common_ticktime); + symbol->accept(generate_c_resources); + } + break; + default: + break; } - - symbol->configuration_name->accept(*this); - stage4out_c config_s4o(current_builddir, current_name, "c"); - generate_c_config_c generate_c_config(&config_s4o); - symbol->accept(generate_c_config); - - config_s4o.print("unsigned long long common_ticktime__ = "); - config_s4o.print_long_long_integer(common_ticktime); - config_s4o.print("; /*ns*/\n"); - config_s4o.print("unsigned long greatest_tick_count__ = "); - config_s4o.print_long_integer(calculate_common_ticktime.get_greatest_tick_count()); - config_s4o.print("; /*tick*/\n"); - - symbol->resource_declarations->accept(*this); - - current_configuration = NULL; - - return NULL; - } - - void *visit(resource_declaration_c *symbol) { - symbol->resource_name->accept(*this); - stage4out_c resources_s4o(current_builddir, current_name, "c"); - generate_c_resources_c generate_c_resources(&resources_s4o, current_configuration, symbol, common_ticktime); - symbol->accept(generate_c_resources); return NULL; } void *visit(single_resource_declaration_c *symbol) { - stage4out_c resources_s4o(current_builddir, "RESOURCE", "c"); - generate_c_resources_c generate_c_resources(&resources_s4o, current_configuration, symbol, common_ticktime); - symbol->accept(generate_c_resources); + switch (current_mode) { + case pous_gm: + { + stage4out_c resources_s4o(current_builddir, "RESOURCE", "c"); + generate_c_resources_c generate_c_resources(&resources_s4o, current_configuration, symbol, common_ticktime); + symbol->accept(generate_c_resources); + } + break; + default: + break; + } return NULL; } diff -r 7dcbd8418771 -r 60b012b7793f stage4/generate_c/generate_c_il.cc --- a/stage4/generate_c/generate_c_il.cc Fri Sep 09 12:03:15 2011 +0200 +++ b/stage4/generate_c/generate_c_il.cc Wed Sep 14 22:58:39 2011 +0200 @@ -548,6 +548,16 @@ #endif +/********************************/ +/* B 1.3.3 - Derived data types */ +/********************************/ + +/* ARRAY '[' array_subrange_list ']' OF non_generic_type_name */ +void *visit(array_specification_c *symbol) { + symbol->non_generic_type_name->accept(*this); + return NULL; +} + /*********************/ /* B 1.4 - Variables */ /*********************/ @@ -676,15 +686,18 @@ /* subscript_list ',' subscript */ void *visit(subscript_list_c *symbol) { + array_dimension_iterator_c* array_dimension_iterator = new array_dimension_iterator_c(current_array_type); for (int i = 0; i < symbol->n; i++) { - s4o.print("[__"); - current_array_type->accept(*this); - s4o.print("_TRANSIDX("); - print_integer(i); - s4o.print(","); + symbol_c* dimension = array_dimension_iterator->next(); + if (dimension == NULL) ERROR; + + s4o.print("[("); symbol->elements[i]->accept(*this); + s4o.print(") - ("); + dimension->accept(*this); s4o.print(")]"); } + delete array_dimension_iterator; return NULL; } diff -r 7dcbd8418771 -r 60b012b7793f stage4/generate_c/generate_c_st.cc --- a/stage4/generate_c/generate_c_st.cc Fri Sep 09 12:03:15 2011 +0200 +++ b/stage4/generate_c/generate_c_st.cc Wed Sep 14 22:58:39 2011 +0200 @@ -223,6 +223,7 @@ /********************************/ /* B 1.3.3 - Derived data types */ /********************************/ + /* signed_integer DOTDOT signed_integer */ void *visit(subrange_c *symbol) { switch (wanted_casegeneration) { @@ -233,11 +234,18 @@ symbol->upper_limit->accept(*this); break; default: + symbol->lower_limit->accept(*this); break; } return NULL; } +/* ARRAY '[' array_subrange_list ']' OF non_generic_type_name */ +void *visit(array_specification_c *symbol) { + symbol->non_generic_type_name->accept(*this); + return NULL; +} + /*********************/ /* B 1.4 - Variables */ /*********************/ @@ -367,15 +375,18 @@ /* subscript_list ',' subscript */ void *visit(subscript_list_c *symbol) { + array_dimension_iterator_c* array_dimension_iterator = new array_dimension_iterator_c(current_array_type); for (int i = 0; i < symbol->n; i++) { - s4o.print("[__"); - current_array_type->accept(*this); - s4o.print("_TRANSIDX("); - print_integer(i); - s4o.print(","); + symbol_c* dimension = array_dimension_iterator->next(); + if (dimension == NULL) ERROR; + + s4o.print("[("); symbol->elements[i]->accept(*this); + s4o.print(") - ("); + dimension->accept(*this); s4o.print(")]"); } + delete array_dimension_iterator; return NULL; } diff -r 7dcbd8418771 -r 60b012b7793f stage4/generate_c/generate_c_typedecl.cc --- a/stage4/generate_c/generate_c_typedecl.cc Fri Sep 09 12:03:15 2011 +0200 +++ b/stage4/generate_c/generate_c_typedecl.cc Wed Sep 14 22:58:39 2011 +0200 @@ -70,10 +70,9 @@ arrayderiveddeclaration_bd, arraybasetype_bd, arraybasetypeincl_bd, - arraysubrange_bd, - arraytranslateindex_bd + arraysubrange_bd } basetypedeclaration_t; - + basetypedeclaration_t current_basetypedeclaration; void print_integer(unsigned int integer) { @@ -373,21 +372,6 @@ } s4o_incl.print(")\n"); - if (search_base_type.type_is_subrange(symbol->identifier)) { - s4o.print("#define __CHECK_"); - current_type_name->accept(*this); - s4o.print(" __CHECK_"); - current_basetypedeclaration = arraybasetype_bd; - symbol->array_spec_init->accept(*this); - current_basetypedeclaration = none_bd; - s4o.print("\n"); - } - - current_basetypedeclaration = arraytranslateindex_bd; - symbol->array_spec_init->accept(*this); - current_basetypedeclaration = none_bd; - s4o.print("\n"); - current_type_name = NULL; current_typedefinition = none_td; @@ -404,18 +388,6 @@ case arrayderiveddeclaration_bd: array_is_derived = dynamic_cast(symbol->array_specification) != NULL; break; - case arraytranslateindex_bd: - if (!array_is_derived) - symbol->array_specification->accept(*this); - s4o.print("#define __"); - current_type_name->accept(*this); - s4o.print("_TRANSIDX(row, index) __"); - if (array_is_derived) - symbol->array_specification->accept(*this); - else - current_type_name->accept(*this); - s4o.print("_TRANSIDX##row(index)"); - break; default: if (array_is_derived) symbol->array_specification->accept(*basedecl); @@ -440,7 +412,6 @@ symbol->non_generic_type_name->accept(*basedecl); break; case arraysubrange_bd: - case arraytranslateindex_bd: symbol->array_subrange_list->accept(*this); break; default: @@ -452,19 +423,7 @@ /* helper symbol for array_specification */ /* array_subrange_list ',' subrange */ void *visit(array_subrange_list_c *symbol) { - if (current_basetypedeclaration == arraytranslateindex_bd) { - for (int i = 0; i < symbol->n; i++) { - s4o.print("#define __"); - current_type_name->accept(*this); - s4o.print("_TRANSIDX"); - print_integer(i); - s4o.print("(index) (index) - "); - symbol->elements[i]->accept(*this); - s4o.print("\n"); - } - } - else - print_list(symbol); + print_list(symbol); return NULL; } @@ -491,6 +450,15 @@ s4o_incl.print(","); symbol->simple_spec_init->accept(*this); s4o_incl.print(")\n"); + + if (search_base_type.type_is_subrange(symbol->simple_type_name)) { + s4o.print("#define __CHECK_"); + current_type_name->accept(*this); + s4o.print(" __CHECK_"); + symbol->simple_spec_init->accept(*this); + s4o.print("\n"); + } + return NULL; } diff -r 7dcbd8418771 -r 60b012b7793f stage4/generate_c/generate_c_vardecl.cc --- a/stage4/generate_c/generate_c_vardecl.cc Fri Sep 09 12:03:15 2011 +0200 +++ b/stage4/generate_c/generate_c_vardecl.cc Wed Sep 14 22:58:39 2011 +0200 @@ -105,7 +105,6 @@ current_mode = typedecl_am; array_specification->accept(*this); - s4o.print(" temp = "); init_array_values(array_initialization); @@ -188,14 +187,21 @@ /* ARRAY '[' array_subrange_list ']' OF non_generic_type_name */ void *visit(array_specification_c *symbol) { - symbol->array_subrange_list->accept(*this); + identifier_c* type_name; switch (current_mode) { case arraysize_am: + symbol->array_subrange_list->accept(*this); array_base_type = symbol->non_generic_type_name; array_default_value = (symbol_c *)symbol->non_generic_type_name->accept(*type_initial_value_c::instance());; if (array_default_value == NULL) ERROR; break; + case typedecl_am: + s4o.print("__"); + symbol->non_generic_type_name->accept(*this); + symbol->array_subrange_list->accept(*this); + break; default: + symbol->array_subrange_list->accept(*this); break; } return NULL; @@ -204,9 +210,14 @@ /* signed_integer DOTDOT signed_integer */ //SYM_REF2(subrange_c, lower_limit, upper_limit) void *visit(subrange_c *symbol) { + int dimension = extract_integer(symbol->upper_limit) - extract_integer(symbol->lower_limit) + 1; switch (current_mode) { case arraysize_am: - array_size *= extract_integer(symbol->upper_limit) - extract_integer(symbol->lower_limit) + 1; + array_size *= dimension; + break; + case typedecl_am: + s4o.print("_"); + s4o.print_integer(dimension); break; default: break; @@ -1379,6 +1390,23 @@ return NULL; } +/* ARRAY '[' array_subrange_list ']' OF non_generic_type_name */ +void *visit(array_specification_c *symbol) { + s4o.print("__"); + symbol->non_generic_type_name->accept(*this); + symbol->array_subrange_list->accept(*this); + return NULL; +} + +/* signed_integer DOTDOT signed_integer */ +//SYM_REF2(subrange_c, lower_limit, upper_limit) +void *visit(subrange_c *symbol) { + int dimension = extract_integer(symbol->upper_limit) - extract_integer(symbol->lower_limit) + 1; + s4o.print("_"); + print_integer(dimension); + return NULL; +} + /* var1_list ':' initialized_structure */ // SYM_REF2(structured_var_init_decl_c, var1_list, initialized_structure) void *visit(structured_var_init_decl_c *symbol) { @@ -1521,7 +1549,7 @@ } void *visit(array_initial_elements_list_c *symbol) { - if (wanted_varformat == localinit_vf) { + if (wanted_varformat == localinit_vf || wanted_varformat == constructorinit_vf) { generate_c_array_initialization_c *array_initialization = new generate_c_array_initialization_c(&s4o); array_initialization->init_array_size(this->current_var_type_symbol); array_initialization->init_array_values(this->current_var_init_symbol); @@ -1952,12 +1980,15 @@ s4o.print(nv->get()); s4o.print(INIT_GLOBAL); s4o.print("("); + this->current_var_type_symbol->accept(*this); + s4o.print(","); if (symbol->global_var_name != NULL) symbol->global_var_name->accept(*this); else symbol->location->accept(*this); - s4o.print(","); + s4o.print(",__INITIAL_VALUE("); this->current_var_init_symbol->accept(*this); + s4o.print(")"); print_retain(); s4o.print(")"); } @@ -2013,9 +2044,12 @@ s4o.print(INIT_GLOBAL); s4o.print("("); + this->current_var_type_symbol->accept(*this); + s4o.print(","); list->elements[i]->accept(*this); - s4o.print(","); + s4o.print(",__INITIAL_VALUE("); this->current_var_init_symbol->accept(*this); + s4o.print(")"); print_retain(); s4o.print(")"); #if 0 diff -r 7dcbd8418771 -r 60b012b7793f stage4/generate_c/generate_var_list.cc --- a/stage4/generate_c/generate_var_list.cc Fri Sep 09 12:03:15 2011 +0200 +++ b/stage4/generate_c/generate_var_list.cc Wed Sep 14 22:58:39 2011 +0200 @@ -25,66 +25,157 @@ * */ -typedef struct -{ - symbol_c *symbol; -} SYMBOL; - -typedef enum { - none_lt, - input_lt, - output_lt, - memory_lt -} locationtype_t; - - -/***********************************************************************/ -/***********************************************************************/ -/***********************************************************************/ -/***********************************************************************/ - + + +/***********************************************************************/ +/***********************************************************************/ +/***********************************************************************/ +/***********************************************************************/ class search_location_type_c: public iterator_visitor_c { public: + typedef enum { + none_lt, + input_lt, + output_lt, + memory_lt + } locationtype_t; + locationtype_t current_location_type; public: - search_location_type_c(void) {} - - virtual ~search_location_type_c(void) {} - - locationtype_t get_location_type(symbol_c *symbol) { + search_location_type_c(void) {} + + virtual ~search_location_type_c(void) {} + + locationtype_t get_location_type(symbol_c *symbol) { current_location_type = none_lt; symbol->accept(*this); if (current_location_type == none_lt) ERROR; return current_location_type; - } + } private: - void *visit(incompl_location_c* symbol) { + void *visit(incompl_location_c* symbol) { if (symbol->value[1] == 'I') current_location_type = input_lt; - else if (symbol->value[1] == 'Q') + else if (symbol->value[1] == 'Q') current_location_type = output_lt; - else if (symbol->value[1] == 'M') + else if (symbol->value[1] == 'M') current_location_type = memory_lt; return NULL; - } - - void *visit(direct_variable_c *symbol) { + } + + void *visit(direct_variable_c *symbol) { if (symbol->value[1] == 'I') current_location_type = input_lt; - else if (symbol->value[1] == 'Q') + else if (symbol->value[1] == 'Q') current_location_type = output_lt; - else if (symbol->value[1] == 'M') + else if (symbol->value[1] == 'M') current_location_type = memory_lt; return NULL; - } + } }; + +/***********************************************************************/ +/***********************************************************************/ +/***********************************************************************/ +/***********************************************************************/ +/***********************************************************************/ +/***********************************************************************/ +/***********************************************************************/ +/***********************************************************************/ + + +class search_type_symbol_c: public iterator_visitor_c { + + public: + typedef enum { + none_vtc, + variable_vtc, + array_vtc, + structure_vtc, + function_block_vtc + } vartypecategory_t; + + vartypecategory_t current_var_type_category; + + private: + symbol_c *current_var_type_symbol; + symbol_c *current_var_type_name; + search_base_type_c search_base_type; + search_fb_typedecl_c *search_fb_typedecl; + + public: + search_type_symbol_c(symbol_c *scope) { + search_fb_typedecl = new search_fb_typedecl_c(scope); + } + + virtual ~search_type_symbol_c(void) { + delete search_fb_typedecl; + } + + symbol_c *get_type_symbol(symbol_c* symbol) { + this->current_var_type_category = variable_vtc; + this->current_var_type_symbol = NULL; + this->current_var_type_name = NULL; + + symbol_c* var_type_symbol = spec_init_sperator_c::get_spec(symbol); + if (var_type_symbol == NULL) { + var_type_symbol = symbol; + } + + var_type_symbol->accept(*this); + + if (this->current_var_type_symbol == NULL) + this->current_var_type_symbol = var_type_symbol; + + return (this->current_var_type_symbol); + } + + symbol_c *get_current_type_name(void) { + if (this->current_var_type_name == NULL) + return (this->current_var_type_symbol); + + return (this->current_var_type_name); + } + + void *visit(identifier_c* symbol) { + if (this->current_var_type_name == NULL) { + this->current_var_type_name = symbol; + + this->current_var_type_symbol = search_fb_typedecl->get_decl(this->current_var_type_name); + if (this->current_var_type_symbol != NULL) + this->current_var_type_category = function_block_vtc; + + else { + this->current_var_type_symbol = (symbol_c *)(this->current_var_type_name->accept(search_base_type)); + this->current_var_type_symbol->accept(*this); + } + } + return NULL; + } + + void *visit(array_specification_c* symbol) { + this->current_var_type_category = array_vtc; + + if (this->current_var_type_name == NULL) + this->current_var_type_name = symbol->non_generic_type_name; + + return NULL; + } + + void *visit(structure_element_declaration_list_c* symbol) { + this->current_var_type_category = structure_vtc; + return NULL; + } + +}; + /***********************************************************************/ /***********************************************************************/ /***********************************************************************/ @@ -97,6 +188,11 @@ class generate_var_list_c: protected generate_c_typedecl_c { public: + typedef struct + { + symbol_c *symbol; + } SYMBOL; + typedef enum { none_dt, programs_dt, @@ -106,18 +202,14 @@ declarationtype_t current_declarationtype; typedef enum { - none_vtc, - variable_vtc, - external_vtc, - located_input_vtc, - located_memory_vtc, - located_output_vtc, - array_vtc, - structure_vtc, - function_block_vtc - } vartypecategory_t; - - vartypecategory_t current_var_type_category; + none_vcc, + external_vcc, + located_input_vcc, + located_memory_vcc, + located_output_vcc, + } varclasscategory_t; + + varclasscategory_t current_var_class_category; private: symbol_c *current_var_type_symbol; @@ -128,49 +220,26 @@ unsigned int action_number; bool configuration_defined; std::list current_symbol_list; - search_base_type_c search_base_type; - search_fb_typedecl_c *search_fb_typedecl; + search_type_symbol_c *search_type_symbol; public: generate_var_list_c(stage4out_c *s4o_ptr, symbol_c *scope) : generate_c_typedecl_c(s4o_ptr) { - search_fb_typedecl = new search_fb_typedecl_c(scope); + search_type_symbol = new search_type_symbol_c(scope); current_var_number = 0; - current_var_type_symbol = current_var_type_name = NULL; + current_var_type_symbol = NULL; + current_var_type_name = NULL; current_declarationtype = none_dt; - current_var_type_category = none_vtc; + current_var_class_category = none_vcc; } ~generate_var_list_c(void) { - delete search_fb_typedecl; + delete search_type_symbol; } void update_var_type_symbol(symbol_c *symbol) { - - this->current_var_type_name = spec_init_sperator_c::get_spec(symbol); - if (this->current_var_type_name == NULL) { - std::list::iterator pt; - for(pt = current_symbol_list.begin(); pt != current_symbol_list.end(); pt++) { - fprintf(stderr, "%s.", ((identifier_c*)(pt->symbol))->value); - } - ERROR; - } - - this->current_var_type_symbol = search_fb_typedecl->get_decl(this->current_var_type_name); - if (this->current_var_type_symbol != NULL) - this->current_var_type_category = function_block_vtc; - else { - this->current_var_type_symbol = (symbol_c *)(this->current_var_type_name->accept(search_base_type)); - - structure_element_declaration_list_c *structure_symbol = dynamic_cast(this->current_var_type_symbol); - if (structure_symbol != NULL) - this->current_var_type_category = structure_vtc; - else - this->current_var_type_category = variable_vtc; - } - - if (this->current_var_type_symbol == NULL) - ERROR; + this->current_var_type_symbol = search_type_symbol->get_type_symbol(symbol); + this->current_var_type_name = search_type_symbol->get_current_type_name(); } void reset_var_type_symbol(void) { @@ -209,39 +278,43 @@ void declare_variable(symbol_c *symbol) { // Arrays and structures are not supported in debugging - switch (this->current_var_type_category) { - case array_vtc: - case structure_vtc: + switch (search_type_symbol->current_var_type_category) { + case search_type_symbol_c::array_vtc: + case search_type_symbol_c::structure_vtc: return; - default: - break; + default: + break; } print_var_number(); s4o.print(";"); - switch (this->current_var_type_category) { - case external_vtc: - s4o.print("EXT"); - break; - case located_input_vtc: - s4o.print("IN"); - break; - case located_memory_vtc: - s4o.print("MEM"); - break; - case located_output_vtc: - s4o.print("OUT"); - break; - case array_vtc: + switch (search_type_symbol->current_var_type_category) { + case search_type_symbol_c::array_vtc: s4o.print("ARRAY"); break; - case structure_vtc: + case search_type_symbol_c::structure_vtc: s4o.print("STRUCT"); break; - case function_block_vtc: + case search_type_symbol_c::function_block_vtc: s4o.print("FB"); break; default: - s4o.print("VAR"); + switch (this->current_var_class_category) { + case external_vcc: + s4o.print("EXT"); + break; + case located_input_vcc: + s4o.print("IN"); + break; + case located_memory_vcc: + s4o.print("MEM"); + break; + case located_output_vcc: + s4o.print("OUT"); + break; + default: + s4o.print("VAR"); + break; + } break; } s4o.print(";"); @@ -251,9 +324,9 @@ print_symbol_list(); symbol->accept(*this); s4o.print(";"); - switch (this->current_var_type_category) { - case structure_vtc: - case function_block_vtc: + switch (search_type_symbol->current_var_type_category) { + case search_type_symbol_c::structure_vtc: + case search_type_symbol_c::function_block_vtc: this->current_var_type_name->accept(*this); s4o.print(";\n"); SYMBOL *current_name; @@ -263,7 +336,7 @@ this->current_var_type_symbol->accept(*this); current_symbol_list.pop_back(); break; - case array_vtc: + case search_type_symbol_c::array_vtc: this->current_var_type_name->accept(*this); s4o.print(";\n"); break; @@ -321,20 +394,33 @@ update_var_type_symbol(symbol->located_var_spec_init); search_location_type_c search_location_type; - locationtype_t location_type = search_location_type.get_location_type(symbol->location); - if (location_type == input_lt) - this->current_var_type_category = located_input_vtc; - else if (location_type == memory_lt) - this->current_var_type_category = located_memory_vtc; - else if (location_type == output_lt) - this->current_var_type_category = located_output_vtc; + switch (search_location_type.get_location_type(symbol->location)) { + case search_location_type_c::input_lt: + this->current_var_class_category = located_input_vcc; + break; + case search_location_type_c::memory_lt: + this->current_var_class_category = located_memory_vcc; + break; + case search_location_type_c::output_lt: + this->current_var_class_category = located_output_vcc; + break; + default: + ERROR; + break; + } if (symbol->variable_name != NULL) declare_variable(symbol->variable_name); else declare_variable(symbol->location); - current_var_type_symbol = NULL; + this->current_var_class_category = none_vcc; + + /* Values no longer in scope, and therefore no longer used. + * Make an effort to keep them set to NULL when not in use + * in order to catch bugs as soon as possible... + */ + reset_var_type_symbol(); return NULL; } @@ -348,20 +434,33 @@ update_var_type_symbol(symbol->var_spec); search_location_type_c search_location_type; - locationtype_t location_type = search_location_type.get_location_type(symbol->incompl_location); - if (location_type == input_lt) - this->current_var_type_category = located_input_vtc; - else if (location_type == memory_lt) - this->current_var_type_category = located_memory_vtc; - else if (location_type == output_lt) - this->current_var_type_category = located_output_vtc; + switch (search_location_type.get_location_type(symbol->incompl_location)) { + case search_location_type_c::input_lt: + this->current_var_class_category = located_input_vcc; + break; + case search_location_type_c::memory_lt: + this->current_var_class_category = located_memory_vcc; + break; + case search_location_type_c::output_lt: + this->current_var_class_category = located_output_vcc; + break; + default: + ERROR; + break; + } if (symbol->variable_name != NULL) declare_variable(symbol->variable_name); else declare_variable(symbol->incompl_location); - current_var_type_symbol = NULL; + this->current_var_class_category = none_vcc; + + /* Values no longer in scope, and therefore no longer used. + * Make an effort to keep them set to NULL when not in use + * in order to catch bugs as soon as possible... + */ + reset_var_type_symbol(); return NULL; } @@ -374,7 +473,6 @@ */ update_var_type_symbol(symbol->array_spec_init); - this->current_var_type_category = array_vtc; declare_variables(symbol->var1_list); /* Values no longer in scope, and therefore no longer used. @@ -400,7 +498,6 @@ update_var_type_symbol(symbol->initialized_structure); /* now to produce the c equivalent... */ - this->current_var_type_category = structure_vtc; declare_variables(symbol->var1_list); /* Values no longer in scope, and therefore no longer used. @@ -450,16 +547,18 @@ */ update_var_type_symbol(symbol->specification); + this->current_var_class_category = external_vcc; + /* now to produce the c equivalent... */ - this->current_var_type_category = external_vtc; declare_variable(symbol->global_var_name); + this->current_var_class_category = none_vcc; + /* Values no longer in scope, and therefore no longer used. * Make an effort to keep them set to NULL when not in use * in order to catch bugs as soon as possible... */ reset_var_type_symbol(); - return NULL; } @@ -498,18 +597,28 @@ // SYM_REF2(global_var_spec_c, global_var_name, location) void *visit(global_var_spec_c *symbol) { search_location_type_c search_location_type; - locationtype_t location_type = search_location_type.get_location_type(symbol->location); - if (location_type == input_lt) - this->current_var_type_category = located_input_vtc; - else if (location_type == memory_lt) - this->current_var_type_category = located_memory_vtc; - else if (location_type == output_lt) - this->current_var_type_category = located_output_vtc; + switch (search_location_type.get_location_type(symbol->location)) { + case search_location_type_c::input_lt: + this->current_var_class_category = located_input_vcc; + break; + case search_location_type_c::memory_lt: + this->current_var_class_category = located_memory_vcc; + break; + case search_location_type_c::output_lt: + this->current_var_class_category = located_output_vcc; + break; + default: + ERROR; + break; + } if (symbol->global_var_name != NULL) declare_variable(symbol->global_var_name); else declare_variable(symbol->location); + + this->current_var_class_category = none_vcc; + return NULL; } @@ -539,7 +648,7 @@ /* Start off by setting the current_var_type_symbol and * current_var_init_symbol private variables... */ - this->current_var_type_symbol = symbol->type; + update_var_type_symbol(symbol->type); /* now to produce the c equivalent... */ declare_variable(symbol->name); @@ -559,7 +668,7 @@ /* Start off by setting the current_var_type_symbol and * current_var_init_symbol private variables... */ - this->current_var_type_symbol = symbol->type; + update_var_type_symbol(symbol->type); /* now to produce the c equivalent... */ declare_variable(symbol->name);