# HG changeset patch # User Mario de Sousa # Date 1492328818 -3600 # Node ID 4d718301348182b7fc5d7dac146544f7706e788d # Parent 37966f855bedae8386d0794039f40e3b654a5d0f# Parent 52f63e622604033da988c0ef1c2a5e06c678395c merge diff -r 52f63e622604 -r 4d7183013481 absyntax/absyntax.cc --- a/absyntax/absyntax.cc Wed Apr 12 08:44:42 2017 +0100 +++ b/absyntax/absyntax.cc Sun Apr 16 08:46:58 2017 +0100 @@ -58,6 +58,7 @@ this->last_column = last_column; this->last_order = last_order; this->parent = NULL; + this->token = NULL; this->datatype = NULL; this->scope = NULL; } @@ -69,6 +70,7 @@ int ll, int lc, const char *lfile, long int lorder) :symbol_c(fl, fc, ffile, forder, ll, lc, lfile, lorder) { this->value = value; + this->token = this; // every token is its own reference token. // printf("New token: %s\n", value); } @@ -83,7 +85,7 @@ int ll, int lc, const char *lfile, long int lorder) :symbol_c(fl, fc, ffile, forder, ll, lc, lfile, lorder),c(LIST_CAP_INIT) { n = 0; - elements = (symbol_c**)malloc(LIST_CAP_INIT*sizeof(symbol_c*)); + elements = (element_entry_t*)malloc(LIST_CAP_INIT*sizeof(element_entry_t)); if (NULL == elements) ERROR_MSG("out of memory"); } @@ -93,20 +95,59 @@ int ll, int lc, const char *lfile, long int lorder) :symbol_c(fl, fc, ffile, forder, ll, lc, lfile, lorder),c(LIST_CAP_INIT) { n = 0; - elements = (symbol_c**)malloc(LIST_CAP_INIT*sizeof(symbol_c*)); + elements = (element_entry_t*)malloc(LIST_CAP_INIT*sizeof(element_entry_t)); if (NULL == elements) ERROR_MSG("out of memory"); add_element(elem); } +/*******************************************/ +/* get element in position pos of the list */ +/*******************************************/ +symbol_c *list_c::get_element(int pos) {return elements[pos].symbol;} + + + +/******************************************/ +/* find element associated to token value */ +/******************************************/ +symbol_c *list_c::find_element(symbol_c *token) { + token_c *t = dynamic_cast(token); + if (t == NULL) ERROR; + return find_element((const char *)t->value); +} + +symbol_c *list_c::find_element(const char *token_value) { + // We could use strcasecmp(), but it's best to always use the same + // method of string comparison throughout matiec + nocasecmp_c ncc; + for (int i = 0; i < n; i++) + if (!ncc(elements[i].token_value, token_value)) + return elements[i].symbol; + + return NULL; // not found +} + + +/***********************************************/ /* append a new element to the end of the list */ -void list_c::add_element(symbol_c *elem) { - // printf("list_c::add_element()\n"); +/***********************************************/ +void list_c::add_element(symbol_c *elem) {add_element(elem, elem);} + +void list_c::add_element(symbol_c *elem, symbol_c *token) { + token_c *t = (token == NULL)? NULL : token->token; + add_element(elem, (t == NULL)? NULL : t->value); +} + +void list_c::add_element(symbol_c *elem, const char *token_value) { if (c <= n) - if (!(elements=(symbol_c**)realloc(elements,(c+=LIST_CAP_INCR)*sizeof(symbol_c *)))) + if (!(elements=(element_entry_t*)realloc(elements,(c+=LIST_CAP_INCR)*sizeof(element_entry_t)))) ERROR_MSG("out of memory"); - elements[n++] = elem; - + //elements[n++] = {token_value, elem}; // only available from C++11 onwards, best not use it for now. + elements[n].symbol = elem; + elements[n].token_value = token_value; + n++; + if (NULL == elem) return; /* Sometimes add_element() is called in stage3 or stage4 to temporarily add an AST symbol to the list. * Since this symbol already belongs in some other place in the aST, it will have the 'parent' pointer set, @@ -143,10 +184,21 @@ } } + +/*********************************************/ /* insert a new element before position pos. */ +/*********************************************/ /* To insert into the begining of list, call with pos=0 */ /* To insert into the end of list, call with pos=list->n */ -void list_c::insert_element(symbol_c *elem, int pos) { + +void list_c::insert_element(symbol_c *elem, int pos) {insert_element(elem, elem, pos);} + +void list_c::insert_element(symbol_c *elem, symbol_c *token, int pos) { + token_c *t = (token == NULL)? NULL : token->token; + insert_element(elem, (t == NULL)? NULL : t->value, pos); +} + +void list_c::insert_element(symbol_c *elem, const char *token_value, int pos) { if((pos<0) || (n=pos ; --i) elements[i+1] = elements[i]; - elements[pos] = elem; - } -} - - + elements[pos].symbol = elem; + elements[pos].token_value = token_value; + } +} + + +/***********************************/ /* remove element at position pos. */ +/***********************************/ void list_c::remove_element(int pos) { if((pos<0) || (n<=pos)) ERROR; @@ -168,12 +223,14 @@ for (int i = pos; i < n-1; i++) elements[i] = elements[i+1]; /* corrent the new size */ n--; - /* elements = (symbol_c **)realloc(elements, n * sizeof(symbol_c *)); */ + /* elements = (symbol_c **)realloc(elements, n * sizeof(element_entry_t)); */ /* TODO: adjust the location parameters, taking into account the removed element. */ } -/* remove element at position pos. */ +/**********************************/ +/* Remove all elements from list. */ +/**********************************/ void list_c::clear(void) { n = 0; /* TODO: adjust the location parameters, taking into account the removed element. */ diff -r 52f63e622604 -r 4d7183013481 absyntax/absyntax.hh --- a/absyntax/absyntax.hh Wed Apr 12 08:44:42 2017 +0100 +++ b/absyntax/absyntax.hh Sun Apr 16 08:46:58 2017 +0100 @@ -154,7 +154,8 @@ {return (_int64.is_valid() || _uint64.is_valid() || _real64.is_valid() || _bool.is_valid());} }; - +// A forward declaration +class token_c; /* The base class of all symbols */ class symbol_c { @@ -167,7 +168,18 @@ * Annotations produced during stage 1_2 */ /* Points to the parent symbol in the AST, i.e. the symbol in the AST that will contain the current symbol */ - symbol_c *parent; + symbol_c *parent; + /* Some symbols may not be tokens, but may be clearly identified by a token. + * For e.g., a FUNCTION declaration is not itself a token, but may be clearly identified by the + * token_c object that contains it's name. Another example is an element in a STRUCT declaration, + * where the structure_element_declaration_c is not itself a token, but can be clearly identified + * by the structure_element_name + * To make it easier to find these tokens from the top level object, we will have the stage1_2 populate this + * token_c *token wherever it makes sense. + * NOTE: This was a late addition to the AST. Not all objects may be currently so populated. + * If you need this please make sure the bison code is populating it correctly for your use case. + */ + token_c *token; /* Line number for the purposes of error checking. */ int first_line; @@ -260,7 +272,14 @@ virtual const char *absyntax_cname(void) {return "list_c";}; int c,n; /* c: current capacity of list (malloc'd memory); n: current number of elements in list */ - symbol_c **elements; + private: +// symbol_c **elements; + typedef struct { + const char *token_value; + symbol_c *symbol; + } element_entry_t; + element_entry_t *elements; + public: list_c(int fl = 0, int fc = 0, const char *ffile = NULL /* filename */, long int forder=0, /* order in which it is read by lexcial analyser */ @@ -271,12 +290,22 @@ int fl = 0, int fc = 0, const char *ffile = NULL /* filename */, long int forder=0, /* order in which it is read by lexcial analyser */ int ll = 0, int lc = 0, const char *lfile = NULL /* filename */, long int lorder=0 /* order in which it is read by lexcial analyser */ ); + /* get element in position pos of the list */ + virtual symbol_c *get_element(int pos); + /* find element associated to token value */ + virtual symbol_c *find_element(symbol_c *token); + virtual symbol_c *find_element(const char *token_value); /* append a new element to the end of the list */ virtual void add_element(symbol_c *elem); + virtual void add_element(symbol_c *elem, symbol_c *token); + virtual void add_element(symbol_c *elem, const char *token_value); /* insert a new element before position pos. */ /* To insert into the begining of list, call with pos=0 */ /* To insert into the end of list, call with pos=list->n */ - virtual void insert_element(symbol_c *elem, int pos = 0); + virtual void insert_element(symbol_c *elem, const char *token_value, int pos = 0); + virtual void insert_element(symbol_c *elem, symbol_c *token, int pos = 0); + virtual void insert_element(symbol_c *elem, int pos = 0); + //virtual void insert_element(symbol_c *elem, int pos, std::string map_ref); /* remove element at position pos. */ virtual void remove_element(int pos = 0); /* remove all elements from list. Does not delete the elements in the list! */ diff -r 52f63e622604 -r 4d7183013481 absyntax/visitor.cc --- a/absyntax/visitor.cc Wed Apr 12 08:44:42 2017 +0100 +++ b/absyntax/visitor.cc Sun Apr 16 08:46:58 2017 +0100 @@ -168,7 +168,7 @@ void *iterator_visitor_c::visit_list(list_c *list) { for(int i = 0; i < list->n; i++) { - list->elements[i]->accept(*this); + list->get_element(i)->accept(*this); } return NULL; } @@ -310,7 +310,7 @@ void *search_visitor_c::visit_list(list_c *list) { for(int i = 0; i < list->n; i++) { - void *res = list->elements[i]->accept(*this); + void *res = list->get_element(i)->accept(*this); if (res != NULL) return res; } diff -r 52f63e622604 -r 4d7183013481 absyntax_utils/add_en_eno_param_decl.cc --- a/absyntax_utils/add_en_eno_param_decl.cc Wed Apr 12 08:44:42 2017 +0100 +++ b/absyntax_utils/add_en_eno_param_decl.cc Sun Apr 16 08:46:58 2017 +0100 @@ -84,7 +84,7 @@ void* add_en_eno_param_decl_c::iterate_list(list_c *list) { for (int i = 0; i < list->n; i++) { - list->elements[i]->accept(*this); + list->get_element(i)->accept(*this); } return NULL; } diff -r 52f63e622604 -r 4d7183013481 absyntax_utils/array_dimension_iterator.cc --- a/absyntax_utils/array_dimension_iterator.cc Wed Apr 12 08:44:42 2017 +0100 +++ b/absyntax_utils/array_dimension_iterator.cc Sun Apr 16 08:46:58 2017 +0100 @@ -64,7 +64,7 @@ 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); + res = list->get_element(i)->accept(*this); if (res != NULL) return res; } diff -r 52f63e622604 -r 4d7183013481 absyntax_utils/case_element_iterator.cc --- a/absyntax_utils/case_element_iterator.cc Wed Apr 12 08:44:42 2017 +0100 +++ b/absyntax_utils/case_element_iterator.cc Sun Apr 16 08:46:58 2017 +0100 @@ -78,7 +78,7 @@ void* case_element_iterator_c::iterate_list(list_c *list) { void *res; for (int i = 0; i < list->n; i++) { - res = list->elements[i]->accept(*this); + res = list->get_element(i)->accept(*this); if (res != NULL) return res; } diff -r 52f63e622604 -r 4d7183013481 absyntax_utils/function_call_param_iterator.cc --- a/absyntax_utils/function_call_param_iterator.cc Wed Apr 12 08:44:42 2017 +0100 +++ b/absyntax_utils/function_call_param_iterator.cc Sun Apr 16 08:46:58 2017 +0100 @@ -67,7 +67,7 @@ switch (current_operation) { case iterate_nf_op: for(int i = 0; i < list->n; i++) { - void *res = list->elements[i]->accept(*this); + void *res = list->get_element(i)->accept(*this); if (NULL != res) { /* It went through the handle_parameter_assignment() function, * and is therefore a parameter assignment ( = ), @@ -77,7 +77,7 @@ } else { param_count++; if (param_count == iterate_nf_next_param) { - return list->elements[i]; + return list->get_element(i); } } } @@ -86,7 +86,7 @@ case iterate_f_op: for(int i = 0; i < list->n; i++) { - void *res = list->elements[i]->accept(*this); + void *res = list->get_element(i)->accept(*this); if (NULL != res) { /* It went through the handle_parameter_assignment() function, * and is therefore a parameter assignment ( = ), @@ -105,7 +105,7 @@ case search_f_op: for(int i = 0; i < list->n; i++) { - void *res = list->elements[i]->accept(*this); + void *res = list->get_element(i)->accept(*this); if (res != NULL) return res; } diff -r 52f63e622604 -r 4d7183013481 absyntax_utils/function_param_iterator.cc --- a/absyntax_utils/function_param_iterator.cc Wed Apr 12 08:44:42 2017 +0100 +++ b/absyntax_utils/function_param_iterator.cc Sun Apr 16 08:46:58 2017 +0100 @@ -167,7 +167,7 @@ switch (current_operation) { case iterate_op: if (next_param <= param_count + list->n) - return list->elements[next_param - param_count - 1]; + return list->get_element(next_param - param_count - 1); /* the desired param is not on this list... */ param_count += list->n; @@ -175,7 +175,7 @@ case search_op: for(int i = 0; i < list->n; i++) { - symbol_c *sym = list->elements[i]; + symbol_c *sym = list->get_element(i); extensible_input_parameter_c *extensible_parameter = dynamic_cast(sym); if (extensible_parameter != NULL) { sym = extensible_parameter->var_name; @@ -243,7 +243,7 @@ void* function_param_iterator_c::iterate_list(list_c *list) { void *res; for (int i = 0; i < list->n; i++) { - res = list->elements[i]->accept(*this); + res = list->get_element(i)->accept(*this); if (res != NULL) return res; } diff -r 52f63e622604 -r 4d7183013481 absyntax_utils/get_datatype_info.cc --- a/absyntax_utils/get_datatype_info.cc Wed Apr 12 08:44:42 2017 +0100 +++ b/absyntax_utils/get_datatype_info.cc Sun Apr 16 08:46:58 2017 +0100 @@ -362,7 +362,7 @@ void *visit(structure_element_declaration_list_c *symbol) { /* now search the structure declaration */ for(int i = 0; i < symbol->n; i++) { - void *tmp = symbol->elements[i]->accept(*this); + void *tmp = symbol->get_element(i)->accept(*this); if (NULL != tmp) return tmp; } return NULL; // not found!! @@ -713,8 +713,8 @@ // comparison of each subrange start and end elements for (int i = 0; i < subrange_list_1->n; i++) { - subrange_c *subrange_1 = dynamic_cast(subrange_list_1->elements[i]); - subrange_c *subrange_2 = dynamic_cast(subrange_list_2->elements[i]); + subrange_c *subrange_1 = dynamic_cast(subrange_list_1->get_element(i)); + subrange_c *subrange_2 = dynamic_cast(subrange_list_2->get_element(i)); if ((NULL == subrange_1) || (NULL == subrange_2)) ERROR; /* check whether the subranges have the same values, using the result of the constant folding agorithm. diff -r 52f63e622604 -r 4d7183013481 absyntax_utils/search_base_type.cc --- a/absyntax_utils/search_base_type.cc Wed Apr 12 08:44:42 2017 +0100 +++ b/absyntax_utils/search_base_type.cc Sun Apr 16 08:46:58 2017 +0100 @@ -255,7 +255,7 @@ } /* signed_integer DOTDOT signed_integer */ -void *search_base_type_c::visit(subrange_c *symbol) {ERROR; return NULL;} /* should never get called... */ +void *search_base_type_c::visit(subrange_c *symbol) {ERROR; return NULL;} /* should never get called... */ /* enumerated_type_name ':' enumerated_spec_init */ void *search_base_type_c::visit(enumerated_type_declaration_c *symbol) { @@ -293,7 +293,7 @@ /* enumerated_type_name '#' identifier */ // SYM_REF2(enumerated_value_c, type, value) -void *search_base_type_c::visit(enumerated_value_c *symbol) {ERROR; return NULL;} /* should never get called... */ +void *search_base_type_c::visit(enumerated_value_c *symbol) {ERROR; return NULL;} /* should never get called... */ /* identifier ':' array_spec_init */ void *search_base_type_c::visit(array_type_declaration_c *symbol) { @@ -312,20 +312,20 @@ } /* ARRAY '[' array_subrange_list ']' OF non_generic_type_name */ -void *search_base_type_c::visit(array_specification_c *symbol) {return (void *)symbol;} +void *search_base_type_c::visit(array_specification_c *symbol) {return (void *)symbol;} /* helper symbol for array_specification */ /* array_subrange_list ',' subrange */ -void *search_base_type_c::visit(array_subrange_list_c *symbol) {ERROR; return NULL;} /* should never get called... */ +void *search_base_type_c::visit(array_subrange_list_c *symbol) {ERROR; return NULL;} /* should never get called... */ /* array_initialization: '[' array_initial_elements_list ']' */ /* helper symbol for array_initialization */ /* array_initial_elements_list ',' array_initial_elements */ -void *search_base_type_c::visit(array_initial_elements_list_c *symbol) {ERROR; return NULL;} /* should never get called... */ +void *search_base_type_c::visit(array_initial_elements_list_c *symbol) {ERROR; return NULL;} /* should never get called... */ /* integer '(' [array_initial_element] ')' */ /* array_initial_element may be NULL ! */ -void *search_base_type_c::visit(array_initial_elements_c *symbol) {ERROR; return NULL;} /* should never get called... */ +void *search_base_type_c::visit(array_initial_elements_c *symbol) {ERROR; return NULL;} /* should never get called... */ /* structure_type_name ':' structure_specification */ /* NOTE: structure_specification will point to either a @@ -339,31 +339,27 @@ } /* var1_list ':' structure_type_name */ -void *search_base_type_c::visit(structured_var_declaration_c *symbol) { - return symbol; -} +void *search_base_type_c::visit(structured_var_declaration_c *symbol) {return symbol;} /* structure_type_name ASSIGN structure_initialization */ /* structure_initialization may be NULL ! */ -void *search_base_type_c::visit(initialized_structure_c *symbol) { - return symbol->structure_type_name->accept(*this); -} +void *search_base_type_c::visit(initialized_structure_c *symbol) {return symbol->structure_type_name->accept(*this);} /* helper symbol for structure_declaration */ /* structure_declaration: STRUCT structure_element_declaration_list END_STRUCT */ /* structure_element_declaration_list structure_element_declaration ';' */ -void *search_base_type_c::visit(structure_element_declaration_list_c *symbol) {return (void *)symbol;} +void *search_base_type_c::visit(structure_element_declaration_list_c *symbol) {return (void *)symbol;} /* structure_element_name ':' *_spec_init */ -void *search_base_type_c::visit(structure_element_declaration_c *symbol) {ERROR; return NULL;} /* should never get called... */ +void *search_base_type_c::visit(structure_element_declaration_c *symbol) {return symbol->spec_init->accept(*this);} /* helper symbol for structure_initialization */ /* structure_initialization: '(' structure_element_initialization_list ')' */ /* structure_element_initialization_list ',' structure_element_initialization */ -void *search_base_type_c::visit(structure_element_initialization_list_c *symbol) {ERROR; return NULL;} /* should never get called... */ +void *search_base_type_c::visit(structure_element_initialization_list_c *symbol) {ERROR; return NULL;} /* should never get called... */ /* structure_element_name ASSIGN value */ -void *search_base_type_c::visit(structure_element_initialization_c *symbol) {ERROR; return NULL;} /* should never get called... */ +void *search_base_type_c::visit(structure_element_initialization_c *symbol) {ERROR; return NULL;} /* should never get called... */ /* string_type_name ':' elementary_string_type_name string_type_declaration_size string_type_declaration_init */ /* @@ -372,7 +368,7 @@ string_type_declaration_size, string_type_declaration_init) // may be == NULL! */ -void *search_base_type_c::visit(string_type_declaration_c *symbol) {return (void *)symbol;} +void *search_base_type_c::visit(string_type_declaration_c *symbol) {return (void *)symbol;} /* function_block_type_name ASSIGN structure_initialization */ @@ -386,15 +382,13 @@ /* ref_spec: REF_TO (non_generic_type_name | function_block_type_name) */ // SYM_REF1(ref_spec_c, type_name) -void *search_base_type_c::visit(ref_spec_c *symbol) {return (void *)symbol;} +void *search_base_type_c::visit(ref_spec_c *symbol) {return (void *)symbol;} /* For the moment, we do not support initialising reference data types */ /* ref_spec_init: ref_spec [ ASSIGN ref_initialization ]; */ /* NOTE: ref_initialization may be NULL!! */ // SYM_REF2(ref_spec_init_c, ref_spec, ref_initialization) -void *search_base_type_c::visit(ref_spec_init_c *symbol) { - return symbol->ref_spec->accept(*this); -} +void *search_base_type_c::visit(ref_spec_init_c *symbol) {return symbol->ref_spec->accept(*this);} /* ref_type_decl: identifier ':' ref_spec_init */ // SYM_REF2(ref_type_decl_c, ref_type_name, ref_spec_init) @@ -410,9 +404,7 @@ /*****************************/ /* FUNCTION_BLOCK derived_function_block_name io_OR_other_var_declarations function_block_body END_FUNCTION_BLOCK */ // SYM_REF3(function_block_declaration_c, fblock_name, var_declarations, fblock_body) -void *search_base_type_c::visit(function_block_declaration_c *symbol) { - return (void *)symbol; -} +void *search_base_type_c::visit(function_block_declaration_c *symbol) {return (void *)symbol;} diff -r 52f63e622604 -r 4d7183013481 absyntax_utils/search_fb_instance_decl.cc --- a/absyntax_utils/search_fb_instance_decl.cc Wed Apr 12 08:44:42 2017 +0100 +++ b/absyntax_utils/search_fb_instance_decl.cc Sun Apr 16 08:46:58 2017 +0100 @@ -95,7 +95,7 @@ void *search_fb_instance_decl_c::visit(fb_name_list_c *symbol) { list_c *list = symbol; for(int i = 0; i < list->n; i++) { - if (compare_identifiers(list->elements[i], search_name) == 0) + if (compare_identifiers(list->get_element(i), search_name) == 0) /* by now, current_fb_declaration should be != NULL */ return current_fb_type_name; } diff -r 52f63e622604 -r 4d7183013481 absyntax_utils/search_var_instance_decl.cc --- a/absyntax_utils/search_var_instance_decl.cc Wed Apr 12 08:44:42 2017 +0100 +++ b/absyntax_utils/search_var_instance_decl.cc Sun Apr 16 08:46:58 2017 +0100 @@ -313,7 +313,7 @@ void *search_var_instance_decl_c::visit(var1_list_c *symbol) { list_c *list = symbol; for(int i = 0; i < list->n; i++) { - if (compare_identifiers(list->elements[i], search_name) == 0) + if (compare_identifiers(list->get_element(i), search_name) == 0) /* by now, current_type_decl should be != NULL */ return current_type_decl; } @@ -335,7 +335,7 @@ void *search_var_instance_decl_c::visit(fb_name_list_c *symbol) { list_c *list = symbol; for(int i = 0; i < list->n; i++) { - if (compare_identifiers(list->elements[i], search_name) == 0) + if (compare_identifiers(list->get_element(i), search_name) == 0) /* by now, current_fb_declaration should be != NULL */ return current_type_decl; } @@ -409,7 +409,7 @@ void *search_var_instance_decl_c::visit(global_var_list_c *symbol) { list_c *list = symbol; for(int i = 0; i < list->n; i++) { - if (compare_identifiers(list->elements[i], search_name) == 0) + if (compare_identifiers(list->get_element(i), search_name) == 0) /* by now, current_type_decl should be != NULL */ return current_type_decl; } diff -r 52f63e622604 -r 4d7183013481 absyntax_utils/search_varfb_instance_type.cc --- a/absyntax_utils/search_varfb_instance_type.cc Wed Apr 12 08:44:42 2017 +0100 +++ b/absyntax_utils/search_varfb_instance_type.cc Sun Apr 16 08:46:58 2017 +0100 @@ -244,7 +244,7 @@ /* now search the structure declaration */ for(int i = 0; i < symbol->n; i++) { - symbol->elements[i]->accept(*this); + symbol->get_element(i)->accept(*this); } return NULL; diff -r 52f63e622604 -r 4d7183013481 absyntax_utils/type_initial_value.cc --- a/absyntax_utils/type_initial_value.cc Wed Apr 12 08:44:42 2017 +0100 +++ b/absyntax_utils/type_initial_value.cc Sun Apr 16 08:46:58 2017 +0100 @@ -224,7 +224,7 @@ /* stage1_2 never creates an enumerated_value_list_c with no entries. If this occurs, then something must have changed! */ if (symbol->n <= 0) ERROR; /* if no initial value explicitly given, then use the lowest value of the subrange */ - return (void *)symbol->elements[0]; + return (void *)symbol->get_element(0); } /* enumerated_type_name '#' identifier */ // SYM_REF2(enumerated_value_c, type, value) diff -r 52f63e622604 -r 4d7183013481 stage1_2/create_enumtype_conversion_functions.cc --- a/stage1_2/create_enumtype_conversion_functions.cc Wed Apr 12 08:44:42 2017 +0100 +++ b/stage1_2/create_enumtype_conversion_functions.cc Sun Apr 16 08:46:58 2017 +0100 @@ -119,7 +119,7 @@ currentTokenList.clear(); list = (list_c *)symbol; for (int i = 0; i < list->n; i++) { - list->elements[i]->accept(*this); + list->get_element(i)->accept(*this); currentTokenList.push_back(currentToken); } diff -r 52f63e622604 -r 4d7183013481 stage1_2/iec_bison.yy --- a/stage1_2/iec_bison.yy Wed Apr 12 08:44:42 2017 +0100 +++ b/stage1_2/iec_bison.yy Sun Apr 16 08:46:58 2017 +0100 @@ -119,7 +119,7 @@ #define FOR_EACH_ELEMENT(elem, list, code) { \ symbol_c *elem; \ for(int i = 0; i < list->n; i++) { \ - elem = list->elements[i]; \ + elem = list->get_element(i); \ code; \ } \ } @@ -3213,15 +3213,15 @@ structure_element_declaration: structure_element_name ':' simple_spec_init - {$$ = new structure_element_declaration_c($1, $3, locloc(@$));} + {$$ = new structure_element_declaration_c($1, $3, locloc(@$)); $$->token = $1->token;} | structure_element_name ':' subrange_spec_init - {$$ = new structure_element_declaration_c($1, $3, locloc(@$));} + {$$ = new structure_element_declaration_c($1, $3, locloc(@$)); $$->token = $1->token;} | structure_element_name ':' enumerated_spec_init - {$$ = new structure_element_declaration_c($1, $3, locloc(@$));} + {$$ = new structure_element_declaration_c($1, $3, locloc(@$)); $$->token = $1->token;} | structure_element_name ':' array_spec_init - {$$ = new structure_element_declaration_c($1, $3, locloc(@$));} + {$$ = new structure_element_declaration_c($1, $3, locloc(@$)); $$->token = $1->token;} | structure_element_name ':' initialized_structure - {$$ = new structure_element_declaration_c($1, $3, locloc(@$));} + {$$ = new structure_element_declaration_c($1, $3, locloc(@$)); $$->token = $1->token;} | structure_element_name ':' ref_spec_init /* non standard extension: Allow use of struct elements storing REF_TO datatypes (either using REF_TO or a previosuly declared ref type) */ { $$ = new structure_element_declaration_c($1, $3, locloc(@$)); if (!allow_ref_to_in_derived_datatypes) { diff -r 52f63e622604 -r 4d7183013481 stage3/array_range_check.cc --- a/stage3/array_range_check.cc Wed Apr 12 08:44:42 2017 +0100 +++ b/stage3/array_range_check.cc Sun Apr 16 08:46:58 2017 +0100 @@ -133,38 +133,38 @@ return; /* Check lower limit */ - if ( VALID_CVALUE( int64, l->elements[i]) && VALID_CVALUE( int64, dimension->lower_limit)) - if ( GET_CVALUE( int64, l->elements[i]) < GET_CVALUE( int64, dimension->lower_limit) ) - {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (using constant value of %"PRId64", should be >= %"PRId64").", GET_CVALUE( int64, l->elements[i]), GET_CVALUE( int64, dimension->lower_limit)); continue;} - - if ( VALID_CVALUE( int64, l->elements[i]) && VALID_CVALUE(uint64, dimension->lower_limit)) - if ( cmp_unsigned_signed( GET_CVALUE(uint64, dimension->lower_limit), GET_CVALUE( int64, l->elements[i])) > 0 ) - {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (using constant value of %"PRId64", should be >= %"PRIu64").", GET_CVALUE( int64, l->elements[i]), GET_CVALUE(uint64, dimension->lower_limit)); continue;} - - if ( VALID_CVALUE(uint64, l->elements[i]) && VALID_CVALUE(uint64, dimension->lower_limit)) - if ( GET_CVALUE(uint64, l->elements[i]) < GET_CVALUE(uint64, dimension->lower_limit)) - {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (using constant value of %"PRIu64", should be >= %"PRIu64").", GET_CVALUE(uint64, l->elements[i]), GET_CVALUE(uint64, dimension->lower_limit)); continue;} - - if ( VALID_CVALUE(uint64, l->elements[i]) && VALID_CVALUE( int64, dimension->lower_limit)) - if ( cmp_unsigned_signed(GET_CVALUE(uint64, l->elements[i]), GET_CVALUE( int64, dimension->lower_limit)) < 0 ) - {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (using constant value of %"PRIu64", should be >= %"PRId64").", GET_CVALUE(uint64, l->elements[i]), GET_CVALUE( int64, dimension->lower_limit)); continue;} + if ( VALID_CVALUE( int64, l->get_element(i)) && VALID_CVALUE( int64, dimension->lower_limit)) + if ( GET_CVALUE( int64, l->get_element(i)) < GET_CVALUE( int64, dimension->lower_limit) ) + {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (using constant value of %"PRId64", should be >= %"PRId64").", GET_CVALUE( int64, l->get_element(i)), GET_CVALUE( int64, dimension->lower_limit)); continue;} + + if ( VALID_CVALUE( int64, l->get_element(i)) && VALID_CVALUE(uint64, dimension->lower_limit)) + if ( cmp_unsigned_signed( GET_CVALUE(uint64, dimension->lower_limit), GET_CVALUE( int64, l->get_element(i))) > 0 ) + {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (using constant value of %"PRId64", should be >= %"PRIu64").", GET_CVALUE( int64, l->get_element(i)), GET_CVALUE(uint64, dimension->lower_limit)); continue;} + + if ( VALID_CVALUE(uint64, l->get_element(i)) && VALID_CVALUE(uint64, dimension->lower_limit)) + if ( GET_CVALUE(uint64, l->get_element(i)) < GET_CVALUE(uint64, dimension->lower_limit)) + {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (using constant value of %"PRIu64", should be >= %"PRIu64").", GET_CVALUE(uint64, l->get_element(i)), GET_CVALUE(uint64, dimension->lower_limit)); continue;} + + if ( VALID_CVALUE(uint64, l->get_element(i)) && VALID_CVALUE( int64, dimension->lower_limit)) + if ( cmp_unsigned_signed(GET_CVALUE(uint64, l->get_element(i)), GET_CVALUE( int64, dimension->lower_limit)) < 0 ) + {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (using constant value of %"PRIu64", should be >= %"PRId64").", GET_CVALUE(uint64, l->get_element(i)), GET_CVALUE( int64, dimension->lower_limit)); continue;} /* Repeat the same check, now for upper limit */ - if ( VALID_CVALUE( int64, l->elements[i]) && VALID_CVALUE( int64, dimension->upper_limit)) - if ( GET_CVALUE( int64, l->elements[i]) > GET_CVALUE( int64, dimension->upper_limit)) - {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (using constant value of %"PRId64", should be <= %"PRId64").", GET_CVALUE( int64, l->elements[i]), GET_CVALUE( int64, dimension->upper_limit)); continue;} - - if ( VALID_CVALUE( int64, l->elements[i]) && VALID_CVALUE(uint64, dimension->upper_limit)) - if ( cmp_unsigned_signed( GET_CVALUE(uint64, dimension->upper_limit), GET_CVALUE( int64, l->elements[i])) < 0 ) - {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (using constant value of %"PRId64", should be <= %"PRIu64").", GET_CVALUE( int64, l->elements[i]), GET_CVALUE(uint64, dimension->upper_limit)); continue;} - - if ( VALID_CVALUE(uint64, l->elements[i]) && VALID_CVALUE(uint64, dimension->upper_limit)) - if ( GET_CVALUE(uint64, l->elements[i]) > GET_CVALUE(uint64, dimension->upper_limit)) - {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (using constant value of %"PRIu64", should be <= %"PRIu64").", GET_CVALUE(uint64, l->elements[i]), GET_CVALUE(uint64, dimension->upper_limit)); continue;} + if ( VALID_CVALUE( int64, l->get_element(i)) && VALID_CVALUE( int64, dimension->upper_limit)) + if ( GET_CVALUE( int64, l->get_element(i)) > GET_CVALUE( int64, dimension->upper_limit)) + {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (using constant value of %"PRId64", should be <= %"PRId64").", GET_CVALUE( int64, l->get_element(i)), GET_CVALUE( int64, dimension->upper_limit)); continue;} + + if ( VALID_CVALUE( int64, l->get_element(i)) && VALID_CVALUE(uint64, dimension->upper_limit)) + if ( cmp_unsigned_signed( GET_CVALUE(uint64, dimension->upper_limit), GET_CVALUE( int64, l->get_element(i))) < 0 ) + {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (using constant value of %"PRId64", should be <= %"PRIu64").", GET_CVALUE( int64, l->get_element(i)), GET_CVALUE(uint64, dimension->upper_limit)); continue;} + + if ( VALID_CVALUE(uint64, l->get_element(i)) && VALID_CVALUE(uint64, dimension->upper_limit)) + if ( GET_CVALUE(uint64, l->get_element(i)) > GET_CVALUE(uint64, dimension->upper_limit)) + {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (using constant value of %"PRIu64", should be <= %"PRIu64").", GET_CVALUE(uint64, l->get_element(i)), GET_CVALUE(uint64, dimension->upper_limit)); continue;} - if ( VALID_CVALUE(uint64, l->elements[i]) && VALID_CVALUE( int64, dimension->upper_limit)) - if ( cmp_unsigned_signed(GET_CVALUE(uint64, l->elements[i]), GET_CVALUE( int64, dimension->upper_limit)) > 0 ) - {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (using constant value of %"PRIu64", should be <= %"PRId64").", GET_CVALUE(uint64, l->elements[i]), GET_CVALUE( int64, dimension->upper_limit)); continue;} + if ( VALID_CVALUE(uint64, l->get_element(i)) && VALID_CVALUE( int64, dimension->upper_limit)) + if ( cmp_unsigned_signed(GET_CVALUE(uint64, l->get_element(i)), GET_CVALUE( int64, dimension->upper_limit)) > 0 ) + {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (using constant value of %"PRIu64", should be <= %"PRId64").", GET_CVALUE(uint64, l->get_element(i)), GET_CVALUE( int64, dimension->upper_limit)); continue;} } } diff -r 52f63e622604 -r 4d7183013481 stage3/case_elements_check.cc --- a/stage3/case_elements_check.cc Wed Apr 12 08:44:42 2017 +0100 +++ b/stage3/case_elements_check.cc Sun Apr 16 08:46:58 2017 +0100 @@ -242,7 +242,7 @@ // SYM_LIST(case_list_c) void *case_elements_check_c::visit(case_list_c *symbol) { for (int i = 0; i < symbol->n; i++) - case_elements_list.push_back(symbol->elements[i]); + case_elements_list.push_back(symbol->get_element(i)); return NULL; } diff -r 52f63e622604 -r 4d7183013481 stage3/constant_folding.cc --- a/stage3/constant_folding.cc Wed Apr 12 08:44:42 2017 +0100 +++ b/stage3/constant_folding.cc Sun Apr 16 08:46:58 2017 +0100 @@ -1038,7 +1038,7 @@ */ if ((NULL != symbol->il_operand) && ((NULL == symbol->simple_instr_list) || (0 == ((list_c *)symbol->simple_instr_list)->n))) ERROR; // stage2 is not behaving as we expect it to! if (NULL != symbol->il_operand) - symbol->il_operand->const_value = ((list_c *)symbol->simple_instr_list)->elements[0]->const_value; + symbol->il_operand->const_value = ((list_c *)symbol->simple_instr_list)->get_element(0)->const_value; return NULL; } @@ -1089,10 +1089,10 @@ return NULL; /* List is empty! Nothing to do. */ for(int i = 0; i < symbol->n; i++) - symbol->elements[i]->accept(*this); + symbol->get_element(i)->accept(*this); /* This object has (inherits) the same cvalues as the il_jump_operator */ - symbol->const_value = symbol->elements[symbol->n-1]->const_value; + symbol->const_value = symbol->get_element(symbol->n-1)->const_value; return NULL; } @@ -1367,8 +1367,8 @@ for (i = 0; i < symbol->n; i++) { // first analyse the configurations - if (NULL != dynamic_cast(symbol->elements[i])) - symbol->elements[i]->accept(*this); + if (NULL != dynamic_cast(symbol->get_element(i))) + symbol->get_element(i)->accept(*this); } for (i = 0; i < symbol->n; i++) { @@ -1377,8 +1377,8 @@ * loop. However, this is OK as the only difference would be how the VAR_EXTERN are handled, * and that is taken care of in the visit(external_declaration_c) visitor! */ - if (NULL == dynamic_cast(symbol->elements[i])) - symbol->elements[i]->accept(*this); + if (NULL == dynamic_cast(symbol->get_element(i))) + symbol->get_element(i)->accept(*this); } return NULL; @@ -1465,14 +1465,14 @@ list_c *list = dynamic_cast(var_list); if (NULL == list) ERROR; for (int i = 0; i < list->n; i++) { - token_c *var_name = dynamic_cast(list->elements[i]); + token_c *var_name = dynamic_cast(list->get_element(i)); if (NULL == var_name) { - if (NULL != dynamic_cast(list->elements[i])) + if (NULL != dynamic_cast(list->get_element(i))) continue; // this is an extensible standard function. Ignore this variable, and continue! - // debug_c::print(list->elements[i]); + // debug_c::print(list->get_element(i)); ERROR; } - list->elements[i]->const_value = init_value->const_value; + list->get_element(i)->const_value = init_value->const_value; if (fixed_init_value_) { (*values)[var_name->value] = init_value->const_value; if (is_global_var) diff -r 52f63e622604 -r 4d7183013481 stage3/fill_candidate_datatypes.cc --- a/stage3/fill_candidate_datatypes.cc Wed Apr 12 08:44:42 2017 +0100 +++ b/stage3/fill_candidate_datatypes.cc Sun Apr 16 08:46:58 2017 +0100 @@ -958,7 +958,15 @@ type_spec->accept(*this); // use bottom->up algorithm!! - if (NULL != init_value) init_value->accept(*this); + /* NOTE: In special cases we will run a modified bottom->up algorithm, i.e. with a top->down indication of + * tentative candidate_datatypes... + * (e.g. structure_element_initialization_list_c). The tentative candidate_datatypes (a list of + * candidate_datatypes to consider while running the bottom->up algorithm) will actually be the + * datatypes in symbol->parent->candidate_datatpes + * This implies that we can only run this bottom->up algorithm on the initial values _after_ + * having set the symbol->candidate_datatpes of the type specification (i.e. the symbol parameter) + */ + if (NULL != init_value) init_value->accept(*this); /* NOTE: Even if the constant and the type are of incompatible data types, we let the * ***_spec_init_c object inherit the data type of the type declaration (simple_specification) * This will let us produce more informative error messages when checking data type compatibility @@ -1036,7 +1044,7 @@ /* We already know the datatype of the enumerated_value(s) in the list, so we set them directly instead of recursively calling the enumerated_value_c visit method! */ for(int i = 0; i < symbol->n; i++) - add_datatype_to_candidate_list(symbol->elements[i], current_enumerated_spec_type); // top->down algorithm!! + add_datatype_to_candidate_list(symbol->get_element(i), current_enumerated_spec_type); // top->down algorithm!! return NULL; } @@ -1163,9 +1171,56 @@ /* structure_initialization: '(' structure_element_initialization_list ')' */ /* structure_element_initialization_list ',' structure_element_initialization */ // SYM_LIST(structure_element_initialization_list_c) +void *fill_candidate_datatypes_c::visit(structure_element_initialization_list_c *symbol) { + // use bottom->up algorithm -> first let all elements determine their candidate_datatypes + iterator_visitor_c::visit(symbol); // call visit(structure_element_initialization_c *) on all elements + + for (unsigned int i = 0; i < symbol->parent->candidate_datatypes.size(); i++) { // size() should always be 1 here -> a single structure or FB type! + // assume symbol->parent->candidate_datatypes[i] is a FB type + search_varfb_instance_type_c search_varfb_instance_type(symbol->parent->candidate_datatypes[i]); + // assume symbol->parent->candidate_datatypes[i] is a STRUCT data type + structure_element_declaration_list_c *struct_decl = dynamic_cast(symbol->parent->candidate_datatypes[i]); + // flag indicating all struct_elem->structure_element_name are structure elements found in the symbol->parent->candidate_datatypes[i] datatype + int flag_all_elem_ok = 1; // assume all found + for (int k = 0; k < symbol->n; k++) { + structure_element_initialization_c *struct_elem = dynamic_cast(symbol->get_element(k)); + if (struct_elem == NULL) ERROR; + + // assume symbol->parent is a FB type... + symbol_c *type = NULL; + if (struct_decl != NULL) { + // search in the struct!! + type = search_base_type_c::get_basetype_decl(struct_decl->find_element(struct_elem->structure_element_name)); + } else { + // parent is a FB type. Lets search there!! + type = search_varfb_instance_type.get_basetype_decl(struct_elem->structure_element_name); + } + if (!get_datatype_info_c::is_ANY_ELEMENTARY(type) && get_datatype_info_c::is_type_valid(type)) { + // for non-elementary datatypes, we must use a top->down algorithm!! + add_datatype_to_candidate_list(struct_elem, type); + struct_elem->accept(*this); + } + if (search_in_candidate_datatype_list(type, struct_elem->candidate_datatypes) < 0) { + flag_all_elem_ok = 0; // the necessary datatype for structure init element is not a candidate_datatype of that element + } + } + if (flag_all_elem_ok) { + add_datatype_to_candidate_list(symbol, symbol->parent->candidate_datatypes[i]); + } + } + return NULL; +} + /* structure_element_name ASSIGN value */ // SYM_REF2(structure_element_initialization_c, structure_element_name, value) +void *fill_candidate_datatypes_c::visit(structure_element_initialization_c *symbol) { + symbol->value->accept(*this); + symbol->candidate_datatypes = symbol->value->candidate_datatypes; + // Note that candidate_datatypes of symbol->structure_element_name are left empty! + return NULL; +} + /* string_type_name ':' elementary_string_type_name string_type_declaration_size string_type_declaration_init */ // SYM_REF4(string_type_declaration_c, string_type_name, elementary_string_type_name, string_type_declaration_size, string_type_declaration_init/* may be == NULL! */) @@ -1369,7 +1424,7 @@ // NOTE: this method is not required since fill_candidate_datatypes_c inherits from iterator_visitor_c. TODO: delete this method! void *fill_candidate_datatypes_c::visit(var1_list_c *symbol) { - for(int i = 0; i < symbol->n; i++) {symbol->elements[i]->accept(*this);} + for(int i = 0; i < symbol->n; i++) {symbol->get_element(i)->accept(*this);} return NULL; } @@ -1648,7 +1703,7 @@ */ for(int j = 0; j < 2; j++) { for(int i = 0; i < symbol->n; i++) { - symbol->elements[i]->accept(*this); + symbol->get_element(i)->accept(*this); } } return NULL; @@ -1763,7 +1818,7 @@ */ if ((NULL != symbol->il_operand) && ((NULL == symbol->simple_instr_list) || (0 == ((list_c *)symbol->simple_instr_list)->n))) ERROR; // stage2 is not behaving as we expect it to! if (NULL != symbol->il_operand) - symbol->il_operand->candidate_datatypes = ((list_c *)symbol->simple_instr_list)->elements[0]->candidate_datatypes; + symbol->il_operand->candidate_datatypes = ((list_c *)symbol->simple_instr_list)->get_element(0)->candidate_datatypes; /* Now check the if the data type semantics of operation are correct, */ il_operand = symbol->simple_instr_list; @@ -1860,10 +1915,10 @@ return NULL; /* List is empty! Nothing to do. */ for(int i = 0; i < symbol->n; i++) - symbol->elements[i]->accept(*this); + symbol->get_element(i)->accept(*this); /* This object has (inherits) the same candidate datatypes as the last il_instruction */ - symbol->candidate_datatypes = symbol->elements[symbol->n-1]->candidate_datatypes; + symbol->candidate_datatypes = symbol->get_element(symbol->n-1)->candidate_datatypes; if (debug) std::cout << "simple_instr_list_c [" << symbol->candidate_datatypes.size() << "] result.\n"; return NULL; diff -r 52f63e622604 -r 4d7183013481 stage3/fill_candidate_datatypes.hh --- a/stage3/fill_candidate_datatypes.hh Wed Apr 12 08:44:42 2017 +0100 +++ b/stage3/fill_candidate_datatypes.hh Sun Apr 16 08:46:58 2017 +0100 @@ -211,8 +211,8 @@ void *visit(initialized_structure_c *symbol); // void *visit(structure_element_declaration_list_c *symbol); // void *visit(structure_element_declaration_c *symbol); -// void *visit(structure_element_initialization_list_c *symbol); -// void *visit(structure_element_initialization_c *symbol); + void *visit(structure_element_initialization_list_c *symbol); + void *visit(structure_element_initialization_c *symbol); // void *visit(string_type_declaration_c *symbol); void *visit(fb_spec_init_c *symbol); diff -r 52f63e622604 -r 4d7183013481 stage3/flow_control_analysis.cc --- a/stage3/flow_control_analysis.cc Wed Apr 12 08:44:42 2017 +0100 +++ b/stage3/flow_control_analysis.cc Sun Apr 16 08:46:58 2017 +0100 @@ -218,8 +218,8 @@ prev_il_instruction_is_JMP_or_RET = false; for(int i = 0; i < symbol->n; i++) { prev_il_instruction = NULL; - if (i > 0) prev_il_instruction = symbol->elements[i-1]; - curr_il_instruction = symbol->elements[i]; + if (i > 0) prev_il_instruction = symbol->get_element(i-1); + curr_il_instruction = symbol->get_element(i); curr_il_instruction->accept(*this); curr_il_instruction = NULL; } @@ -310,8 +310,8 @@ void *flow_control_analysis_c::visit(simple_instr_list_c *symbol) { for(int i = 0; i < symbol->n; i++) { /* The prev_il_instruction for element[0] was set in visit(il_expression_c *) */ - if (i>0) prev_il_instruction = symbol->elements[i-1]; - symbol->elements[i]->accept(*this); + if (i>0) prev_il_instruction = symbol->get_element(i-1); + symbol->get_element(i)->accept(*this); } return NULL; } diff -r 52f63e622604 -r 4d7183013481 stage3/forced_narrow_candidate_datatypes.cc --- a/stage3/forced_narrow_candidate_datatypes.cc Wed Apr 12 08:44:42 2017 +0100 +++ b/stage3/forced_narrow_candidate_datatypes.cc Sun Apr 16 08:46:58 2017 +0100 @@ -161,7 +161,7 @@ void *forced_narrow_candidate_datatypes_c::visit(instruction_list_c *symbol) { for(int j = 0; j < 2; j++) { for(int i = symbol->n-1; i >= 0; i--) { - symbol->elements[i]->accept(*this); + symbol->get_element(i)->accept(*this); } } @@ -171,7 +171,7 @@ */ /* for(int i = symbol->n-1; i >= 0; i--) { - if (NULL == symbol->elements[i]->datatype) + if (NULL == symbol->get_element(i)->datatype) ERROR; } */ diff -r 52f63e622604 -r 4d7183013481 stage3/narrow_candidate_datatypes.cc --- a/stage3/narrow_candidate_datatypes.cc Wed Apr 12 08:44:42 2017 +0100 +++ b/stage3/narrow_candidate_datatypes.cc Sun Apr 16 08:46:58 2017 +0100 @@ -609,8 +609,8 @@ // SYM_LIST(enumerated_value_list_c) void *narrow_candidate_datatypes_c::visit(enumerated_value_list_c *symbol) { //if (NULL == symbol->datatype) ERROR; // Comented out-> Reserve this check for the print_datatypes_error_c ??? - for(int i = 0; i < symbol->n; i++) set_datatype(symbol->datatype, symbol->elements[i]); -//for(int i = 0; i < symbol->n; i++) if (NULL == symbol->elements[i]->datatype) ERROR; // Comented out-> Reserve this check for the print_datatypes_error_c ??? + for(int i = 0; i < symbol->n; i++) set_datatype(symbol->datatype, symbol->get_element(i)); +//for(int i = 0; i < symbol->n; i++) if (NULL == symbol->get_element(i)->datatype) ERROR; // Comented out-> Reserve this check for the print_datatypes_error_c ??? return NULL; } @@ -672,11 +672,45 @@ /* structure_initialization: '(' structure_element_initialization_list ')' */ /* structure_element_initialization_list ',' structure_element_initialization */ // SYM_LIST(structure_element_initialization_list_c) -// Not needed ??? +void *narrow_candidate_datatypes_c::visit(structure_element_initialization_list_c *symbol) { + symbol_c *type = NULL; + + // first try to narrow with the correct type, if valid. + if (!get_datatype_info_c::is_type_valid(type)) type = symbol->datatype; + // to reduce number of error messages, we try to narrow with parent's spec_init->datatype + if (!get_datatype_info_c::is_type_valid(type)) type = symbol->parent->datatype; + + if (get_datatype_info_c::is_type_valid(type)) { + // We need to iterate and determine the required datatype of each structure element + // assume type is a FB type + search_varfb_instance_type_c search_varfb_instance_type(type); + // assume type is a STRUCT type + structure_element_declaration_list_c *struct_decl = dynamic_cast(type); + for (int k = 0; k < symbol->n; k++) { + structure_element_initialization_c *struct_elem = (structure_element_initialization_c *)symbol->get_element(k); + symbol_c *type = NULL; + if (struct_decl == NULL) { + // type is not a struct. Must be a FB. + type = search_varfb_instance_type.get_basetype_decl(struct_elem->structure_element_name); + } else { + // type is a struct. + type = search_base_type_c::get_basetype_decl(struct_decl->find_element(struct_elem->structure_element_name)); + } + set_datatype(type, struct_elem); + struct_elem->accept(*this); + /* We do best effort narrowing, even in the presence of errors, to reduce number of error messages + * so the following two assertions are not always met. + */ + // if (!get_datatype_info_c::is_type_valid(type)) ERROR; + // if (struct_elem->datatype == NULL) ERROR; // should never occur. Already checked in fill_candidate_datatypes_c + } + } + return NULL; +} /* structure_element_name ASSIGN value */ // SYM_REF2(structure_element_initialization_c, structure_element_name, value) -// Not needed ??? +void *narrow_candidate_datatypes_c::visit(structure_element_initialization_c *symbol) {set_datatype(symbol->datatype, symbol->value); symbol->value->accept(*this); return NULL;} /* string_type_name ':' elementary_string_type_name string_type_declaration_size string_type_declaration_init */ // SYM_REF4(string_type_declaration_c, string_type_name, elementary_string_type_name, string_type_declaration_size, string_type_declaration_init/* may be == NULL! */) @@ -754,11 +788,11 @@ // SYM_LIST(subscript_list_c) void *narrow_candidate_datatypes_c::visit(subscript_list_c *symbol) { for (int i = 0; i < symbol->n; i++) { - for (unsigned int k = 0; k < symbol->elements[i]->candidate_datatypes.size(); k++) { - if (get_datatype_info_c::is_ANY_INT(symbol->elements[i]->candidate_datatypes[k])) - symbol->elements[i]->datatype = symbol->elements[i]->candidate_datatypes[k]; + for (unsigned int k = 0; k < symbol->get_element(i)->candidate_datatypes.size(); k++) { + if (get_datatype_info_c::is_ANY_INT(symbol->get_element(i)->candidate_datatypes[k])) + symbol->get_element(i)->datatype = symbol->get_element(i)->candidate_datatypes[k]; } - symbol->elements[i]->accept(*this); + symbol->get_element(i)->accept(*this); } return NULL; } @@ -828,8 +862,8 @@ void *narrow_candidate_datatypes_c::visit(var1_list_c *symbol) { #if 0 /* We don't really need to set the datatype of each variable. We just check the declaration itself! */ for(int i = 0; i < symbol->n; i++) { - if (symbol->elements[i]->candidate_datatypes.size() == 1) - symbol->elements[i]->datatype = symbol->elements[i]->candidate_datatypes[0]; + if (symbol->get_element(i)->candidate_datatypes.size() == 1) + symbol->get_element(i)->datatype = symbol->get_element(i)->candidate_datatypes[0]; } #endif return NULL; @@ -1008,7 +1042,7 @@ */ for(int j = 0; j < 2; j++) { for(int i = symbol->n-1; i >= 0; i--) { - symbol->elements[i]->accept(*this); + symbol->get_element(i)->accept(*this); } } return NULL; @@ -1123,7 +1157,7 @@ */ if ((NULL != symbol->il_operand) && ((NULL == symbol->simple_instr_list) || (0 == ((list_c *)symbol->simple_instr_list)->n))) ERROR; // stage2 is not behaving as we expect it to! if (NULL != symbol->il_operand) - symbol->il_operand->datatype = ((list_c *)symbol->simple_instr_list)->elements[0]->datatype; + symbol->il_operand->datatype = ((list_c *)symbol->simple_instr_list)->get_element(0)->datatype; return NULL; } @@ -1195,10 +1229,10 @@ /* This object is referenced by il_expression_c objects */ void *narrow_candidate_datatypes_c::visit(simple_instr_list_c *symbol) { if (symbol->n > 0) - symbol->elements[symbol->n - 1]->datatype = symbol->datatype; + symbol->get_element(symbol->n - 1)->datatype = symbol->datatype; for(int i = symbol->n-1; i >= 0; i--) { - symbol->elements[i]->accept(*this); + symbol->get_element(i)->accept(*this); } return NULL; } @@ -1730,8 +1764,8 @@ // SYM_LIST(case_element_list_c) void *narrow_candidate_datatypes_c::visit(case_element_list_c *symbol) { for (int i = 0; i < symbol->n; i++) { - symbol->elements[i]->datatype = symbol->datatype; - symbol->elements[i]->accept(*this); + symbol->get_element(i)->datatype = symbol->datatype; + symbol->get_element(i)->accept(*this); } return NULL; } @@ -1748,12 +1782,12 @@ // SYM_LIST(case_list_c) void *narrow_candidate_datatypes_c::visit(case_list_c *symbol) { for (int i = 0; i < symbol->n; i++) { - for (unsigned int k = 0; k < symbol->elements[i]->candidate_datatypes.size(); k++) { - if (get_datatype_info_c::is_type_equal(symbol->datatype, symbol->elements[i]->candidate_datatypes[k])) - symbol->elements[i]->datatype = symbol->elements[i]->candidate_datatypes[k]; + for (unsigned int k = 0; k < symbol->get_element(i)->candidate_datatypes.size(); k++) { + if (get_datatype_info_c::is_type_equal(symbol->datatype, symbol->get_element(i)->candidate_datatypes[k])) + symbol->get_element(i)->datatype = symbol->get_element(i)->candidate_datatypes[k]; } /* NOTE: this may be an integer, a subrange_c, or a enumerated value! */ - symbol->elements[i]->accept(*this); + symbol->get_element(i)->accept(*this); } return NULL; } diff -r 52f63e622604 -r 4d7183013481 stage3/narrow_candidate_datatypes.hh --- a/stage3/narrow_candidate_datatypes.hh Wed Apr 12 08:44:42 2017 +0100 +++ b/stage3/narrow_candidate_datatypes.hh Sun Apr 16 08:46:58 2017 +0100 @@ -185,8 +185,8 @@ void *visit(initialized_structure_c *symbol); // void *visit(structure_element_declaration_list_c *symbol); // void *visit(structure_element_declaration_c *symbol); -// void *visit(structure_element_initialization_list_c *symbol); -// void *visit(structure_element_initialization_c *symbol); + void *visit(structure_element_initialization_list_c *symbol); + void *visit(structure_element_initialization_c *symbol); // void *visit(string_type_declaration_c *symbol); void *visit(fb_spec_init_c *symbol); diff -r 52f63e622604 -r 4d7183013481 stage3/print_datatypes_error.cc --- a/stage3/print_datatypes_error.cc Wed Apr 12 08:44:42 2017 +0100 +++ b/stage3/print_datatypes_error.cc Sun Apr 16 08:46:58 2017 +0100 @@ -545,6 +545,16 @@ } + +void *print_datatypes_error_c::visit(structure_element_initialization_c *symbol) { + symbol->value->accept(*this); + if (!get_datatype_info_c::is_type_valid(symbol->datatype)) + STAGE3_ERROR(0, symbol, symbol, "Initialization element identifier (%s) is not declared in referenced structure/FB scope, or is set to value of incompatible datatype.", + symbol->structure_element_name->token->value); + return NULL; +} + + /*********************/ /* B 1.4 - Variables */ /*********************/ @@ -587,9 +597,9 @@ void *print_datatypes_error_c::visit(subscript_list_c *symbol) { for (int i = 0; i < symbol->n; i++) { int start_error_count = error_count; - symbol->elements[i]->accept(*this); + symbol->get_element(i)->accept(*this); /* The following error message will only get printed if the current_display_error_level is set higher than 0! */ - if ((start_error_count == error_count) && (!get_datatype_info_c::is_type_valid(symbol->elements[i]->datatype))) + if ((start_error_count == error_count) && (!get_datatype_info_c::is_type_valid(symbol->get_element(i)->datatype))) STAGE3_ERROR(0, symbol, symbol, "Invalid data type for array subscript field."); } return NULL; diff -r 52f63e622604 -r 4d7183013481 stage3/print_datatypes_error.hh --- a/stage3/print_datatypes_error.hh Wed Apr 12 08:44:42 2017 +0100 +++ b/stage3/print_datatypes_error.hh Sun Apr 16 08:46:58 2017 +0100 @@ -161,6 +161,8 @@ void *visit(simple_spec_init_c *symbol); // void *visit(data_type_declaration_c *symbol); /* use base iterator_c method! */ void *visit(enumerated_value_c *symbol); +// void *visit(structure_element_initialization_list_c *symbol); + void *visit(structure_element_initialization_c *symbol); /*********************/ /* B 1.4 - Variables */ diff -r 52f63e622604 -r 4d7183013481 stage3/remove_forward_dependencies.cc --- a/stage3/remove_forward_dependencies.cc Wed Apr 12 08:44:42 2017 +0100 +++ b/stage3/remove_forward_dependencies.cc Sun Apr 16 08:46:58 2017 +0100 @@ -209,10 +209,10 @@ /* Note too that circular references in derived datatypes is also not possible due to sytax! */ int initial_error_count = error_count; for (int i = 0; i < symbol->n; i++) - if ( (inserted_symbols.find(symbol->elements[i]) == inserted_symbols.end()) // if not copied to new AST - &&( (NULL != dynamic_cast (symbol->elements[i])) // and (is a FB - ||(NULL != dynamic_cast < function_declaration_c *>(symbol->elements[i])))) // or a Function) - STAGE3_ERROR(0, symbol->elements[i], symbol->elements[i], "POU (%s) contains a self-reference and/or belongs in a circular referencing loop", get_datatype_info_c::get_id_str(symbol->elements[i])); + if ( (inserted_symbols.find(symbol->get_element(i)) == inserted_symbols.end()) // if not copied to new AST + &&( (NULL != dynamic_cast (symbol->get_element(i))) // and (is a FB + ||(NULL != dynamic_cast < function_declaration_c *>(symbol->get_element(i))))) // or a Function) + STAGE3_ERROR(0, symbol->get_element(i), symbol->get_element(i), "POU (%s) contains a self-reference and/or belongs in a circular referencing loop", get_datatype_info_c::get_id_str(symbol->get_element(i))); if (error_count == initial_error_count) ERROR; // We were unable to determine which POUs contain the circular references!! } @@ -228,8 +228,8 @@ /* first insert all the derived datatype declarations, in the same order by which they are delcared in the original AST */ /* Since IEC 61131-3 does not allow FBs in arrays or structures, it is actually safe to place all the datatypes before all the POUs! */ for (int i = 0; i < symbol->n; i++) - if (NULL != dynamic_cast (symbol->elements[i])) - new_tree->add_element(symbol->elements[i]); + if (NULL != dynamic_cast (symbol->get_element(i))) + new_tree->add_element(symbol->get_element(i)); /* now do the POUs, in whatever order is necessary to guarantee no forward references. */ long long int old_tree_pou_count = pou_count_c::get_count(symbol); @@ -241,7 +241,7 @@ cycle_count++; prev_n = new_tree->n; current_code_generation_pragma = default_code_generation_pragma; - for (int i = 0; i < symbol->n; i++) symbol->elements[i]->accept(*this); + for (int i = 0; i < symbol->n; i++) symbol->get_element(i)->accept(*this); } while (prev_n != new_tree->n); // repeat while new elementns are still being added to the new AST if (old_tree_pou_count != pou_count_c::get_count(new_tree)) diff -r 52f63e622604 -r 4d7183013481 stage4/generate_c/generate_c.cc --- a/stage4/generate_c/generate_c.cc Wed Apr 12 08:44:42 2017 +0100 +++ b/stage4/generate_c/generate_c.cc Sun Apr 16 08:46:58 2017 +0100 @@ -2191,7 +2191,7 @@ pous_incl_s4o.print("#include \"accessor.h\"\n#include \"iec_std_lib.h\"\n\n"); for(int i = 0; i < symbol->n; i++) { - symbol->elements[i]->accept(*this); + symbol->get_element(i)->accept(*this); } pous_incl_s4o.print("#endif //__POUS_H\n"); @@ -2229,8 +2229,8 @@ /* helper symbol for data_type_declaration */ void *visit(type_declaration_list_c *symbol) { for(int i = 0; i < symbol->n; i++) { - symbol->elements[i]->accept(generate_c_implicit_typedecl); - symbol->elements[i]->accept(generate_c_typedecl); + symbol->get_element(i)->accept(generate_c_implicit_typedecl); + symbol->get_element(i)->accept(generate_c_typedecl); } return NULL; } diff -r 52f63e622604 -r 4d7183013481 stage4/generate_c/generate_c_base.cc --- a/stage4/generate_c/generate_c_base.cc Wed Apr 12 08:44:42 2017 +0100 +++ b/stage4/generate_c/generate_c_base.cc Sun Apr 16 08:46:58 2017 +0100 @@ -201,13 +201,13 @@ if (list->n > 0) { //std::cout << "generate_c_base_c::print_list(n = " << list->n << ") 000\n"; s4o.print(pre_elem_str); - list->elements[0]->accept(*visitor); + list->get_element(0)->accept(*visitor); } for(int i = 1; i < list->n; i++) { //std::cout << "generate_c_base_c::print_list " << i << "\n"; s4o.print(inter_elem_str); - list->elements[i]->accept(*visitor); + list->get_element(i)->accept(*visitor); } if (list->n > 0) diff -r 52f63e622604 -r 4d7183013481 stage4/generate_c/generate_c_il.cc --- a/stage4/generate_c/generate_c_il.cc Wed Apr 12 08:44:42 2017 +0100 +++ b/stage4/generate_c/generate_c_il.cc Sun Apr 16 08:46:58 2017 +0100 @@ -661,7 +661,7 @@ if (dimension == NULL) ERROR; s4o.print("[("); - symbol->elements[i]->accept(*this); + symbol->get_element(i)->accept(*this); s4o.print(") - ("); dimension->accept(*this); s4o.print(")]"); @@ -711,9 +711,9 @@ declare_implicit_variable_back(); for(int i = 0; i < symbol->n; i++) { - print_line_directive(symbol->elements[i]); + print_line_directive(symbol->get_element(i)); s4o.print(s4o.indent_spaces); - symbol->elements[i]->accept(*this); + symbol->get_element(i)->accept(*this); s4o.print(";\n"); } return NULL; diff -r 52f63e622604 -r 4d7183013481 stage4/generate_c/generate_c_sfc.cc --- a/stage4/generate_c/generate_c_sfc.cc Wed Apr 12 08:44:42 2017 +0100 +++ b/stage4/generate_c/generate_c_sfc.cc Sun Apr 16 08:46:58 2017 +0100 @@ -443,7 +443,7 @@ for(int i = 0; i < symbol->n; i++) { s4o.print(GET_VAR); s4o.print("("); - print_step_argument(symbol->elements[i], "X"); + print_step_argument(symbol->get_element(i), "X"); s4o.print(")"); if (i < symbol->n - 1) { s4o.print(" && "); @@ -452,12 +452,12 @@ break; case stepset_sg: for(int i = 0; i < symbol->n; i++) { - print_set_step(symbol->elements[i]); + print_set_step(symbol->get_element(i)); } break; case stepreset_sg: for(int i = 0; i < symbol->n; i++) { - print_reset_step(symbol->elements[i]); + print_reset_step(symbol->get_element(i)); } break; default: @@ -710,8 +710,8 @@ generate_c_sfc_elements->reset_transition_number(); for(i = 0; i < symbol->n; i++) { - symbol->elements[i]->accept(*this); - generate_c_sfc_elements->generate(symbol->elements[i], generate_c_sfc_elements_c::transitionlist_sg); + symbol->get_element(i)->accept(*this); + generate_c_sfc_elements->generate(symbol->get_element(i), generate_c_sfc_elements_c::transitionlist_sg); } s4o.print(s4o.indent_spaces +"INT i;\n"); @@ -853,7 +853,7 @@ s4o.print(s4o.indent_spaces + "// Transitions reset steps\n"); generate_c_sfc_elements->reset_transition_number(); for(i = 0; i < symbol->n; i++) { - generate_c_sfc_elements->generate(symbol->elements[i], generate_c_sfc_elements_c::stepreset_sg); + generate_c_sfc_elements->generate(symbol->get_element(i), generate_c_sfc_elements_c::stepreset_sg); } s4o.print("\n"); @@ -861,14 +861,14 @@ s4o.print(s4o.indent_spaces + "// Transitions set steps\n"); generate_c_sfc_elements->reset_transition_number(); for(i = 0; i < symbol->n; i++) { - generate_c_sfc_elements->generate(symbol->elements[i], generate_c_sfc_elements_c::stepset_sg); + generate_c_sfc_elements->generate(symbol->get_element(i), generate_c_sfc_elements_c::stepset_sg); } s4o.print("\n"); /* generate step association */ s4o.print(s4o.indent_spaces + "// Steps association\n"); for(i = 0; i < symbol->n; i++) { - generate_c_sfc_elements->generate(symbol->elements[i], generate_c_sfc_elements_c::actionassociation_sg); + generate_c_sfc_elements->generate(symbol->get_element(i), generate_c_sfc_elements_c::actionassociation_sg); } s4o.print("\n"); @@ -967,7 +967,7 @@ } } for(i = 0; i < symbol->n; i++) { - generate_c_sfc_elements->generate(symbol->elements[i], generate_c_sfc_elements_c::actionbody_sg); + generate_c_sfc_elements->generate(symbol->get_element(i), generate_c_sfc_elements_c::actionbody_sg); } s4o.print("\n"); diff -r 52f63e622604 -r 4d7183013481 stage4/generate_c/generate_c_sfcdecl.cc --- a/stage4/generate_c/generate_c_sfcdecl.cc Wed Apr 12 08:44:42 2017 +0100 +++ b/stage4/generate_c/generate_c_sfcdecl.cc Sun Apr 16 08:46:58 2017 +0100 @@ -85,7 +85,7 @@ switch (wanted_sfcdeclaration) { case sfcdecl_sd: for(int i = 0; i < symbol->n; i++) - symbol->elements[i]->accept(*this); + symbol->get_element(i)->accept(*this); /* steps table declaration */ s4o.print(s4o.indent_spaces + "STEP __step_list["); @@ -120,7 +120,7 @@ /* steps table count */ wanted_sfcdeclaration = stepcount_sd; for(int i = 0; i < symbol->n; i++) - symbol->elements[i]->accept(*this); + symbol->get_element(i)->accept(*this); s4o.print(s4o.indent_spaces); print_variable_prefix(); s4o.print("__nb_steps = "); @@ -141,12 +141,12 @@ s4o.indent_left(); s4o.print(s4o.indent_spaces + "}\n"); for(int i = 0; i < symbol->n; i++) - symbol->elements[i]->accept(*this); + symbol->get_element(i)->accept(*this); /* actions table count */ wanted_sfcdeclaration = actioncount_sd; for(int i = 0; i < symbol->n; i++) - symbol->elements[i]->accept(*this); + symbol->get_element(i)->accept(*this); s4o.print(s4o.indent_spaces); print_variable_prefix(); s4o.print("__nb_actions = "); @@ -170,7 +170,7 @@ /* transitions table count */ wanted_sfcdeclaration = transitioncount_sd; for(int i = 0; i < symbol->n; i++) - symbol->elements[i]->accept(*this); + symbol->get_element(i)->accept(*this); s4o.print(s4o.indent_spaces); print_variable_prefix(); s4o.print("__nb_transitions = "); @@ -187,7 +187,7 @@ case stepdef_sd: s4o.print("// Steps definitions\n"); for(int i = 0; i < symbol->n; i++) - symbol->elements[i]->accept(*this); + symbol->get_element(i)->accept(*this); s4o.print("\n"); break; case actiondef_sd: @@ -196,12 +196,12 @@ // first fill up the this->variable_list variable! wanted_sfcdeclaration = actioncount_sd; for(int i = 0; i < symbol->n; i++) - symbol->elements[i]->accept(*this); + symbol->get_element(i)->accept(*this); action_number = 0; // reset the counter! wanted_sfcdeclaration = actiondef_sd; // Now do the defines for actions! for(int i = 0; i < symbol->n; i++) - symbol->elements[i]->accept(*this); + symbol->get_element(i)->accept(*this); // Now do the defines for actions that reference a variable instead of an action block! std::list::iterator pt; for(pt = variable_list.begin(); pt != variable_list.end(); pt++) { @@ -219,18 +219,18 @@ case stepundef_sd: s4o.print("// Steps undefinitions\n"); for(int i = 0; i < symbol->n; i++) - symbol->elements[i]->accept(*this); + symbol->get_element(i)->accept(*this); s4o.print("\n"); break; case actionundef_sd: s4o.print("// Actions undefinitions\n"); for(int i = 0; i < symbol->n; i++) - symbol->elements[i]->accept(*this); + symbol->get_element(i)->accept(*this); { // first fill up the this->variable_list variable! wanted_sfcdeclaration = actioncount_sd; for(int i = 0; i < symbol->n; i++) - symbol->elements[i]->accept(*this); + symbol->get_element(i)->accept(*this); wanted_sfcdeclaration = actionundef_sd; std::list::iterator pt; for(pt = variable_list.begin(); pt != variable_list.end(); pt++) { diff -r 52f63e622604 -r 4d7183013481 stage4/generate_c/generate_c_st.cc --- a/stage4/generate_c/generate_c_st.cc Wed Apr 12 08:44:42 2017 +0100 +++ b/stage4/generate_c/generate_c_st.cc Sun Apr 16 08:46:58 2017 +0100 @@ -422,7 +422,7 @@ if (dimension == NULL) ERROR; s4o.print("[("); - symbol->elements[i]->accept(*this); + symbol->get_element(i)->accept(*this); s4o.print(") - ("); dimension->accept(*this); s4o.print(")]"); @@ -925,9 +925,9 @@ /********************/ void *visit(statement_list_c *symbol) { for(int i = 0; i < symbol->n; i++) { - print_line_directive(symbol->elements[i]); + print_line_directive(symbol->get_element(i)); s4o.print(s4o.indent_spaces); - symbol->elements[i]->accept(*this); + symbol->get_element(i)->accept(*this); s4o.print(";\n"); } return NULL; @@ -1213,10 +1213,10 @@ */ if (0 != i) s4o.print(" ||\n" + s4o.indent_spaces + " "); s4o.print("("); - subrange_c *subrange = dynamic_cast(symbol->elements[i]); + subrange_c *subrange = dynamic_cast(symbol->get_element(i)); if (NULL == subrange) { s4o.print("__case_expression == "); - symbol->elements[i]->accept(*this); + symbol->get_element(i)->accept(*this); } else { s4o.print("__case_expression >= "); subrange->lower_limit->accept(*this); diff -r 52f63e622604 -r 4d7183013481 stage4/generate_c/generate_c_typedecl.cc --- a/stage4/generate_c/generate_c_typedecl.cc Wed Apr 12 08:44:42 2017 +0100 +++ b/stage4/generate_c/generate_c_typedecl.cc Sun Apr 16 08:46:58 2017 +0100 @@ -178,7 +178,7 @@ /* helper symbol for array_specification */ /* array_subrange_list ',' subrange */ void *visit(array_subrange_list_c *symbol) { - for(int i = 0; i < symbol->n; i++) {symbol->elements[i]->accept(*this);} + for(int i = 0; i < symbol->n; i++) {symbol->get_element(i)->accept(*this);} return NULL; } @@ -295,12 +295,12 @@ if (list->n > 0) { s4o_incl.print(pre_elem_str); - list->elements[0]->accept(*this); + list->get_element(0)->accept(*this); } for(int i = 1; i < list->n; i++) { s4o_incl.print(inter_elem_str); - list->elements[i]->accept(*this); + list->get_element(i)->accept(*this); } if (list->n > 0) diff -r 52f63e622604 -r 4d7183013481 stage4/generate_c/generate_c_vardecl.cc --- a/stage4/generate_c/generate_c_vardecl.cc Wed Apr 12 08:44:42 2017 +0100 +++ b/stage4/generate_c/generate_c_vardecl.cc Sun Apr 16 08:46:58 2017 +0100 @@ -168,7 +168,7 @@ s4o.print("("); print_variable_prefix(); s4o.print(","); - symbol->elements[i]->accept(*this); + symbol->get_element(i)->accept(*this); s4o.print(",,temp);\n"); } return NULL; @@ -249,14 +249,14 @@ ERROR; if (defined_values_count > 0) s4o.print(","); - symbol->elements[i]->accept(*this); + symbol->get_element(i)->accept(*this); defined_values_count++; } else { - array_initial_elements_c *array_initial_element = dynamic_cast(symbol->elements[i]); + array_initial_elements_c *array_initial_element = dynamic_cast(symbol->get_element(i)); if (array_initial_element != NULL) { - symbol->elements[i]->accept(*this); + symbol->get_element(i)->accept(*this); } } current_initialization_count++; @@ -414,7 +414,7 @@ void *visit(structure_element_declaration_list_c *symbol) { void *res; for (int i = 0; i < symbol->n; i++) { - res = symbol->elements[i]->accept(*this); + res = symbol->get_element(i)->accept(*this); if (res != NULL) return res; } @@ -472,7 +472,7 @@ void *visit(structure_element_initialization_list_c *symbol) { void *res; for (int i = 0; i < symbol->n; i++) { - res = symbol->elements[i]->accept(*this); + res = symbol->get_element(i)->accept(*this); if (res != NULL) return res; } @@ -599,7 +599,7 @@ s4o.print("("); print_variable_prefix(); s4o.print(","); - symbol->elements[i]->accept(*this); + symbol->get_element(i)->accept(*this); s4o.print(",,temp);\n"); } return NULL; @@ -974,8 +974,13 @@ if (NULL == init_list) ERROR; for (int i = 0; i < init_list->n; i++) { - structure_element_initialization_c *init_list_elem = dynamic_cast(init_list->elements[i]); + structure_element_initialization_c *init_list_elem = dynamic_cast(init_list->get_element(i)); if (NULL == init_list_elem) ERROR; + if (!get_datatype_info_c::is_ANY_ELEMENTARY(init_list_elem->value->datatype)) { + STAGE4_ERROR(init_list_elem, init_list_elem, + "C code generation does not yet support initializing FB/structures with non-elementary values."); + ERROR; + } s4o.print("\n"); s4o.print(s4o.indent_spaces); s4o.print(INIT_VAR); @@ -1030,20 +1035,20 @@ print_variable_prefix(); s4o.print(","); } - list->elements[i]->accept(*this); + list->get_element(i)->accept(*this); if (wanted_varformat != local_vf) { if (wanted_varformat == localinit_vf && (current_vartype & inoutput_vt) != 0) { s4o.print(";\n"); s4o.print(s4o.indent_spaces); s4o.print("if (__"); - list->elements[i]->accept(*this); + list->get_element(i)->accept(*this); s4o.print(" != NULL) {\n"); s4o.indent_right(); s4o.print(s4o.indent_spaces); - list->elements[i]->accept(*this); + list->get_element(i)->accept(*this); s4o.print(" = *__"); - list->elements[i]->accept(*this); + list->get_element(i)->accept(*this); s4o.print(";\n"); s4o.indent_left(); s4o.print(s4o.indent_spaces); @@ -1058,7 +1063,7 @@ this->current_var_init_symbol->accept(*this); s4o.print(";\n"); s4o.print(s4o.indent_spaces); - list->elements[i]->accept(*this); + list->get_element(i)->accept(*this); s4o.print(" = temp;\n"); s4o.indent_left(); s4o.print(s4o.indent_spaces); @@ -1094,7 +1099,7 @@ s4o.print(" *__"); else s4o.print(" "); - list->elements[i]->accept(*this); + list->get_element(i)->accept(*this); /* We do not print the initial value at function declaration! * It is up to the caller to pass the correct default value * if none is specified in the ST source code @@ -1109,13 +1114,13 @@ for(int i = 0; i < list->n; i++) { if ((current_vartype & (output_vt | inoutput_vt)) != 0) { s4o.print(s4o.indent_spaces + "if (__"); - list->elements[i]->accept(*this); + list->get_element(i)->accept(*this); s4o.print(" != NULL) {\n"); s4o.indent_right(); s4o.print(s4o.indent_spaces + "*__"); - list->elements[i]->accept(*this); + list->get_element(i)->accept(*this); s4o.print(" = "); - list->elements[i]->accept(*this); + list->get_element(i)->accept(*this); s4o.print(";\n"); s4o.indent_left(); s4o.print(s4o.indent_spaces + "}\n"); @@ -1139,7 +1144,7 @@ s4o.print(FB_INIT_SUFFIX); s4o.print("(&"); this->print_variable_prefix(); - list->elements[i]->accept(*this); + list->get_element(i)->accept(*this); print_retain(); s4o.print(");"); if (this->current_var_init_symbol != NULL) { @@ -1152,7 +1157,7 @@ * __INIT_VAR(data__->my_fb.var1, __INT_LITERAL(42), retain); * __INIT_VAR(data__->my_fb.var1, __STRING_LITERAL("hello"), retain); */ - print_fb_explicit_initial_values(list->elements[i], this->current_var_init_symbol); + print_fb_explicit_initial_values(list->get_element(i), this->current_var_init_symbol); } } else if (this->current_var_init_symbol != NULL) { @@ -1160,7 +1165,7 @@ s4o.print(INIT_VAR); s4o.print("("); this->print_variable_prefix(); - list->elements[i]->accept(*this); + list->get_element(i)->accept(*this); s4o.print(","); this->current_var_init_symbol->accept(*this); print_retain(); @@ -2157,7 +2162,7 @@ if(this->resource_name != NULL) this->resource_name->accept(*this); s4o.print(","); - list->elements[i]->accept(*this); + list->get_element(i)->accept(*this); s4o.print(")\n"); } break; @@ -2174,7 +2179,7 @@ s4o.print("("); this->current_var_type_symbol->accept(*this); s4o.print(","); - list->elements[i]->accept(*this); + list->get_element(i)->accept(*this); if (this->current_var_init_symbol != NULL) { s4o.print(","); s4o.print(INITIAL_VALUE); @@ -2196,7 +2201,7 @@ this->globalnamespace->accept(*this); s4o.print("::"); } - list->elements[i]->accept(*this); + list->get_element(i)->accept(*this); if (this->current_var_init_symbol != NULL) { s4o.print(" = "); @@ -2219,7 +2224,7 @@ s4o.print("("); this->current_var_type_symbol->accept(*this); s4o.print(","); - list->elements[i]->accept(*this); + list->get_element(i)->accept(*this); s4o.print(")\n"); } break; diff -r 52f63e622604 -r 4d7183013481 stage4/generate_c/generate_var_list.cc --- a/stage4/generate_c/generate_var_list.cc Wed Apr 12 08:44:42 2017 +0100 +++ b/stage4/generate_c/generate_var_list.cc Sun Apr 16 08:46:58 2017 +0100 @@ -289,7 +289,7 @@ if (list == NULL) ERROR; for(int i = 0; i < list->n; i++) { - declare_variable(list->elements[i]); + declare_variable(list->get_element(i)); } } @@ -793,7 +793,7 @@ void *visit(structure_element_declaration_list_c *symbol) { for(int i = 0; i < symbol->n; i++) { - symbol->elements[i]->accept(*this); + symbol->get_element(i)->accept(*this); } return NULL; } @@ -860,7 +860,7 @@ transition_number = 0; action_number = 0; for(int i = 0; i < symbol->n; i++) { - symbol->elements[i]->accept(*this); + symbol->get_element(i)->accept(*this); } return NULL; } @@ -937,7 +937,7 @@ //SYM_LIST(step_name_list_c) void *visit(step_name_list_c *symbol) { for(int i = 0; i < symbol->n; i++) { - symbol->elements[i]->accept(*this); + symbol->get_element(i)->accept(*this); if (i < symbol->n - 1) s4o.print(","); } diff -r 52f63e622604 -r 4d7183013481 stage4/generate_iec/generate_iec.cc --- a/stage4/generate_iec/generate_iec.cc Wed Apr 12 08:44:42 2017 +0100 +++ b/stage4/generate_iec/generate_iec.cc Sun Apr 16 08:46:58 2017 +0100 @@ -164,12 +164,12 @@ std::string post_elem_str = "") { if (list->n > 0) { s4o.print(pre_elem_str); - list->elements[0]->accept(*this); + list->get_element(0)->accept(*this); } for(int i = 1; i < list->n; i++) { s4o.print(inter_elem_str); - list->elements[i]->accept(*this); + list->get_element(i)->accept(*this); } if (list->n > 0)