1168 /*********************/ |
1168 /*********************/ |
1169 /* B 1.4 - Variables */ |
1169 /* B 1.4 - Variables */ |
1170 /*********************/ |
1170 /*********************/ |
1171 void *fill_candidate_datatypes_c::visit(symbolic_variable_c *symbol) { |
1171 void *fill_candidate_datatypes_c::visit(symbolic_variable_c *symbol) { |
1172 symbol->scope = current_scope; // the scope in which this variable was declared! |
1172 symbol->scope = current_scope; // the scope in which this variable was declared! |
1173 /* NOTE: We need to fully determine the datatype of each element in the structured_variable inside this fill_candidate_datatypes class! |
1173 add_datatype_to_candidate_list(symbol, search_var_instance_decl->get_basetype_decl(symbol)); /* will only add if non NULL */ |
1174 * Basically, for variables (be they symbolic_variable, structured_variable, array_variable), we do the narrow algorithm |
|
1175 * in this fill_candidate_datatypes_c itself! |
|
1176 * This is needed because we need to know in which scope (i.e. the datatype of the record_variable in a structtured_variable_c) |
|
1177 * we will search for the field_variable of the structured_variable_c. Similarly, it is also used to determine the datatype |
|
1178 * to which a REF_TO variable points to. |
|
1179 */ |
|
1180 symbol->datatype = search_var_instance_decl->get_basetype_decl(symbol); // Do the narrow algorithm in this fill_candidate_datatypes_c!! |
|
1181 add_datatype_to_candidate_list(symbol, symbol->datatype); /* will only add if non NULL */ |
|
1182 if (debug) std::cout << "VAR [" << symbol->candidate_datatypes.size() << "]\n"; |
1174 if (debug) std::cout << "VAR [" << symbol->candidate_datatypes.size() << "]\n"; |
1183 return NULL; |
1175 return NULL; |
1184 } |
1176 } |
1185 |
1177 |
1186 |
1178 |
1233 symbol->subscripted_variable->accept(*this); |
1225 symbol->subscripted_variable->accept(*this); |
1234 // the scope in which this variable was declared! It will be the same as the subscripted variable (a symbolic_variable_ !) |
1226 // the scope in which this variable was declared! It will be the same as the subscripted variable (a symbolic_variable_ !) |
1235 symbol->scope = symbol->subscripted_variable->scope; |
1227 symbol->scope = symbol->subscripted_variable->scope; |
1236 if (NULL == symbol->scope) ERROR; |
1228 if (NULL == symbol->scope) ERROR; |
1237 |
1229 |
1238 /* get the declaration of the data type __stored__ in the array... */ |
1230 |
1239 add_datatype_to_candidate_list(symbol, search_base_type_c::get_basetype_decl(get_datatype_info_c::get_array_storedtype_id(symbol->subscripted_variable->datatype))); /* will only add if non NULL */ |
1231 for (unsigned int i = 0; i < symbol->subscripted_variable->candidate_datatypes.size(); i++) { |
1240 |
1232 /* get the declaration of the data type __stored__ in the array... */ |
1241 /* NOTE: We need to fully determine the datatype of each element in the structured_variable inside this fill_candidate_datatypes class! |
1233 add_datatype_to_candidate_list(symbol, search_base_type_c::get_basetype_decl(get_datatype_info_c::get_array_storedtype_id(symbol->subscripted_variable->candidate_datatypes[i]))); /* will only add if non NULL */ |
1242 * Basically, for variables (be they symbolic_variable, structured_variable, array_variable), we do the narrow algorithm |
1234 } |
1243 * in this fill_candidate_datatypes_c itself! |
|
1244 * This is needed because we need to know in which scope (i.e. the datatype of the record_variable in a structtured_variable_c) |
|
1245 * we will search for the field_variable of the structured_variable_c. Similarly, it is also used to determine the datatype |
|
1246 * to which a REF_TO variable points to. |
|
1247 */ |
|
1248 if (symbol->candidate_datatypes.size() == 1) |
|
1249 // narrow the symbol->datatype for this array_variable as explained above! |
|
1250 symbol->datatype = symbol->candidate_datatypes[0]; |
|
1251 |
1235 |
1252 /* recursively call the subscript list, so we can check the data types of the expressions used for the subscripts */ |
1236 /* recursively call the subscript list, so we can check the data types of the expressions used for the subscripts */ |
1253 symbol->subscript_list->accept(*this); |
1237 symbol->subscript_list->accept(*this); |
1254 |
1238 |
1255 if (debug) std::cout << "ARRAY_VAR [" << symbol->candidate_datatypes.size() << "]\n"; |
1239 if (debug) std::cout << "ARRAY_VAR [" << symbol->candidate_datatypes.size() << "]\n"; |
1275 * The array subscripts may contain a complex expression (e.g. arrayvar[ varx + 33].elem1) whose datatype must be correctly determined! |
1259 * The array subscripts may contain a complex expression (e.g. arrayvar[ varx + 33].elem1) whose datatype must be correctly determined! |
1276 * The expression, may even contain a function call to an overloaded function! |
1260 * The expression, may even contain a function call to an overloaded function! |
1277 * (e.g. arrayvar[ varx + TRUNC(realvar)].elem1) |
1261 * (e.g. arrayvar[ varx + TRUNC(realvar)].elem1) |
1278 */ |
1262 */ |
1279 symbol->record_variable->accept(*this); |
1263 symbol->record_variable->accept(*this); |
1280 symbol->scope = symbol->record_variable->datatype; // the scope in which this variable was declared! Will be used in stage4 |
1264 |
1281 |
1265 if (symbol->record_variable->candidate_datatypes.size() == 1) { |
1282 /* NOTE: We need to fully determine the datatype of each element in the structured_variable inside this fill_candidate_datatypes class! |
1266 // set the scope in which this variable is declared (will be a struct datatype declaration!) |
1283 * Basically, for variables (be they symbolic_variable, structured_variable, array_variable), we do the narrow algorithm |
1267 // We rely on the fact that if only one candidate datatype exists, then it will be the scope in which the field_variable is declared! |
1284 * in this fill_candidate_datatypes_c itself! |
1268 symbol->scope = symbol->record_variable->candidate_datatypes[0]; // the scope in which this variable was declared! Will be used in stage4 |
1285 * This is needed because we need to know in which scope (i.e. the datatype of the record_variable in a structtured_variable_c) |
1269 // Determine candidate datatypes... |
1286 * we will search for the field_variable of the structured_variable_c. Similarly, it is also used to determine the datatype |
1270 add_datatype_to_candidate_list(symbol, search_base_type_c::get_basetype_decl(get_datatype_info_c::get_struct_field_type_id(symbol->scope, symbol->field_selector))); /* will only add if non NULL */ |
1287 * to which a REF_TO variable points to. |
1271 } |
1288 */ |
1272 |
1289 if (NULL != symbol->record_variable->datatype) |
1273 return NULL; |
1290 // We relly on the fact that we have already narrowed the symbol->datatype for the record variable, and use it as the scope in which the filed_variable is declared! |
|
1291 add_datatype_to_candidate_list(symbol, search_base_type_c::get_basetype_decl(get_datatype_info_c::get_struct_field_type_id(symbol->record_variable->datatype, symbol->field_selector))); /* will only add if non NULL */ |
|
1292 if (symbol->candidate_datatypes.size() == 1) |
|
1293 // narrow the symbol->datatype for this strcutured_variable as explained above! |
|
1294 symbol->datatype = symbol->candidate_datatypes[0]; |
|
1295 return NULL; |
|
1296 } |
1274 } |
1297 |
1275 |
1298 |
1276 |
1299 |
1277 |
1300 /******************************************/ |
1278 /******************************************/ |
2043 if (NULL != ref_spec) |
2021 if (NULL != ref_spec) |
2044 add_datatype_to_candidate_list(symbol, search_base_type_c::get_basetype_decl(ref_spec->type_name)); |
2022 add_datatype_to_candidate_list(symbol, search_base_type_c::get_basetype_decl(ref_spec->type_name)); |
2045 |
2023 |
2046 } |
2024 } |
2047 |
2025 |
2048 /* NOTE: We need to fully determine the datatype of each element in the structured_variable inside this fill_candidate_datatypes class! |
2026 /* Since the deref_operator_c may be used inside structures, we must handle set the 'scope' annotation here too! */ |
2049 * Basically, for variables (be they symbolic_variable, structured_variable, array_variable), we do the narrow algorithm |
|
2050 * in this fill_candidate_datatypes_c itself! |
|
2051 * This is needed because we need to know in which scope (i.e. the datatype of the record_variable in a structtured_variable_c) |
|
2052 * we will search for the field_variable of the structured_variable_c. Similarly, it is also used to determine the datatype |
|
2053 * to which a REF_TO variable points to. |
|
2054 * |
|
2055 * Since the deref_operator_c may be used inside structures, we must narrow it here, if possible! |
|
2056 */ |
|
2057 if (symbol->candidate_datatypes.size() == 1) |
|
2058 // narrow the symbol->datatype for this symbol as explained above! |
|
2059 symbol->datatype = symbol->candidate_datatypes[0]; |
|
2060 |
|
2061 /* Since the deref_operator_c may be used inside structures, we must handle set the 'scope' annotation here too! */ |
|
2062 symbol->scope = symbol->exp->scope; |
2027 symbol->scope = symbol->exp->scope; |
2063 |
2028 |
2064 return NULL; |
2029 return NULL; |
2065 } |
2030 } |
2066 |
2031 |
2067 |
2032 |
2068 /* SYM_REF1(ref_expression_c, exp) --> an extension to the IEC 61131-3 standard - based on the IEC 61131-3 v3 standard. Returns address of the varible! */ |
2033 /* SYM_REF1(ref_expression_c, exp) --> an extension to the IEC 61131-3 standard - based on the IEC 61131-3 v3 standard. Returns address of the varible! */ |
2069 void *fill_candidate_datatypes_c::visit( ref_expression_c *symbol) { |
2034 void *fill_candidate_datatypes_c::visit( ref_expression_c *symbol) { |
2070 /* We must first determine the datatype of the expression passed to the REF() operator, with no ambiguities! |
2035 /* |
2071 * To do this, we could use the complete standard fill/narrow algorithm for determining the datatype |
2036 * Note that symbol->exp may be an array variable, and these may containg complex |
2072 * of the expression. This is actually possible, as nothing stops us from directly calling the narrow_candidate_datatypes_c |
2037 * expressions that include function calls in their indexes. These complex expressions must also be |
2073 * from this method inside fill_candidate_datatypes_c, to complete the fill/narrow algorithm on this |
|
2074 * expression only. |
|
2075 * However, for the moment we take a shortcut, and set the expression's "datatype" directly, even though this |
|
2076 * should really only be done in narrow_candidate_datatypes_c. This is possible because the expression should be |
|
2077 * an lvalue (assuming source code has no bugs), with only one candidate datatype. |
|
2078 * |
|
2079 * (We should really check whether the expression is an lvalue. For now, leave it for the future!) |
|
2080 * |
|
2081 * Note, however, that array variables are also lvalues, and they may containg complex |
|
2082 * expressions that include function calls in their indexes. These complex expressions must therefore still be |
|
2083 * analysed using the standard fill/narrow algorithm... |
2038 * analysed using the standard fill/narrow algorithm... |
2084 */ |
2039 */ |
2085 symbol->exp->accept(*this); |
2040 symbol->exp->accept(*this); |
2086 if (symbol->exp->candidate_datatypes.size() == 1) |
2041 |
2087 symbol->exp->datatype = symbol->exp->candidate_datatypes[0]; |
2042 /* Currently the IEC 61131-3 symtax requires that the REF() operator have as a parameter a lvalue (a variable), that will have |
2088 |
2043 * at most one candidate_datatype. This means that we do not really need the for() loop here, but we use it |
2089 /* Create a new object of ref_spec_c, as this is the class used as the */ |
2044 * anyway as it is the correct way of implementing the fill/narrow algorithm! |
2090 /* canonical/base datatype of REF_TO types (see search_base_type_c ...) */ |
2045 */ |
2091 ref_spec_c *ref_spec = new ref_spec_c(symbol->exp->datatype); |
2046 for (unsigned int i = 0; i < symbol->exp->candidate_datatypes.size(); i++) { |
2092 add_datatype_to_candidate_list(symbol, ref_spec); |
2047 /* Create a new object of ref_spec_c, as this is the class used as the */ |
|
2048 /* canonical/base datatype of REF_TO types (see search_base_type_c ...) */ |
|
2049 ref_spec_c *ref_spec = new ref_spec_c(symbol->exp->candidate_datatypes[i]); |
|
2050 add_datatype_to_candidate_list(symbol, ref_spec); |
|
2051 } |
2093 return NULL; |
2052 return NULL; |
2094 } |
2053 } |
2095 |
2054 |
2096 void *fill_candidate_datatypes_c::visit( or_expression_c *symbol) {return handle_binary_expression (widen_OR_table, symbol, symbol->l_exp, symbol->r_exp);} |
2055 void *fill_candidate_datatypes_c::visit( or_expression_c *symbol) {return handle_binary_expression (widen_OR_table, symbol, symbol->l_exp, symbol->r_exp);} |
2097 void *fill_candidate_datatypes_c::visit( xor_expression_c *symbol) {return handle_binary_expression (widen_XOR_table, symbol, symbol->l_exp, symbol->r_exp);} |
2056 void *fill_candidate_datatypes_c::visit( xor_expression_c *symbol) {return handle_binary_expression (widen_XOR_table, symbol, symbol->l_exp, symbol->r_exp);} |