61 if ((typeid(*left_type) == typeid(*widen_table[k].left)) && (typeid(*right_type) == typeid(*widen_table[k].right))) |
61 if ((typeid(*left_type) == typeid(*widen_table[k].left)) && (typeid(*right_type) == typeid(*widen_table[k].right))) |
62 return widen_table[k].result; |
62 return widen_table[k].result; |
63 return NULL; |
63 return NULL; |
64 } |
64 } |
65 |
65 |
66 void fill_candidate_datatypes_c::match_nonformal_call(symbol_c *f_call, symbol_c *f_decl, int *error_count) { |
66 /* returns true if compatible function/FB invocation, otherwise returns false */ |
|
67 bool fill_candidate_datatypes_c::match_nonformal_call(symbol_c *f_call, symbol_c *f_decl) { |
67 symbol_c *call_param_value, *param_type; |
68 symbol_c *call_param_value, *param_type; |
68 identifier_c *param_name; |
69 identifier_c *param_name; |
69 function_param_iterator_c fp_iterator(f_decl); |
70 function_param_iterator_c fp_iterator(f_decl); |
70 function_call_param_iterator_c fcp_iterator(f_call); |
71 function_call_param_iterator_c fcp_iterator(f_call); |
71 int extensible_parameter_highest_index = -1; |
72 int extensible_parameter_highest_index = -1; |
72 unsigned int i; |
73 unsigned int i; |
73 |
74 |
74 /* reset error counter */ |
|
75 if (error_count != NULL) *error_count = 0; |
|
76 /* Iterating through the non-formal parameters of the function call */ |
75 /* Iterating through the non-formal parameters of the function call */ |
77 while((call_param_value = fcp_iterator.next_nf()) != NULL) { |
76 while((call_param_value = fcp_iterator.next_nf()) != NULL) { |
78 /* Obtaining the type of the value being passed in the function call */ |
|
79 std::vector <symbol_c *>&call_param_types = call_param_value->candidate_datatypes; |
|
80 /* Iterate to the next parameter of the function being called. |
77 /* Iterate to the next parameter of the function being called. |
81 * Get the name of that parameter, and ignore if EN or ENO. |
78 * Get the name of that parameter, and ignore if EN or ENO. |
82 */ |
79 */ |
83 do { |
80 do { |
84 param_name = fp_iterator.next(); |
81 param_name = fp_iterator.next(); |
85 /* If there is no other parameter declared, then we are passing too many parameters... */ |
82 /* If there is no other parameter declared, then we are passing too many parameters... */ |
86 if(param_name == NULL) { |
83 if(param_name == NULL) return false; |
87 (*error_count)++; |
|
88 return; |
|
89 } |
|
90 } while ((strcmp(param_name->value, "EN") == 0) || (strcmp(param_name->value, "ENO") == 0)); |
84 } while ((strcmp(param_name->value, "EN") == 0) || (strcmp(param_name->value, "ENO") == 0)); |
91 |
85 |
92 /* Get the parameter type */ |
86 /* Get the parameter type */ |
93 param_type = base_type(fp_iterator.param_type()); |
87 param_type = base_type(fp_iterator.param_type()); |
94 for(i = 0; i < call_param_types.size(); i++) { |
88 |
95 /* If the declared parameter and the parameter from the function call do not have the same type */ |
89 /* check whether one of the candidate_data_types of the value being passed is the same as the param_type */ |
96 if(is_type_equal(param_type, call_param_types[i])) { |
90 for(i = 0; i < call_param_value->candidate_datatypes.size(); i++) { |
97 break; |
91 /* If found (correct data type being passed), then stop the search */ |
98 } |
92 if(is_type_equal(param_type, call_param_value->candidate_datatypes[i])) break; |
99 } |
93 } |
100 if (i >= call_param_types.size()) (*error_count)++; |
94 /* if we reached the end of the loop, and no compatible type found, then return false */ |
101 } |
95 if (i >= call_param_value->candidate_datatypes.size()) return false; |
102 } |
96 } |
103 |
97 /* call is compatible! */ |
104 void fill_candidate_datatypes_c::match_formal_call(symbol_c *f_call, symbol_c *f_decl, int *error_count) { |
98 return true; |
|
99 } |
|
100 |
|
101 /* returns true if compatible function/FB invocation, otherwise returns false */ |
|
102 bool fill_candidate_datatypes_c::match_formal_call(symbol_c *f_call, symbol_c *f_decl) { |
105 symbol_c *call_param_value, *call_param_name, *param_type; |
103 symbol_c *call_param_value, *call_param_name, *param_type; |
106 symbol_c *verify_duplicate_param; |
104 symbol_c *verify_duplicate_param; |
107 identifier_c *param_name; |
105 identifier_c *param_name; |
108 function_param_iterator_c fp_iterator(f_decl); |
106 function_param_iterator_c fp_iterator(f_decl); |
109 function_call_param_iterator_c fcp_iterator(f_call); |
107 function_call_param_iterator_c fcp_iterator(f_call); |
110 int extensible_parameter_highest_index = -1; |
108 int extensible_parameter_highest_index = -1; |
111 identifier_c *extensible_parameter_name; |
109 identifier_c *extensible_parameter_name; |
112 unsigned int i; |
110 unsigned int i; |
113 |
111 |
114 /* reset error counter */ |
|
115 if (error_count != NULL) *error_count = 0; |
|
116 |
|
117 /* Iterating through the formal parameters of the function call */ |
112 /* Iterating through the formal parameters of the function call */ |
118 while((call_param_name = fcp_iterator.next_f()) != NULL) { |
113 while((call_param_name = fcp_iterator.next_f()) != NULL) { |
119 |
114 |
120 /* Obtaining the value being passed in the function call */ |
115 /* Obtaining the value being passed in the function call */ |
121 call_param_value = fcp_iterator.get_current_value(); |
116 call_param_value = fcp_iterator.get_current_value(); |
123 if (NULL == call_param_value) ERROR; |
118 if (NULL == call_param_value) ERROR; |
124 |
119 |
125 /* Checking if there are duplicated parameter values */ |
120 /* Checking if there are duplicated parameter values */ |
126 verify_duplicate_param = fcp_iterator.search_f(call_param_name); |
121 verify_duplicate_param = fcp_iterator.search_f(call_param_name); |
127 if(verify_duplicate_param != call_param_value) |
122 if(verify_duplicate_param != call_param_value) |
128 (*error_count)++; |
123 return false; |
129 |
124 |
130 /* Obtaining the type of the value being passed in the function call */ |
125 /* Obtaining the type of the value being passed in the function call */ |
131 std::vector <symbol_c *>&call_param_types = call_param_value->candidate_datatypes; |
126 std::vector <symbol_c *>&call_param_types = call_param_value->candidate_datatypes; |
132 |
127 |
133 |
128 |
134 /* Find the corresponding parameter in function declaration */ |
129 /* Find the corresponding parameter in function declaration */ |
135 param_name = fp_iterator.search(call_param_name); |
130 param_name = fp_iterator.search(call_param_name); |
136 if(param_name == NULL) { |
131 if(param_name == NULL) { |
137 (*error_count)++; |
132 return false; |
138 } else { |
133 } else { |
139 /* Get the parameter type */ |
134 /* Get the parameter type */ |
140 param_type = base_type(fp_iterator.param_type()); |
135 param_type = base_type(fp_iterator.param_type()); |
141 for (i = 0; i < call_param_types.size(); i++) { |
136 for (i = 0; i < call_param_types.size(); i++) { |
142 /* If the declared parameter and the parameter from the function call have the same type */ |
137 /* If the declared parameter and the parameter from the function call have the same type */ |
143 if(is_type_equal(param_type, call_param_types[i])) |
138 if(is_type_equal(param_type, call_param_types[i])) |
144 break; |
139 break; |
145 } |
140 } |
146 if (i >= call_param_types.size()) (*error_count)++; |
141 if (i >= call_param_types.size()) |
147 } |
142 return false;; |
148 } |
143 } |
149 |
144 } |
|
145 return true; |
150 } |
146 } |
151 |
147 |
152 /* a helper function... */ |
148 /* a helper function... */ |
153 symbol_c *fill_candidate_datatypes_c::base_type(symbol_c *symbol) { |
149 symbol_c *fill_candidate_datatypes_c::base_type(symbol_c *symbol) { |
154 /* NOTE: symbol == NULL is valid. It will occur when, for e.g., an undefined/undeclared symbolic_variable is used |
150 /* NOTE: symbol == NULL is valid. It will occur when, for e.g., an undefined/undeclared symbolic_variable is used |
1665 |
1661 |
1666 void *fill_candidate_datatypes_c::visit(function_invocation_c *symbol) { |
1662 void *fill_candidate_datatypes_c::visit(function_invocation_c *symbol) { |
1667 function_declaration_c *f_decl; |
1663 function_declaration_c *f_decl; |
1668 list_c *parameter_list; |
1664 list_c *parameter_list; |
1669 list_c *parameter_candidate_datatypes; |
1665 list_c *parameter_candidate_datatypes; |
1670 symbol_c *parameter_type; |
1666 symbol_c *returned_parameter_type; |
1671 function_symtable_t::iterator lower = function_symtable.lower_bound(symbol->function_name); |
1667 function_symtable_t::iterator lower = function_symtable.lower_bound(symbol->function_name); |
1672 function_symtable_t::iterator upper = function_symtable.upper_bound(symbol->function_name); |
1668 function_symtable_t::iterator upper = function_symtable.upper_bound(symbol->function_name); |
1673 /* If the name of the function being called is not found in the function symbol table, then this is an invalid call */ |
1669 /* If the name of the function being called is not found in the function symbol table, then this is an invalid call */ |
1674 /* Since the lexical parser already checks for this, then if this occurs then we have an internal compiler error. */ |
1670 /* Since the lexical parser already checks for this, then if this occurs then we have an internal compiler error. */ |
1675 if (lower == function_symtable.end()) ERROR; |
1671 if (lower == function_symtable.end()) ERROR; |
1681 else ERROR; |
1677 else ERROR; |
1682 |
1678 |
1683 if (debug) std::cout << "function()\n"; |
1679 if (debug) std::cout << "function()\n"; |
1684 parameter_list->accept(*this); |
1680 parameter_list->accept(*this); |
1685 for(; lower != upper; lower++) { |
1681 for(; lower != upper; lower++) { |
1686 int error_count = 0; |
1682 bool compatible = false; |
1687 f_decl = function_symtable.get_value(lower); |
1683 f_decl = function_symtable.get_value(lower); |
1688 /* Check if function declaration in symbol_table is compatible with parameters */ |
1684 /* Check if function declaration in symbol_table is compatible with parameters */ |
1689 if (NULL != symbol->nonformal_param_list) match_nonformal_call(symbol, f_decl, &error_count); |
1685 if (NULL != symbol->nonformal_param_list) compatible=match_nonformal_call(symbol, f_decl); |
1690 if (NULL != symbol-> formal_param_list) match_formal_call(symbol, f_decl, &error_count); |
1686 if (NULL != symbol-> formal_param_list) compatible= match_formal_call(symbol, f_decl); |
1691 if (0 == error_count) { |
1687 if (compatible) { |
1692 /* Add basetype matching function only if not present */ |
1688 /* Add the data type returned by the called functions. |
|
1689 * However, only do this if this data type is not already present in the candidate_datatypes list_c |
|
1690 */ |
1693 unsigned int k; |
1691 unsigned int k; |
1694 parameter_type = base_type(f_decl->type_name); |
1692 returned_parameter_type = base_type(f_decl->type_name); |
1695 for(k = 0; k < symbol->candidate_datatypes.size(); k++) { |
1693 for(k = 0; k < symbol->candidate_datatypes.size(); k++) { |
1696 if (is_type_equal(parameter_type, symbol->candidate_datatypes[k])) |
1694 if (is_type_equal(returned_parameter_type, symbol->candidate_datatypes[k])) |
1697 break; |
1695 break; |
1698 } |
1696 } |
1699 if (k >= symbol->candidate_datatypes.size()) |
1697 if (k >= symbol->candidate_datatypes.size()) { |
1700 symbol->candidate_datatypes.push_back(parameter_type); |
1698 symbol->candidate_datatypes.push_back(returned_parameter_type); |
|
1699 symbol->candidate_functions.push_back(f_decl); |
|
1700 } |
1701 } |
1701 } |
1702 } |
1702 } |
1703 if (debug) std::cout << "end_function() [" << symbol->candidate_datatypes.size() << "] result.\n"; |
1703 if (debug) std::cout << "end_function() [" << symbol->candidate_datatypes.size() << "] result.\n"; |
1704 return NULL; |
1704 return NULL; |
1705 } |
1705 } |
1736 |
1736 |
1737 /*****************************************/ |
1737 /*****************************************/ |
1738 /* B 3.2.2 Subprogram Control Statements */ |
1738 /* B 3.2.2 Subprogram Control Statements */ |
1739 /*****************************************/ |
1739 /*****************************************/ |
1740 void *fill_candidate_datatypes_c::visit(fb_invocation_c *symbol) { |
1740 void *fill_candidate_datatypes_c::visit(fb_invocation_c *symbol) { |
|
1741 bool compatible = false; |
1741 symbol_c *fb_decl = search_varfb_instance_type->get_basetype_decl(symbol->fb_name); |
1742 symbol_c *fb_decl = search_varfb_instance_type->get_basetype_decl(symbol->fb_name); |
1742 |
1743 |
1743 if (NULL == fb_decl) ERROR; |
1744 if (NULL == fb_decl) ERROR; |
1744 if (symbol-> formal_param_list != NULL) match_formal_call(symbol, fb_decl); |
1745 if (symbol-> formal_param_list != NULL) { |
1745 if (symbol->nonformal_param_list != NULL) match_nonformal_call(symbol, fb_decl); |
1746 symbol->formal_param_list->accept(*this); |
|
1747 compatible = match_formal_call(symbol, fb_decl); |
|
1748 } |
|
1749 if (symbol->nonformal_param_list != NULL) { |
|
1750 symbol->nonformal_param_list->accept(*this); |
|
1751 compatible = match_nonformal_call(symbol, fb_decl); |
|
1752 } |
1746 if (debug) std::cout << "FB [] ==> " << symbol->candidate_datatypes.size() << " result.\n"; |
1753 if (debug) std::cout << "FB [] ==> " << symbol->candidate_datatypes.size() << " result.\n"; |
1747 return NULL; |
1754 return NULL; |
1748 } |
1755 } |
1749 |
1756 |
1750 |
1757 |