Adding support for compiling direct array specification inside variable declaration
--- 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 \
--- 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@
--- 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"
--- /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 <http://www.gnu.org/licenses/>.
+ *
+ *
+ * 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<array_specification_c*>(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);
+}
+
--- /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 <http://www.gnu.org/licenses/>.
+ *
+ *
+ * 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
+
+
+
+
+
+
+
--- 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();
--- 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);
--- 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);
}
--- 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;
--- 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);
}
--- 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)
--- 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 */
--- 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 <sstream>
#include <typeinfo>
#include <list>
+#include <map>
+#include <sstream>
#include <strings.h>
#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<std::string, int> 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<array_specification_c*>(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<std::string,int>::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<array_specification_c*>(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<array_specification_c*>(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<array_spec_init_c*>(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;
}
--- 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;
}
--- 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;
}
--- 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<identifier_c *>(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;
}
--- 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
--- 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<SYMBOL> 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<SYMBOL>::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<structure_element_declaration_list_c *>(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);