660 |
660 |
661 |
661 |
662 |
662 |
663 /* handle the two equality comparison operations, i.e. = (euqal) and != (not equal) */ |
663 /* handle the two equality comparison operations, i.e. = (euqal) and != (not equal) */ |
664 /* This function is special, as it will also allow enumeration data types to be compared, with the result being a BOOL data type! |
664 /* This function is special, as it will also allow enumeration data types to be compared, with the result being a BOOL data type! |
665 * This possibility os not expressed in the 'widening' tables, so we need to hard code it here |
665 * It will also allow to REF_TO datatypes to be compared. |
|
666 * These possibilities are not expressed in the 'widening' tables, so we need to hard code it here |
666 */ |
667 */ |
667 void *fill_candidate_datatypes_c::handle_equality_comparison(const struct widen_entry widen_table[], symbol_c *symbol, symbol_c *l_expr, symbol_c *r_expr) { |
668 void *fill_candidate_datatypes_c::handle_equality_comparison(const struct widen_entry widen_table[], symbol_c *symbol, symbol_c *l_expr, symbol_c *r_expr) { |
668 handle_binary_expression(widen_table, symbol, l_expr, r_expr); |
669 handle_binary_expression(widen_table, symbol, l_expr, r_expr); |
669 for(unsigned int i = 0; i < l_expr->candidate_datatypes.size(); i++) |
670 for(unsigned int i = 0; i < l_expr->candidate_datatypes.size(); i++) |
670 for(unsigned int j = 0; j < r_expr->candidate_datatypes.size(); j++) { |
671 for(unsigned int j = 0; j < r_expr->candidate_datatypes.size(); j++) { |
671 if ((l_expr->candidate_datatypes[i] == r_expr->candidate_datatypes[j]) && get_datatype_info_c::is_enumerated(l_expr->candidate_datatypes[i])) |
672 if ( (get_datatype_info_c::is_enumerated(l_expr->candidate_datatypes[i]) && (l_expr->candidate_datatypes[i] == r_expr->candidate_datatypes[j])) |
|
673 || (get_datatype_info_c::is_ref_to (l_expr->candidate_datatypes[i]) && get_datatype_info_c::is_type_equal(l_expr->candidate_datatypes[i], r_expr->candidate_datatypes[j]))) |
672 add_datatype_to_candidate_list(symbol, &get_datatype_info_c::bool_type_name); |
674 add_datatype_to_candidate_list(symbol, &get_datatype_info_c::bool_type_name); |
673 } |
675 } |
674 return NULL; |
676 return NULL; |
675 } |
677 } |
676 |
678 |
687 /***************************/ |
689 /***************************/ |
688 /* B 0 - Programming Model */ |
690 /* B 0 - Programming Model */ |
689 /***************************/ |
691 /***************************/ |
690 /* main entry function! */ |
692 /* main entry function! */ |
691 void *fill_candidate_datatypes_c::visit(library_c *symbol) { |
693 void *fill_candidate_datatypes_c::visit(library_c *symbol) { |
692 symbol->accept(populate_globalenumvalue_symtable); |
694 symbol->accept(populate_globalenumvalue_symtable); |
693 /* Now let the base class iterator_visitor_c iterate through all the library elements */ |
695 /* Now let the base class iterator_visitor_c iterate through all the library elements */ |
694 return iterator_visitor_c::visit(symbol); |
696 return iterator_visitor_c::visit(symbol); |
695 } |
697 } |
696 |
698 |
697 |
699 |
698 /*********************/ |
700 /*********************/ |
699 /* B 1.2 - Constants */ |
701 /* B 1.2 - Constants */ |
700 /*********************/ |
702 /*********************/ |
|
703 /*********************************/ |
|
704 /* B 1.2.XX - Reference Literals */ |
|
705 /*********************************/ |
|
706 /* defined in IEC 61131-3 v3 - Basically the 'NULL' keyword! */ |
|
707 void *fill_candidate_datatypes_c::visit(ref_value_null_literal_c *symbol) { |
|
708 /* 'NULL' does not have any specific datatype. It is compatible with any reference, i.e. REF_TO <anything> |
|
709 * The fill_candidate_datatypes / narrow_candidate_datatypes algorithm would require us to add |
|
710 * as possible datatypes all the REF_TO <datatype>. To do this we would need to go through the list of all |
|
711 * user declared datatypes, as well as all the elementary datatypes. This is easily done by using the |
|
712 * type_symtable symbol table declared in absyntax_utils.hh. |
|
713 * |
|
714 * for(int i=0; i<type_symtable.n; i++) add_datatype_to_candidate_list(symbol, new ref_spec_c(type_symtable[i])); |
|
715 * add_datatype_to_candidate_list(symbol, new ref_spec_c( ... SINT ...)); |
|
716 * add_datatype_to_candidate_list(symbol, new ref_spec_c( ... INT ...)); |
|
717 * add_datatype_to_candidate_list(symbol, new ref_spec_c( ... LINT ...)); |
|
718 * ... |
|
719 * |
|
720 * However, doing this for all NULL constants that may show up is probably a little too crazy, just for |
|
721 * the 'pleasure' of following the standard fill/narrow algorithm. |
|
722 * |
|
723 * I have therefore opted to handle this as a special case: We use the ref_value_null_literal_c symbol itself as the NULL datatype! |
|
724 * This implies the following changes: |
|
725 * - We change the get_datatype_info_c::is_type_equal() to take the NULL datatype into account |
|
726 * - We change the get_datatype_info_c::is_ref_to() to take the NULL datatype into account |
|
727 * - We change the fill_candidate_datatypes_c::visit(assignment_statement_c) to make sure it uses the datatype of the lvalue |
|
728 * as the datatype of the assignment statement |
|
729 * - We search_base_type_c::get_basetype_decl |
|
730 */ |
|
731 add_datatype_to_candidate_list(symbol, symbol); |
|
732 return NULL; |
|
733 } |
|
734 |
|
735 |
701 /******************************/ |
736 /******************************/ |
702 /* B 1.2.1 - Numeric Literals */ |
737 /* B 1.2.1 - Numeric Literals */ |
703 /******************************/ |
738 /******************************/ |
704 #define sizeoftype(symbol) get_sizeof_datatype_c::getsize(symbol) |
739 #define sizeoftype(symbol) get_sizeof_datatype_c::getsize(symbol) |
705 |
740 |
1999 /*********************************/ |
2034 /*********************************/ |
2000 /* B 3.2.1 Assignment Statements */ |
2035 /* B 3.2.1 Assignment Statements */ |
2001 /*********************************/ |
2036 /*********************************/ |
2002 void *fill_candidate_datatypes_c::visit(assignment_statement_c *symbol) { |
2037 void *fill_candidate_datatypes_c::visit(assignment_statement_c *symbol) { |
2003 symbol_c *left_type, *right_type; |
2038 symbol_c *left_type, *right_type; |
2004 |
|
2005 symbol->l_exp->accept(*this); |
2039 symbol->l_exp->accept(*this); |
2006 symbol->r_exp->accept(*this); |
2040 symbol->r_exp->accept(*this); |
2007 for (unsigned int i = 0; i < symbol->l_exp->candidate_datatypes.size(); i++) { |
2041 for (unsigned int i = 0; i < symbol->l_exp->candidate_datatypes.size(); i++) { |
2008 for(unsigned int j = 0; j < symbol->r_exp->candidate_datatypes.size(); j++) { |
2042 for(unsigned int j = 0; j < symbol->r_exp->candidate_datatypes.size(); j++) { |
2009 left_type = symbol->l_exp->candidate_datatypes[i]; |
2043 left_type = symbol->l_exp->candidate_datatypes[i]; |
2010 right_type = symbol->r_exp->candidate_datatypes[j]; |
2044 right_type = symbol->r_exp->candidate_datatypes[j]; |
2011 if (get_datatype_info_c::is_type_equal(left_type, right_type)) |
2045 if (get_datatype_info_c::is_type_equal(left_type, right_type)) |
2012 add_datatype_to_candidate_list(symbol, left_type); |
2046 add_datatype_to_candidate_list(symbol, left_type); // NOTE: Must use left_type, as the right_type may be the 'NULL' reference! (see comment in visit(ref_value_null_literal_c)) */ |
2013 } |
2047 } |
2014 } |
2048 } |
2015 if (debug) std::cout << ":= [" << symbol->l_exp->candidate_datatypes.size() << "," << symbol->r_exp->candidate_datatypes.size() << "] ==> " << symbol->candidate_datatypes.size() << " result.\n"; |
2049 if (debug) std::cout << ":= [" << symbol->l_exp->candidate_datatypes.size() << "," << symbol->r_exp->candidate_datatypes.size() << "] ==> " << symbol->candidate_datatypes.size() << " result.\n"; |
2016 return NULL; |
2050 return NULL; |
2017 } |
2051 } |