# HG changeset patch # User laurent # Date 1318329049 -7200 # Node ID ac6dfec701c9100a7bbc12203ba5019d6ca5acb6 # Parent 2fd934b91ffd0968f04a4529db602319b0cc70d0 Fix bug in parser while trying to use IL operator like S1, R1, etc... as standard function block interface variable in structured_variable syntax and bug in code generator while generating code for assignment of function block interface variable using structured_variable syntax diff -r 2fd934b91ffd -r ac6dfec701c9 absyntax_utils/decompose_var_instance_name.cc --- a/absyntax_utils/decompose_var_instance_name.cc Sun Oct 09 20:18:55 2011 +0200 +++ b/absyntax_utils/decompose_var_instance_name.cc Tue Oct 11 12:30:49 2011 +0200 @@ -128,17 +128,38 @@ /* The correct code, is therefore more complex... */ if (next_variable_name == symbol) { - /* NOTE: field_selector is always an identifier_c, - * so we do not have to recursevily visit it again... - * return (void *)symbol->field_selector->accept(*this); -> NOT REQUIRED!! - */ - return (void *)symbol->field_selector; + return (void *)symbol->field_selector->accept(*this); } current_recursive_variable_name = symbol; return symbol->record_variable->accept(*this); } +/********************************/ +/* B 2.2 - Operators */ +/********************************/ +void *decompose_var_instance_name_c::visit(LD_operator_c *symbol) {return (void *)&LD_operator_name;} +void *decompose_var_instance_name_c::visit(S_operator_c *symbol) {return (void *)&S_operator_name;} +void *decompose_var_instance_name_c::visit(R_operator_c *symbol) {return (void *)&R_operator_name;} +void *decompose_var_instance_name_c::visit(S1_operator_c *symbol) {return (void *)&S1_operator_name;} +void *decompose_var_instance_name_c::visit(R1_operator_c *symbol) {return (void *)&R1_operator_name;} +void *decompose_var_instance_name_c::visit(CLK_operator_c *symbol) {return (void *)&CLK_operator_name;} +void *decompose_var_instance_name_c::visit(CU_operator_c *symbol) {return (void *)&CU_operator_name;} +void *decompose_var_instance_name_c::visit(CD_operator_c *symbol) {return (void *)&CD_operator_name;} +void *decompose_var_instance_name_c::visit(PV_operator_c *symbol) {return (void *)&PV_operator_name;} +void *decompose_var_instance_name_c::visit(IN_operator_c *symbol) {return (void *)&IN_operator_name;} +void *decompose_var_instance_name_c::visit(PT_operator_c *symbol) {return (void *)&PT_operator_name;} + +identifier_c decompose_var_instance_name_c::LD_operator_name("LD"); +identifier_c decompose_var_instance_name_c::S_operator_name("S"); +identifier_c decompose_var_instance_name_c::R_operator_name("R"); +identifier_c decompose_var_instance_name_c::S1_operator_name("S1"); +identifier_c decompose_var_instance_name_c::R1_operator_name("R1"); +identifier_c decompose_var_instance_name_c::CLK_operator_name("CLK"); +identifier_c decompose_var_instance_name_c::CU_operator_name("CU"); +identifier_c decompose_var_instance_name_c::CD_operator_name("CD"); +identifier_c decompose_var_instance_name_c::PV_operator_name("PV"); +identifier_c decompose_var_instance_name_c::IN_operator_name("IN"); +identifier_c decompose_var_instance_name_c::PT_operator_name("PT"); - diff -r 2fd934b91ffd -r ac6dfec701c9 absyntax_utils/decompose_var_instance_name.hh --- a/absyntax_utils/decompose_var_instance_name.hh Sun Oct 09 20:18:55 2011 +0200 +++ b/absyntax_utils/decompose_var_instance_name.hh Tue Oct 11 12:30:49 2011 +0200 @@ -52,6 +52,23 @@ class decompose_var_instance_name_c: null_visitor_c { + public: + /***********************************/ + /* B 1.2 - Operators */ + /***********************************/ + static identifier_c LD_operator_name; + static identifier_c S_operator_name; + static identifier_c R_operator_name; + static identifier_c S1_operator_name; + static identifier_c R1_operator_name; + static identifier_c CLK_operator_name; + static identifier_c CU_operator_name; + static identifier_c CD_operator_name; + static identifier_c PV_operator_name; + static identifier_c IN_operator_name; + static identifier_c PT_operator_name; + + private: symbol_c *variable_name; symbol_c *next_variable_name; @@ -98,6 +115,21 @@ //SYM_REF2(structured_variable_c, record_variable, field_selector) void *visit(structured_variable_c *symbol); + /********************************/ + /* B 2.2 - Operators */ + /********************************/ + void *visit(LD_operator_c *symbol); + void *visit(S_operator_c *symbol); + void *visit(R_operator_c *symbol); + void *visit(S1_operator_c *symbol); + void *visit(R1_operator_c *symbol); + void *visit(CLK_operator_c *symbol); + void *visit(CU_operator_c *symbol); + void *visit(CD_operator_c *symbol); + void *visit(PV_operator_c *symbol); + void *visit(IN_operator_c *symbol); + void *visit(PT_operator_c *symbol); + }; // decompose_var_instance_name_c diff -r 2fd934b91ffd -r ac6dfec701c9 absyntax_utils/search_varfb_instance_type.cc --- a/absyntax_utils/search_varfb_instance_type.cc Sun Oct 09 20:18:55 2011 +0200 +++ b/absyntax_utils/search_varfb_instance_type.cc Tue Oct 11 12:30:49 2011 +0200 @@ -309,7 +309,72 @@ this->is_complex = true; if (NULL != current_structelement_name) ERROR; - /* make sure that we have decomposed all strcuture elements of the variable name */ + /* make sure that we have decomposed all structure elements of the variable name */ + symbol_c *var_name = decompose_var_instance_name->next_part(); + if (NULL == var_name) { + /* this is it... ! + * No need to look any further... + * Note also that, unlike for the struct types, a function block may + * not be defined based on another (i.e. no inheritance is allowed), + * so this function block is already the most base type. + * We simply return it. + */ + return (void *)symbol; + } + + /* reset current_type_id because of new structure element part */ + this->current_typeid = NULL; + + /* look for the var_name in the structure declaration */ + current_structelement_name = var_name; + + /* recursively find out the data type of current_structelement_name... */ + 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_varfb_instance_type_c::visit(structure_element_declaration_list_c *symbol) { + if (NULL == current_structelement_name) ERROR; + /* now search the structure declaration */ + return visit_list(symbol); +} + +/* structure_element_name ':' spec_init */ +void *search_varfb_instance_type_c::visit(structure_element_declaration_c *symbol) { + if (NULL == current_structelement_name) ERROR; + + if (compare_identifiers(symbol->structure_element_name, current_structelement_name) == 0) { + current_structelement_name = NULL; + /* found the type of the element we were looking for! */ + return symbol->spec_init->accept(*this); + } + + /* Did not find the type of the element we were looking for! */ + /* Will keep looking... */ + return NULL; +} + +/* helper symbol for structure_initialization */ +/* structure_initialization: '(' structure_element_initialization_list ')' */ +/* structure_element_initialization_list ',' structure_element_initialization */ +void *search_varfb_instance_type_c::visit(structure_element_initialization_list_c *symbol) {ERROR; return NULL;} /* should never get called... */ +/* structure_element_name ASSIGN value */ +void *search_varfb_instance_type_c::visit(structure_element_initialization_c *symbol) {ERROR; return NULL;} /* should never get called... */ + + + +/**************************************/ +/* B.1.5 - Program organization units */ +/**************************************/ +/*****************************/ +/* B 1.5.2 - Function Blocks */ +/*****************************/ +/* FUNCTION_BLOCK derived_function_block_name io_OR_other_var_declarations function_block_body END_FUNCTION_BLOCK */ +// SYM_REF4(function_block_declaration_c, fblock_name, var_declarations, fblock_body, unused) +void *search_varfb_instance_type_c::visit(function_block_declaration_c *symbol) { + /* make sure that we have decomposed all structure elements of the variable name */ symbol_c *var_name = decompose_var_instance_name->next_part(); if (NULL == var_name) { /* this is it... ! @@ -322,67 +387,8 @@ return (void *)symbol; } - /* look for the var_name in the structure declaration */ - current_structelement_name = var_name; - - /* recursively find out the data type of current_structelement_name... */ - 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_varfb_instance_type_c::visit(structure_element_declaration_list_c *symbol) { - if (NULL == current_structelement_name) ERROR; - /* now search the structure declaration */ - return visit_list(symbol); -} - -/* structure_element_name ':' spec_init */ -void *search_varfb_instance_type_c::visit(structure_element_declaration_c *symbol) { - if (NULL == current_structelement_name) ERROR; - - if (compare_identifiers(symbol->structure_element_name, current_structelement_name) == 0) { - current_structelement_name = NULL; - /* found the type of the element we were looking for! */ - return symbol->spec_init->accept(*this); - } - - /* Did not find the type of the element we were looking for! */ - /* Will keep looking... */ - return NULL; -} - -/* helper symbol for structure_initialization */ -/* structure_initialization: '(' structure_element_initialization_list ')' */ -/* structure_element_initialization_list ',' structure_element_initialization */ -void *search_varfb_instance_type_c::visit(structure_element_initialization_list_c *symbol) {ERROR; return NULL;} /* should never get called... */ -/* structure_element_name ASSIGN value */ -void *search_varfb_instance_type_c::visit(structure_element_initialization_c *symbol) {ERROR; return NULL;} /* should never get called... */ - - - -/**************************************/ -/* B.1.5 - Program organization units */ -/**************************************/ -/*****************************/ -/* B 1.5.2 - Function Blocks */ -/*****************************/ -/* FUNCTION_BLOCK derived_function_block_name io_OR_other_var_declarations function_block_body END_FUNCTION_BLOCK */ -// SYM_REF4(function_block_declaration_c, fblock_name, var_declarations, fblock_body, unused) -void *search_varfb_instance_type_c::visit(function_block_declaration_c *symbol) { - /* make sure that we have decomposed all strcuture elements of the variable name */ - symbol_c *var_name = decompose_var_instance_name->next_part(); - if (NULL == var_name) { - /* this is it... ! - * No need to look any further... - * Note also that, unlike for the struct types, a function block may - * not be defined based on another (i.e. no inheritance is allowed), - * so this function block is already the most base type. - * We simply return it. - */ - return (void *)symbol; - } + /* reset current_type_id because of new structure element part */ + this->current_typeid = NULL; /* now search the function block declaration for the variable... */ search_var_instance_decl_c search_decl(symbol); @@ -404,7 +410,7 @@ current_structelement_name = var_name; /* recursively find out the data type of var_name... */ return symbol->var_declarations->accept(*this); -#endif +#endif /* carry on recursively, in case the variable has more elements to be decomposed... */ return var_decl->accept(*this); } diff -r 2fd934b91ffd -r ac6dfec701c9 stage1_2/iec_bison.yy --- a/stage1_2/iec_bison.yy Sun Oct 09 20:18:55 2011 +0200 +++ b/stage1_2/iec_bison.yy Tue Oct 11 12:30:49 2011 +0200 @@ -1220,6 +1220,7 @@ %type il_simple_operator_clash %type il_simple_operator_clash1 %type il_simple_operator_clash2 +%type il_simple_operator_clash3 %type il_simple_operator_noclash //%type il_expr_operator @@ -3405,6 +3406,8 @@ structured_variable: record_variable '.' field_selector {$$ = new structured_variable_c($1, $3, locloc(@$));} +| record_variable '.' il_simple_operator_clash3 + {$$ = new structured_variable_c($1, $3, locloc(@$));} ; @@ -3412,6 +3415,8 @@ any_structured_variable: any_record_variable '.' field_selector {$$ = new structured_variable_c($1, $3, locloc(@$));} +| any_record_variable '.' il_simple_operator_clash3 + {$$ = new structured_variable_c($1, $3, locloc(@$));} ; @@ -6825,10 +6830,29 @@ il_simple_operator_noclash: - LD_operator -| LDN_operator + LDN_operator | ST_operator | STN_operator +| il_expr_operator_noclash +; + + +il_simple_operator_clash: + il_simple_operator_clash1 +| il_simple_operator_clash2 +| il_simple_operator_clash3 +; + +il_simple_operator_clash1: + NOT_operator +; + +il_simple_operator_clash2: + il_expr_operator_clash +; + +il_simple_operator_clash3: + LD_operator | S_operator | R_operator | S1_operator @@ -6839,23 +6863,7 @@ | PV_operator | IN_operator | PT_operator -| il_expr_operator_noclash -; - - -il_simple_operator_clash: - il_simple_operator_clash1 -| il_simple_operator_clash2 -; - -il_simple_operator_clash1: - NOT_operator -; - -il_simple_operator_clash2: - il_expr_operator_clash -; - +; /* il_expr_operator: diff -r 2fd934b91ffd -r ac6dfec701c9 stage4/generate_c/generate_c_il.cc --- a/stage4/generate_c/generate_c_il.cc Sun Oct 09 20:18:55 2011 +0200 +++ b/stage4/generate_c/generate_c_il.cc Tue Oct 11 12:30:49 2011 +0200 @@ -324,6 +324,11 @@ /* A helper function... */ void *XXX_CAL_operator(const char *param_name, symbol_c *fb_name) { + if (wanted_variablegeneration != expression_vg) { + s4o.print(param_name); + return NULL; + } + if (NULL == fb_name) ERROR; symbolic_variable_c *sv = dynamic_cast(fb_name); if (NULL == sv) ERROR; @@ -462,6 +467,7 @@ symbol_c* fb_value = NULL, bool negative = false) { unsigned int vartype = search_varfb_instance_type->get_vartype(symbol); + bool type_is_complex = search_varfb_instance_type->type_is_complex(); if (vartype == search_var_instance_decl_c::external_vt) { symbolic_variable_c *variable = dynamic_cast(symbol); /* TODO Find a solution for forcing global complex variables */ @@ -489,8 +495,11 @@ fb_symbol->accept(*this); s4o.print("."); } + else if (type_is_complex) + wanted_variablegeneration = complextype_base_vg; else - wanted_variablegeneration = complextype_base_vg; + wanted_variablegeneration = assignment_vg; + symbol->accept(*this); s4o.print(","); if (negative) { @@ -501,7 +510,7 @@ } wanted_variablegeneration = expression_vg; print_check_function(type, value, fb_value); - if (search_varfb_instance_type->type_is_complex()) { + if (type_is_complex) { s4o.print(","); wanted_variablegeneration = complextype_suffix_vg; symbol->accept(*this); @@ -552,6 +561,12 @@ /* B 1.3.3 - Derived data types */ /********************************/ +/* signed_integer DOTDOT signed_integer */ +void *visit(subrange_c *symbol) { + symbol->lower_limit->accept(*this); + return NULL; +} + /* ARRAY '[' array_subrange_list ']' OF non_generic_type_name */ void *visit(array_specification_c *symbol) { symbol->non_generic_type_name->accept(*this); @@ -564,23 +579,29 @@ void *visit(symbolic_variable_c *symbol) { unsigned int vartype; - if (wanted_variablegeneration == complextype_base_vg) - generate_c_base_c::visit(symbol); - else if (wanted_variablegeneration == complextype_suffix_vg) - return NULL; - else if (this->is_variable_prefix_null()) { - vartype = search_varfb_instance_type->get_vartype(symbol); - if (wanted_variablegeneration == fparam_output_vg) { - s4o.print("&("); + switch (wanted_variablegeneration) { + case complextype_base_vg: + case assignment_vg: generate_c_base_c::visit(symbol); - s4o.print(")"); - } - else { - generate_c_base_c::visit(symbol); - } - } - else - print_getter(symbol); + break; + case complextype_suffix_vg: + break; + default: + if (this->is_variable_prefix_null()) { + vartype = search_varfb_instance_type->get_vartype(symbol); + if (wanted_variablegeneration == fparam_output_vg) { + s4o.print("&("); + generate_c_base_c::visit(symbol); + s4o.print(")"); + } + else { + generate_c_base_c::visit(symbol); + } + } + else + print_getter(symbol); + break; + } return NULL; } @@ -630,6 +651,7 @@ symbol->record_variable->accept(*this); break; case complextype_suffix_vg: + case assignment_vg: symbol->record_variable->accept(*this); s4o.print("."); symbol->field_selector->accept(*this); @@ -1554,6 +1576,11 @@ /*******************/ void *visit(LD_operator_c *symbol) { + if (wanted_variablegeneration != expression_vg) { + s4o.print("LD"); + return NULL; + } + /* the data type resulting from this operation... */ this->default_variable_name.current_type = this->current_operand_type; XXX_operator(&(this->default_variable_name), " = ", this->current_operand); @@ -1617,6 +1644,11 @@ } void *visit(S_operator_c *symbol) { + if (wanted_variablegeneration != expression_vg) { + s4o.print("LD"); + return NULL; + } + if ((NULL == this->current_operand) || (NULL == this->current_operand_type)) ERROR; C_modifier(); @@ -1635,6 +1667,11 @@ } void *visit(R_operator_c *symbol) { + if (wanted_variablegeneration != expression_vg) { + s4o.print("LD"); + return NULL; + } + if ((NULL == this->current_operand) || (NULL == this->current_operand_type)) ERROR; C_modifier(); diff -r 2fd934b91ffd -r ac6dfec701c9 stage4/generate_c/generate_c_st.cc --- a/stage4/generate_c/generate_c_st.cc Sun Oct 09 20:18:55 2011 +0200 +++ b/stage4/generate_c/generate_c_st.cc Tue Oct 11 12:30:49 2011 +0200 @@ -170,6 +170,7 @@ symbol_c* fb_value = NULL) { unsigned int vartype = search_varfb_instance_type->get_vartype(symbol); + bool type_is_complex = search_varfb_instance_type->type_is_complex(); if (vartype == search_var_instance_decl_c::external_vt) { symbolic_variable_c *variable = dynamic_cast(symbol); /* TODO Find a solution for forcing global complex variables */ @@ -197,20 +198,16 @@ fb_symbol->accept(*this); s4o.print("."); } + else if (type_is_complex) + wanted_variablegeneration = complextype_base_vg; else - wanted_variablegeneration = complextype_base_vg; + wanted_variablegeneration = assignment_vg; symbol->accept(*this); s4o.print(","); wanted_variablegeneration = expression_vg; print_check_function(type, value, fb_value); - /* We need to call search_varfb_instance_type->get_vartype() again, as it may have been called - * again since we called it in the beginning of this print_setter() function. - * This make sure the call to search_varfb_instance_type->type_is_complex() will return - * the correct value regarding our 'symbol'. - */ - search_varfb_instance_type->get_vartype(symbol); - if (search_varfb_instance_type->type_is_complex()) { + if (type_is_complex) { s4o.print(","); wanted_variablegeneration = complextype_suffix_vg; symbol->accept(*this); @@ -251,23 +248,29 @@ /*********************/ void *visit(symbolic_variable_c *symbol) { unsigned int vartype; - if (wanted_variablegeneration == complextype_base_vg) - generate_c_base_c::visit(symbol); - else if (wanted_variablegeneration == complextype_suffix_vg) - return NULL; - else if (this->is_variable_prefix_null()) { - vartype = search_varfb_instance_type->get_vartype(symbol); - if (wanted_variablegeneration == fparam_output_vg) { - s4o.print("&("); - generate_c_base_c::visit(symbol); - s4o.print(")"); - } - else { - generate_c_base_c::visit(symbol); - } - } - else - print_getter(symbol); + switch (wanted_variablegeneration) { + case complextype_base_vg: + case assignment_vg: + generate_c_base_c::visit(symbol); + break; + case complextype_suffix_vg: + break; + default: + if (this->is_variable_prefix_null()) { + vartype = search_varfb_instance_type->get_vartype(symbol); + if (wanted_variablegeneration == fparam_output_vg) { + s4o.print("&("); + generate_c_base_c::visit(symbol); + s4o.print(")"); + } + else { + generate_c_base_c::visit(symbol); + } + } + else + print_getter(symbol); + break; + } return NULL; } @@ -317,6 +320,7 @@ symbol->record_variable->accept(*this); break; case complextype_suffix_vg: + case assignment_vg: symbol->record_variable->accept(*this); s4o.print("."); symbol->field_selector->accept(*this);