63 } |
63 } |
64 } |
64 } |
65 return false; |
65 return false; |
66 } |
66 } |
67 |
67 |
68 void narrow_candidate_datatypes_c::narrow_nonformal_call(symbol_c *f_call, symbol_c *f_decl) { |
68 void narrow_candidate_datatypes_c::narrow_nonformal_call(symbol_c *f_call, symbol_c *f_decl, int *ext_parm_count) { |
69 symbol_c *call_param_value, *param_type; |
69 symbol_c *call_param_value, *param_type; |
70 identifier_c *param_name; |
70 identifier_c *param_name; |
71 function_param_iterator_c fp_iterator(f_decl); |
71 function_param_iterator_c fp_iterator(f_decl); |
72 function_call_param_iterator_c fcp_iterator(f_call); |
72 function_call_param_iterator_c fcp_iterator(f_call); |
73 int extensible_parameter_highest_index = -1; |
73 int extensible_parameter_highest_index = -1; |
74 identifier_c *extensible_parameter_name; |
|
75 unsigned int i; |
74 unsigned int i; |
76 |
75 |
|
76 if (NULL != ext_parm_count) *ext_parm_count = -1; |
77 |
77 |
78 /* Iterating through the non-formal parameters of the function call */ |
78 /* Iterating through the non-formal parameters of the function call */ |
79 while((call_param_value = fcp_iterator.next_nf()) != NULL) { |
79 while((call_param_value = fcp_iterator.next_nf()) != NULL) { |
80 /* Obtaining the type of the value being passed in the function call */ |
80 /* Obtaining the type of the value being passed in the function call */ |
81 /* Iterate to the next parameter of the function being called. |
81 /* Iterate to the next parameter of the function being called. |
82 * Get the name of that parameter, and ignore if EN or ENO. |
82 * Get the name of that parameter, and ignore if EN or ENO. |
83 */ |
83 */ |
84 do { |
84 do { |
85 param_name = fp_iterator.next(); |
85 param_name = fp_iterator.next(); |
86 /* If there is no other parameter declared, then we are passing too many parameters... */ |
86 /* If there is no other parameter declared, then we are passing too many parameters... */ |
87 if(param_name == NULL) { |
87 /* This error should have been caught in fill_candidate_datatypes_c */ |
88 return; |
88 if(param_name == NULL) ERROR; |
89 } |
|
90 } while ((strcmp(param_name->value, "EN") == 0) || (strcmp(param_name->value, "ENO") == 0)); |
89 } while ((strcmp(param_name->value, "EN") == 0) || (strcmp(param_name->value, "ENO") == 0)); |
91 |
90 |
92 /* Get the parameter type */ |
91 /* Set the desired datatype for this parameter, and call it recursively. */ |
93 call_param_value->datatype = base_type(fp_iterator.param_type()); |
92 call_param_value->datatype = base_type(fp_iterator.param_type()); |
94 call_param_value->accept(*this); |
93 call_param_value->accept(*this); |
95 if (extensible_parameter_highest_index < fp_iterator.extensible_param_index()) { |
94 |
|
95 if (extensible_parameter_highest_index < fp_iterator.extensible_param_index()) |
96 extensible_parameter_highest_index = fp_iterator.extensible_param_index(); |
96 extensible_parameter_highest_index = fp_iterator.extensible_param_index(); |
97 extensible_parameter_name = param_name; |
97 } |
98 } |
98 /* call is compatible! */ |
99 } |
99 |
100 int extensible_param_count = -1; |
100 /* In the case of a call to an extensible function, we store the highest index |
101 if (extensible_parameter_highest_index >=0) /* if call to extensible function */ |
101 * of the extensible parameters this particular call uses, in the symbol_c object |
102 extensible_param_count = 1 + extensible_parameter_highest_index - fp_iterator.first_extensible_param_index(); |
102 * of the function call itself! |
103 function_invocation_c *function_invocation = dynamic_cast<function_invocation_c *>(f_call); |
103 * In calls to non-extensible functions, this value will be set to -1. |
104 if (function_invocation != NULL) function_invocation->extensible_param_count = extensible_param_count; |
104 * This information is later used in stage4 to correctly generate the |
105 |
105 * output code. |
106 } |
106 */ |
107 |
107 if ((NULL != ext_parm_count) && (extensible_parameter_highest_index >=0) /* if call to extensible function */) |
108 void narrow_candidate_datatypes_c::narrow_formal_call(symbol_c *f_call, symbol_c *f_decl) { |
108 *ext_parm_count = 1 + extensible_parameter_highest_index - fp_iterator.first_extensible_param_index(); |
|
109 } |
|
110 |
|
111 |
|
112 |
|
113 void narrow_candidate_datatypes_c::narrow_formal_call(symbol_c *f_call, symbol_c *f_decl, int *ext_parm_count) { |
109 symbol_c *call_param_value, *call_param_name, *param_type; |
114 symbol_c *call_param_value, *call_param_name, *param_type; |
110 symbol_c *verify_duplicate_param; |
115 symbol_c *verify_duplicate_param; |
111 identifier_c *param_name; |
116 identifier_c *param_name; |
112 function_param_iterator_c fp_iterator(f_decl); |
117 function_param_iterator_c fp_iterator(f_decl); |
113 function_call_param_iterator_c fcp_iterator(f_call); |
118 function_call_param_iterator_c fcp_iterator(f_call); |
114 int extensible_parameter_highest_index = -1; |
119 int extensible_parameter_highest_index = -1; |
115 identifier_c *extensible_parameter_name; |
120 identifier_c *extensible_parameter_name; |
116 unsigned int i; |
121 unsigned int i; |
117 |
122 |
|
123 if (NULL != ext_parm_count) *ext_parm_count = -1; |
118 |
124 |
119 /* Iterating through the formal parameters of the function call */ |
125 /* Iterating through the formal parameters of the function call */ |
120 while((call_param_name = fcp_iterator.next_f()) != NULL) { |
126 while((call_param_name = fcp_iterator.next_f()) != NULL) { |
121 |
127 |
122 /* Obtaining the value being passed in the function call */ |
128 /* Obtaining the value being passed in the function call */ |
125 if (NULL == call_param_value) ERROR; |
131 if (NULL == call_param_value) ERROR; |
126 |
132 |
127 /* Find the corresponding parameter in function declaration */ |
133 /* Find the corresponding parameter in function declaration */ |
128 param_name = fp_iterator.search(call_param_name); |
134 param_name = fp_iterator.search(call_param_name); |
129 |
135 |
130 /* Get the parameter type */ |
136 /* Set the desired datatype for this parameter, and call it recursively. */ |
131 call_param_name->datatype = base_type(fp_iterator.param_type()); |
137 call_param_name->datatype = base_type(fp_iterator.param_type()); |
132 call_param_name->accept(*this); |
138 call_param_name->accept(*this); |
133 /* the first parameter (il_def_variable) is correct */ |
139 |
134 if (extensible_parameter_highest_index < fp_iterator.extensible_param_index()) { |
140 if (extensible_parameter_highest_index < fp_iterator.extensible_param_index()) |
135 extensible_parameter_highest_index = fp_iterator.extensible_param_index(); |
141 extensible_parameter_highest_index = fp_iterator.extensible_param_index(); |
136 } |
142 } |
137 } |
143 /* call is compatible! */ |
138 /* The function call may not have any errors! */ |
144 |
139 /* In the case of a call to an extensible function, we store the highest index |
145 /* In the case of a call to an extensible function, we store the highest index |
140 * of the extensible parameters this particular call uses, in the symbol_c object |
146 * of the extensible parameters this particular call uses, in the symbol_c object |
141 * of the function call itself! |
147 * of the function call itself! |
142 * In calls to non-extensible functions, this value will be set to -1. |
148 * In calls to non-extensible functions, this value will be set to -1. |
143 * This information is later used in stage4 to correctly generate the |
149 * This information is later used in stage4 to correctly generate the |
144 * output code. |
150 * output code. |
145 */ |
151 */ |
146 int extensible_param_count = -1; |
152 if ((NULL != ext_parm_count) && (extensible_parameter_highest_index >=0) /* if call to extensible function */) |
147 if (extensible_parameter_highest_index >=0) /* if call to extensible function */ |
153 *ext_parm_count = 1 + extensible_parameter_highest_index - fp_iterator.first_extensible_param_index(); |
148 extensible_param_count = 1 + extensible_parameter_highest_index - fp_iterator.first_extensible_param_index(); |
154 } |
149 function_invocation_c *function_invocation = dynamic_cast<function_invocation_c *>(f_call); |
155 |
150 if (function_invocation != NULL) function_invocation->extensible_param_count = extensible_param_count; |
156 |
151 } |
|
152 |
157 |
153 /* a helper function... */ |
158 /* a helper function... */ |
154 symbol_c *narrow_candidate_datatypes_c::base_type(symbol_c *symbol) { |
159 symbol_c *narrow_candidate_datatypes_c::base_type(symbol_c *symbol) { |
155 /* NOTE: symbol == NULL is valid. It will occur when, for e.g., an undefined/undeclared symbolic_variable is used |
160 /* NOTE: symbol == NULL is valid. It will occur when, for e.g., an undefined/undeclared symbolic_variable is used |
156 * in the code. |
161 * in the code. |
984 return NULL; |
989 return NULL; |
985 } |
990 } |
986 |
991 |
987 |
992 |
988 void *narrow_candidate_datatypes_c::visit(function_invocation_c *symbol) { |
993 void *narrow_candidate_datatypes_c::visit(function_invocation_c *symbol) { |
989 function_declaration_c *f_decl; |
994 int ext_parm_count; |
990 list_c *parameter_list; |
995 |
991 list_c *parameter_candidate_datatypes; |
996 /* set the called_function_declaration taking into account the datatype that we need to return */ |
992 function_symtable_t::iterator lower = function_symtable.lower_bound(symbol->function_name); |
997 symbol->called_function_declaration = NULL; |
993 function_symtable_t::iterator upper = function_symtable.upper_bound(symbol->function_name); |
998 for(unsigned int i = 0; i < symbol->candidate_datatypes.size(); i++) { |
994 |
999 if (is_type_equal(symbol->candidate_datatypes[i], symbol->datatype)) { |
995 if (NULL != symbol->formal_param_list) |
1000 symbol->called_function_declaration = symbol->candidate_functions[i]; |
996 parameter_list = (list_c *)symbol->formal_param_list; |
1001 break; |
997 else if (NULL != symbol->nonformal_param_list) |
1002 } |
998 parameter_list = (list_c *)symbol->nonformal_param_list; |
1003 } |
999 else ERROR; |
1004 if (NULL == symbol->called_function_declaration) ERROR; |
1000 for(; lower != upper; lower++) { |
1005 |
1001 f_decl = function_symtable.get_value(lower); |
1006 if (NULL != symbol->nonformal_param_list) narrow_nonformal_call(symbol, symbol->called_function_declaration, &ext_parm_count); |
1002 symbol_c * return_type = base_type(f_decl->type_name); |
1007 if (NULL != symbol-> formal_param_list) narrow_formal_call(symbol, symbol->called_function_declaration, &ext_parm_count); |
1003 if (return_type && typeid(*symbol->datatype) != typeid(*return_type)) |
1008 symbol->extensible_param_count = ext_parm_count; |
1004 continue; |
|
1005 /* We set which function declaration it'll use in STAGE4 */ |
|
1006 symbol->called_function_declaration = f_decl; |
|
1007 /* Check if function declaration in symbol_table is compatible with parameters */ |
|
1008 if (NULL != symbol->nonformal_param_list) |
|
1009 /* nonformal parameter function call */ |
|
1010 narrow_nonformal_call(symbol, f_decl); |
|
1011 else |
|
1012 /* formal parameter function call */ |
|
1013 narrow_formal_call (symbol, f_decl); |
|
1014 break; |
|
1015 } |
|
1016 |
1009 |
1017 return NULL; |
1010 return NULL; |
1018 } |
1011 } |
1019 |
1012 |
1020 /********************/ |
1013 /********************/ |