553 /* handle implicit FB call in IL. |
553 /* handle implicit FB call in IL. |
554 * e.g. CLK ton_var |
554 * e.g. CLK ton_var |
555 * CU counter_var |
555 * CU counter_var |
556 */ |
556 */ |
557 void *fill_candidate_datatypes_c::handle_implicit_il_fb_call(symbol_c *il_instruction, const char *param_name, symbol_c *&called_fb_declaration) { |
557 void *fill_candidate_datatypes_c::handle_implicit_il_fb_call(symbol_c *il_instruction, const char *param_name, symbol_c *&called_fb_declaration) { |
558 symbol_c *fb_type_id = search_varfb_instance_type->get_basetype_id(il_operand); |
558 symbol_c *fb_decl = (NULL == il_operand)? NULL : search_varfb_instance_type->get_basetype_decl(il_operand); |
559 /* Although a call to a non-declared FB is a semantic error, this is currently caught by stage 2! */ |
559 if (! get_datatype_info_c::is_function_block(fb_decl)) fb_decl = NULL; |
560 if (NULL == fb_type_id) ERROR; |
560 |
561 |
561 /* Although a call to a non-declared FB is a semantic error, this is currently caught by stage 2! */ |
562 function_block_declaration_c *fb_decl = function_block_type_symtable.find_value(fb_type_id); |
562 /* However, when calling using the 'S' and 'R' operators, this error is not caught by stage 2, as these operators have two possible semantics */ |
563 if (function_block_type_symtable.end_value() == fb_decl) |
563 // if (NULL == fb_type_id) ERROR; |
564 /* The il_operand is not the name of a FB instance. Most probably it is the name of a variable of some other type. |
564 |
565 * this is a semantic error. |
|
566 */ |
|
567 fb_decl = NULL; |
|
568 |
|
569 /* The narrow_candidate_datatypes_c does not rely on this called_fb_declaration pointer being == NULL to conclude that |
565 /* The narrow_candidate_datatypes_c does not rely on this called_fb_declaration pointer being == NULL to conclude that |
570 * we have a datatype incompatibility error, so we set it to fb_decl to allow the print_datatype_error_c to print out |
566 * we have a datatype incompatibility error, so we set it to fb_decl to allow the print_datatype_error_c to print out |
571 * more informative error messages! |
567 * more informative error messages! |
572 */ |
568 */ |
573 called_fb_declaration = fb_decl; |
569 called_fb_declaration = fb_decl; |
592 } |
588 } |
593 |
589 |
594 |
590 |
595 |
591 |
596 |
592 |
|
593 |
|
594 /* handle the S and R IL operators... */ |
|
595 /* operator_str should be set to either "S" or "R" */ |
|
596 void *fill_candidate_datatypes_c::handle_S_and_R_operator(symbol_c *symbol, const char *operator_str, symbol_c *&called_fb_declaration) { |
|
597 /* NOTE: this operator has two possible semantic meanings: |
|
598 * - Set/Reset the BOOL operand variable to true |
|
599 * - call the FB specified by the operand. |
|
600 * Which of the two semantics will have to be determined by the datatype of the operand! |
|
601 */ |
|
602 symbol_c *prev_instruction_type, *operand_type; |
|
603 |
|
604 if (NULL == prev_il_instruction) return NULL; |
|
605 if (NULL == il_operand) return NULL; |
|
606 |
|
607 for (unsigned int i = 0; i < prev_il_instruction->candidate_datatypes.size(); i++) { |
|
608 for(unsigned int j = 0; j < il_operand->candidate_datatypes.size(); j++) { |
|
609 prev_instruction_type = prev_il_instruction->candidate_datatypes[i]; |
|
610 operand_type = il_operand->candidate_datatypes[j]; |
|
611 /* IEC61131-3, Table 52, Note (e) states that the datatype of the operand must be BOOL! |
|
612 * IEC61131-3, Table 52, line 3 states that this operator should "Set operand to 1 if current result is Boolean 1" |
|
613 * which implies that the prev_instruction_type MUST also be BOOL compatible. |
|
614 */ |
|
615 if (get_datatype_info_c::is_BOOL_compatible(prev_instruction_type) && get_datatype_info_c::is_BOOL_compatible(operand_type)) |
|
616 add_datatype_to_candidate_list(symbol, prev_instruction_type); |
|
617 } |
|
618 } |
|
619 |
|
620 /* if the appropriate semantics is not a Set/Reset of a boolean variable, the we try for the FB invocation! */ |
|
621 if (symbol->candidate_datatypes.size() == 0) |
|
622 handle_implicit_il_fb_call(symbol, operator_str, called_fb_declaration); |
|
623 |
|
624 /* If it is also not a valid FB call, make sure the candidate_datatypes is empty (handle_implicit_il_fb_call may leave it non-empty!!) */ |
|
625 /* From here on out, all later code will consider the symbol->called_fb_declaration being NULL as an indication that this operator must use the |
|
626 * Set/Reset semantics, so we must also guarantee that the remainder of the state of this symbol is compatible with that assumption! |
|
627 */ |
|
628 if (NULL == called_fb_declaration) |
|
629 symbol->candidate_datatypes.clear(); |
|
630 |
|
631 if (debug) std::cout << operator_str << " [" << prev_il_instruction->candidate_datatypes.size() << "," << il_operand->candidate_datatypes.size() << "] ==> " << symbol->candidate_datatypes.size() << " result.\n"; |
|
632 return NULL; |
|
633 } |
|
634 |
|
635 |
|
636 |
597 /* handle a binary IL operator, like ADD, SUB, etc... */ |
637 /* handle a binary IL operator, like ADD, SUB, etc... */ |
598 void *fill_candidate_datatypes_c::handle_binary_operator(const struct widen_entry widen_table[], symbol_c *symbol, symbol_c *l_expr, symbol_c *r_expr) { |
638 void *fill_candidate_datatypes_c::handle_binary_operator(const struct widen_entry widen_table[], symbol_c *symbol, symbol_c *l_expr, symbol_c *r_expr) { |
599 if (NULL == l_expr) /* if no prev_il_instruction */ |
639 if (NULL == l_expr) return NULL; /* if no prev_il_instruction */ |
600 return NULL; |
640 if (NULL == r_expr) return NULL; /* if no IL operand!! */ |
601 |
641 |
602 for(unsigned int i = 0; i < l_expr->candidate_datatypes.size(); i++) |
642 for(unsigned int i = 0; i < l_expr->candidate_datatypes.size(); i++) |
603 for(unsigned int j = 0; j < r_expr->candidate_datatypes.size(); j++) |
643 for(unsigned int j = 0; j < r_expr->candidate_datatypes.size(); j++) |
604 /* NOTE: add_datatype_to_candidate_list() will only really add the datatype if it is != NULL !!! */ |
644 /* NOTE: add_datatype_to_candidate_list() will only really add the datatype if it is != NULL !!! */ |
605 add_datatype_to_candidate_list(symbol, widening_conversion(l_expr->candidate_datatypes[i], r_expr->candidate_datatypes[j], widen_table)); |
645 add_datatype_to_candidate_list(symbol, widening_conversion(l_expr->candidate_datatypes[i], r_expr->candidate_datatypes[j], widen_table)); |
1551 * | il_call_operator prev_declared_fb_name '(' ')' |
1591 * | il_call_operator prev_declared_fb_name '(' ')' |
1552 * | il_call_operator prev_declared_fb_name '(' eol_list ')' |
1592 * | il_call_operator prev_declared_fb_name '(' eol_list ')' |
1553 * | il_call_operator prev_declared_fb_name '(' il_operand_list ')' |
1593 * | il_call_operator prev_declared_fb_name '(' il_operand_list ')' |
1554 * | il_call_operator prev_declared_fb_name '(' eol_list il_param_list ')' |
1594 * | il_call_operator prev_declared_fb_name '(' eol_list il_param_list ')' |
1555 */ |
1595 */ |
1556 /* NOTE: The parameter 'called_fb_declaration'is used to pass data between stage 3 and stage4 (although currently it is not used in stage 4 */ |
1596 /* NOTE: The parameter 'called_fb_declaration'is used to pass data between stage 3 and stage4 */ |
1557 // SYM_REF4(il_fb_call_c, il_call_operator, fb_name, il_operand_list, il_param_list, symbol_c *called_fb_declaration) |
1597 // SYM_REF4(il_fb_call_c, il_call_operator, fb_name, il_operand_list, il_param_list, symbol_c *called_fb_declaration) |
1558 void *fill_candidate_datatypes_c::visit(il_fb_call_c *symbol) { |
1598 void *fill_candidate_datatypes_c::visit(il_fb_call_c *symbol) { |
1559 /* We do not call |
1599 symbol_c *fb_decl = search_varfb_instance_type->get_basetype_decl(symbol->fb_name); |
1560 * fb_decl = search_varfb_instance_type->get_basetype_decl(symbol->fb_name); |
1600 if (! get_datatype_info_c::is_function_block(fb_decl)) fb_decl = NULL; |
1561 * because we want to make sure it is a FB instance, and not some other data type... |
|
1562 */ |
|
1563 symbol_c *fb_type_id = search_varfb_instance_type->get_basetype_id(symbol->fb_name); |
|
1564 /* Although a call to a non-declared FB is a semantic error, this is currently caught by stage 2! */ |
|
1565 if (NULL == fb_type_id) ERROR; |
|
1566 |
|
1567 function_block_declaration_c *fb_decl = function_block_type_symtable.find_value(fb_type_id); |
|
1568 if (function_block_type_symtable.end_value() == fb_decl) |
|
1569 /* The fb_name not the name of a FB instance. Most probably it is the name of a variable of some other type. */ |
|
1570 fb_decl = NULL; |
|
1571 |
1601 |
1572 /* Although a call to a non-declared FB is a semantic error, this is currently caught by stage 2! */ |
1602 /* Although a call to a non-declared FB is a semantic error, this is currently caught by stage 2! */ |
1573 if (NULL == fb_decl) ERROR; |
1603 if (NULL == fb_decl) ERROR; |
1574 |
1604 |
1575 if (symbol-> il_param_list != NULL) symbol->il_param_list->accept(*this); |
1605 if (symbol-> il_param_list != NULL) symbol->il_param_list->accept(*this); |
1662 |
1692 |
1663 /*******************/ |
1693 /*******************/ |
1664 /* B 2.2 Operators */ |
1694 /* B 2.2 Operators */ |
1665 /*******************/ |
1695 /*******************/ |
1666 void *fill_candidate_datatypes_c::visit(LD_operator_c *symbol) { |
1696 void *fill_candidate_datatypes_c::visit(LD_operator_c *symbol) { |
|
1697 if (NULL == il_operand) return NULL; |
1667 for(unsigned int i = 0; i < il_operand->candidate_datatypes.size(); i++) { |
1698 for(unsigned int i = 0; i < il_operand->candidate_datatypes.size(); i++) { |
1668 add_datatype_to_candidate_list(symbol, il_operand->candidate_datatypes[i]); |
1699 add_datatype_to_candidate_list(symbol, il_operand->candidate_datatypes[i]); |
1669 } |
1700 } |
1670 if (debug) std::cout << "LD [" << il_operand->candidate_datatypes.size() << "] ==> " << symbol->candidate_datatypes.size() << " result.\n"; |
1701 if (debug) std::cout << "LD [" << il_operand->candidate_datatypes.size() << "] ==> " << symbol->candidate_datatypes.size() << " result.\n"; |
1671 return NULL; |
1702 return NULL; |
1672 } |
1703 } |
1673 |
1704 |
1674 void *fill_candidate_datatypes_c::visit(LDN_operator_c *symbol) { |
1705 void *fill_candidate_datatypes_c::visit(LDN_operator_c *symbol) { |
|
1706 if (NULL == il_operand) return NULL; |
1675 for(unsigned int i = 0; i < il_operand->candidate_datatypes.size(); i++) { |
1707 for(unsigned int i = 0; i < il_operand->candidate_datatypes.size(); i++) { |
1676 if (get_datatype_info_c::is_ANY_BIT_compatible(il_operand->candidate_datatypes[i])) |
1708 if (get_datatype_info_c::is_ANY_BIT_compatible(il_operand->candidate_datatypes[i])) |
1677 add_datatype_to_candidate_list(symbol, il_operand->candidate_datatypes[i]); |
1709 add_datatype_to_candidate_list(symbol, il_operand->candidate_datatypes[i]); |
1678 } |
1710 } |
1679 if (debug) std::cout << "LDN [" << il_operand->candidate_datatypes.size() << "] ==> " << symbol->candidate_datatypes.size() << " result.\n"; |
1711 if (debug) std::cout << "LDN [" << il_operand->candidate_datatypes.size() << "] ==> " << symbol->candidate_datatypes.size() << " result.\n"; |
1718 * However, it does not define the semantic of the NOT operation when the <il_operand> is specified. |
1752 * However, it does not define the semantic of the NOT operation when the <il_operand> is specified. |
1719 * We therefore consider it an error if an il_operand is specified! |
1753 * We therefore consider it an error if an il_operand is specified! |
1720 * We do not need to generate an error message. This error will be caught somewhere else! |
1754 * We do not need to generate an error message. This error will be caught somewhere else! |
1721 */ |
1755 */ |
1722 if (NULL == prev_il_instruction) return NULL; |
1756 if (NULL == prev_il_instruction) return NULL; |
|
1757 if (NULL == il_operand) return NULL; |
1723 for (unsigned int i = 0; i < prev_il_instruction->candidate_datatypes.size(); i++) { |
1758 for (unsigned int i = 0; i < prev_il_instruction->candidate_datatypes.size(); i++) { |
1724 if (get_datatype_info_c::is_ANY_BIT_compatible(prev_il_instruction->candidate_datatypes[i])) |
1759 if (get_datatype_info_c::is_ANY_BIT_compatible(prev_il_instruction->candidate_datatypes[i])) |
1725 add_datatype_to_candidate_list(symbol, prev_il_instruction->candidate_datatypes[i]); |
1760 add_datatype_to_candidate_list(symbol, prev_il_instruction->candidate_datatypes[i]); |
1726 } |
1761 } |
1727 if (debug) std::cout << "NOT_operator [" << prev_il_instruction->candidate_datatypes.size() << "] ==> " << symbol->candidate_datatypes.size() << " result.\n"; |
1762 if (debug) std::cout << "NOT_operator [" << prev_il_instruction->candidate_datatypes.size() << "] ==> " << symbol->candidate_datatypes.size() << " result.\n"; |
1728 return NULL; |
1763 return NULL; |
1729 } |
1764 } |
1730 |
1765 |
1731 |
1766 |
1732 void *fill_candidate_datatypes_c::visit(S_operator_c *symbol) { |
1767 void *fill_candidate_datatypes_c::visit( S_operator_c *symbol) {return handle_S_and_R_operator (symbol, "S", symbol->called_fb_declaration);} |
1733 /* TODO: what if this is a FB call ?? */ |
1768 void *fill_candidate_datatypes_c::visit( R_operator_c *symbol) {return handle_S_and_R_operator (symbol, "R", symbol->called_fb_declaration);} |
1734 symbol_c *prev_instruction_type, *operand_type; |
1769 |
1735 |
1770 void *fill_candidate_datatypes_c::visit( S1_operator_c *symbol) {return handle_implicit_il_fb_call(symbol, "S1", symbol->called_fb_declaration);} |
1736 if (NULL == prev_il_instruction) return NULL; |
1771 void *fill_candidate_datatypes_c::visit( R1_operator_c *symbol) {return handle_implicit_il_fb_call(symbol, "R1", symbol->called_fb_declaration);} |
1737 for (unsigned int i = 0; i < prev_il_instruction->candidate_datatypes.size(); i++) { |
|
1738 for(unsigned int j = 0; j < il_operand->candidate_datatypes.size(); j++) { |
|
1739 prev_instruction_type = prev_il_instruction->candidate_datatypes[i]; |
|
1740 operand_type = il_operand->candidate_datatypes[j]; |
|
1741 /* TODO: I believe the following is wrong! The data types of prev_instruction_type and operand_type DO NOT have to be equal. |
|
1742 * the prev_instruction_type MUST be BOOL compatible. |
|
1743 * I am not too sure about operand_type, does it have to be BOOL compatible, or can it be ANY_BIT compatible? Must check! |
|
1744 */ |
|
1745 if (get_datatype_info_c::is_type_equal(prev_instruction_type,operand_type) && get_datatype_info_c::is_BOOL_compatible(operand_type)) |
|
1746 add_datatype_to_candidate_list(symbol, prev_instruction_type); |
|
1747 } |
|
1748 } |
|
1749 if (debug) std::cout << "S [" << prev_il_instruction->candidate_datatypes.size() << "," << il_operand->candidate_datatypes.size() << "] ==> " << symbol->candidate_datatypes.size() << " result.\n"; |
|
1750 return NULL; |
|
1751 } |
|
1752 |
|
1753 |
|
1754 void *fill_candidate_datatypes_c::visit(R_operator_c *symbol) { |
|
1755 /* TODO: what if this is a FB call ?? */ |
|
1756 symbol_c *prev_instruction_type, *operand_type; |
|
1757 |
|
1758 if (NULL == prev_il_instruction) return NULL; |
|
1759 for (unsigned int i = 0; i < prev_il_instruction->candidate_datatypes.size(); i++) { |
|
1760 for(unsigned int j = 0; j < il_operand->candidate_datatypes.size(); j++) { |
|
1761 prev_instruction_type = prev_il_instruction->candidate_datatypes[i]; |
|
1762 operand_type = il_operand->candidate_datatypes[j]; |
|
1763 /* TODO: I believe the following is wrong! The data types of prev_instruction_type and operand_type DO NOT have to be equal. |
|
1764 * the prev_instruction_type MUST be BOOL compatible. |
|
1765 * I am not too sure about operand_type, does it have to be BOOL compatible, or can it be ANY_BIT compatible? Must check! |
|
1766 */ |
|
1767 if (get_datatype_info_c::is_type_equal(prev_instruction_type,operand_type) && get_datatype_info_c::is_BOOL_compatible(operand_type)) |
|
1768 add_datatype_to_candidate_list(symbol, prev_instruction_type); |
|
1769 } |
|
1770 } |
|
1771 if (debug) std::cout << "R [" << prev_il_instruction->candidate_datatypes.size() << "," << il_operand->candidate_datatypes.size() << "] ==> " << symbol->candidate_datatypes.size() << " result.\n"; |
|
1772 return NULL; |
|
1773 } |
|
1774 |
|
1775 |
|
1776 void *fill_candidate_datatypes_c::visit( S1_operator_c *symbol) {return handle_implicit_il_fb_call(symbol, "S1", symbol->called_fb_declaration);} |
|
1777 void *fill_candidate_datatypes_c::visit( R1_operator_c *symbol) {return handle_implicit_il_fb_call(symbol, "R1", symbol->called_fb_declaration);} |
|
1778 void *fill_candidate_datatypes_c::visit( CLK_operator_c *symbol) {return handle_implicit_il_fb_call(symbol, "CLK", symbol->called_fb_declaration);} |
1772 void *fill_candidate_datatypes_c::visit( CLK_operator_c *symbol) {return handle_implicit_il_fb_call(symbol, "CLK", symbol->called_fb_declaration);} |
1779 void *fill_candidate_datatypes_c::visit( CU_operator_c *symbol) {return handle_implicit_il_fb_call(symbol, "CU", symbol->called_fb_declaration);} |
1773 void *fill_candidate_datatypes_c::visit( CU_operator_c *symbol) {return handle_implicit_il_fb_call(symbol, "CU", symbol->called_fb_declaration);} |
1780 void *fill_candidate_datatypes_c::visit( CD_operator_c *symbol) {return handle_implicit_il_fb_call(symbol, "CD", symbol->called_fb_declaration);} |
1774 void *fill_candidate_datatypes_c::visit( CD_operator_c *symbol) {return handle_implicit_il_fb_call(symbol, "CD", symbol->called_fb_declaration);} |
1781 void *fill_candidate_datatypes_c::visit( PV_operator_c *symbol) {return handle_implicit_il_fb_call(symbol, "PV", symbol->called_fb_declaration);} |
1775 void *fill_candidate_datatypes_c::visit( PV_operator_c *symbol) {return handle_implicit_il_fb_call(symbol, "PV", symbol->called_fb_declaration);} |
1782 void *fill_candidate_datatypes_c::visit( IN_operator_c *symbol) {return handle_implicit_il_fb_call(symbol, "IN", symbol->called_fb_declaration);} |
1776 void *fill_candidate_datatypes_c::visit( IN_operator_c *symbol) {return handle_implicit_il_fb_call(symbol, "IN", symbol->called_fb_declaration);} |
1783 void *fill_candidate_datatypes_c::visit( PT_operator_c *symbol) {return handle_implicit_il_fb_call(symbol, "PT", symbol->called_fb_declaration);} |
1777 void *fill_candidate_datatypes_c::visit( PT_operator_c *symbol) {return handle_implicit_il_fb_call(symbol, "PT", symbol->called_fb_declaration);} |
1784 |
1778 |
1785 void *fill_candidate_datatypes_c::visit( AND_operator_c *symbol) {return handle_binary_operator(widen_AND_table, symbol, prev_il_instruction, il_operand);} |
1779 void *fill_candidate_datatypes_c::visit( AND_operator_c *symbol) {return handle_binary_operator(widen_AND_table, symbol, prev_il_instruction, il_operand);} |
1786 void *fill_candidate_datatypes_c::visit( OR_operator_c *symbol) {return handle_binary_operator( widen_OR_table, symbol, prev_il_instruction, il_operand);} |
1780 void *fill_candidate_datatypes_c::visit( OR_operator_c *symbol) {return handle_binary_operator( widen_OR_table, symbol, prev_il_instruction, il_operand);} |
1787 void *fill_candidate_datatypes_c::visit( XOR_operator_c *symbol) {return handle_binary_operator(widen_XOR_table, symbol, prev_il_instruction, il_operand);} |
1781 void *fill_candidate_datatypes_c::visit( XOR_operator_c *symbol) {return handle_binary_operator(widen_XOR_table, symbol, prev_il_instruction, il_operand);} |
1788 void *fill_candidate_datatypes_c::visit(ANDN_operator_c *symbol) {return handle_binary_operator(widen_AND_table, symbol, prev_il_instruction, il_operand);} |
1782 void *fill_candidate_datatypes_c::visit(ANDN_operator_c *symbol) {return handle_binary_operator(widen_AND_table, symbol, prev_il_instruction, il_operand);} |
1967 |
1961 |
1968 /*****************************************/ |
1962 /*****************************************/ |
1969 /* B 3.2.2 Subprogram Control Statements */ |
1963 /* B 3.2.2 Subprogram Control Statements */ |
1970 /*****************************************/ |
1964 /*****************************************/ |
1971 void *fill_candidate_datatypes_c::visit(fb_invocation_c *symbol) { |
1965 void *fill_candidate_datatypes_c::visit(fb_invocation_c *symbol) { |
1972 symbol_c *fb_type_id = search_varfb_instance_type->get_basetype_id(symbol->fb_name); |
1966 symbol_c *fb_decl = search_varfb_instance_type->get_basetype_decl(symbol->fb_name); |
1973 /* Although a call to a non-declared FB is a semantic error, this is currently caught by stage 2! */ |
1967 if (! get_datatype_info_c::is_function_block(fb_decl )) fb_decl = NULL; |
1974 if (NULL == fb_type_id) ERROR; |
1968 if (NULL == fb_decl) ERROR; /* Although a call to a non-declared FB is a semantic error, this is currently caught by stage 2! */ |
1975 |
|
1976 function_block_declaration_c *fb_decl = function_block_type_symtable.find_value(fb_type_id); |
|
1977 if (function_block_type_symtable.end_value() == fb_decl) |
|
1978 /* The fb_name not the name of a FB instance. Most probably it is the name of a variable of some other type. */ |
|
1979 fb_decl = NULL; |
|
1980 |
|
1981 /* Although a call to a non-declared FB is a semantic error, this is currently caught by stage 2! */ |
|
1982 if (NULL == fb_decl) ERROR; |
|
1983 |
1969 |
1984 if (symbol-> formal_param_list != NULL) symbol->formal_param_list->accept(*this); |
1970 if (symbol-> formal_param_list != NULL) symbol->formal_param_list->accept(*this); |
1985 if (symbol->nonformal_param_list != NULL) symbol->nonformal_param_list->accept(*this); |
1971 if (symbol->nonformal_param_list != NULL) symbol->nonformal_param_list->accept(*this); |
1986 |
1972 |
1987 /* The print_datatypes_error_c does not rely on this called_fb_declaration pointer being != NULL to conclude that |
1973 /* The print_datatypes_error_c does not rely on this called_fb_declaration pointer being != NULL to conclude that |