1100 |
1100 |
1101 /* If il_operand already has a non-NULL datatype (remember, narrow algorithm runs twice over IL lists!), |
1101 /* If il_operand already has a non-NULL datatype (remember, narrow algorithm runs twice over IL lists!), |
1102 * but narrow algorithm has not yet been able to determine what datatype it should take? This is strange, |
1102 * but narrow algorithm has not yet been able to determine what datatype it should take? This is strange, |
1103 * and most probably an error! |
1103 * and most probably an error! |
1104 */ |
1104 */ |
1105 if ((NULL != il_operand->datatype) && (NULL == datatype)) |
1105 if ((NULL != il_operand->datatype) && (NULL == datatype)) ERROR; |
1106 ERROR; |
|
1107 |
1106 |
1108 /* If the il_operand's datatype has already been set previously, and |
1107 /* If the il_operand's datatype has already been set previously, and |
1109 * the narrow algorithm has already determined the datatype the il_operand should take! |
1108 * the narrow algorithm has already determined the datatype the il_operand should take! |
1110 * ...we just make sure that the new datatype is the same as the current il_operand's datatype |
1109 * ...we just make sure that the new datatype is the same as the current il_operand's datatype |
1111 */ |
1110 */ |
1112 if ((NULL != il_operand->datatype) && (NULL != datatype)) { |
1111 if ((NULL != il_operand->datatype) && (NULL != datatype)) { |
1113 /* Only one of the two datatypes is an invalid_type_name_c? This implies they are diferent!! */ |
1112 /* Both datatypes are an invalid_type_name_c. This implies they are the same!! */ |
1114 if ((!get_datatype_info_c::is_type_valid(datatype)) ^ ((!get_datatype_info_c::is_type_valid(il_operand->datatype)))) ERROR; |
1113 if ((!get_datatype_info_c::is_type_valid(datatype)) && ((!get_datatype_info_c::is_type_valid(il_operand->datatype)))) |
|
1114 return NULL;; |
1115 /* OK, so both the datatypes are valid, but are they equal? */ |
1115 /* OK, so both the datatypes are valid, but are they equal? */ |
1116 if ( !get_datatype_info_c::is_type_equal(il_operand->datatype, datatype)) ERROR; |
1116 if ( !get_datatype_info_c::is_type_equal(il_operand->datatype, datatype)) |
|
1117 ERROR; |
1117 /* The datatypes are the same. We have nothing to do, so we simply return! */ |
1118 /* The datatypes are the same. We have nothing to do, so we simply return! */ |
1118 return NULL; |
1119 return NULL; |
1119 } |
1120 } |
1120 |
1121 |
1121 /* Set the il_operand's datatype. Note that the new 'datatype' may even be NULL!!! */ |
1122 /* Set the il_operand's datatype. Note that the new 'datatype' may even be NULL!!! */ |
1182 } |
1183 } |
1183 |
1184 |
1184 |
1185 |
1185 |
1186 |
1186 |
1187 |
1187 |
1188 /* Narrow IL operators whose execution is conditional on the boolean value in the accumulator. |
1188 void *narrow_candidate_datatypes_c::handle_il_instruction(symbol_c *symbol) { |
1189 * Basically, narrow the JMPC, JMPCN, RETC, RETCN, CALC, and CALCN operators! |
1189 /* |
1190 * Also does part of the S and R operator narrowing!!! |
1190 * NOTE 2: We do not need to call prev_il_instruction->accept(*this), as the object to which prev_il_instruction |
1191 */ |
1191 * is pointing to will be later narrowed by the call from the for() loop of the instruction_list_c |
1192 void *narrow_candidate_datatypes_c::narrow_conditional_operator(symbol_c *symbol) { |
1192 * (or simple_instr_list_c), which iterates backwards. |
1193 /* if the next IL instructions needs us to provide a datatype other than a BOOL or a SAFEBOOL, |
1193 */ |
1194 * then we have an internal compiler error - most likely in fill_candidate_datatypes_c |
1194 if (NULL != symbol->datatype) // next IL instructions were able to determine the datatype this instruction should produce |
1195 */ |
1195 /* set the desired datatype of the previous il instruction */ |
1196 // I (mario) am confident the fill/narrow algorithms are working correctly, so for now we can disable the assertions! |
1196 set_datatype_in_prev_il_instructions(symbol->datatype, fake_prev_il_instruction); |
1197 //if ((NULL != symbol->datatype) && (!get_datatype_info_c::is_BOOL_compatible(symbol->datatype))) ERROR; |
1197 |
1198 //if (symbol->candidate_datatypes.size() > 2) ERROR; /* may contain, at most, a BOOL and a SAFEBOOL */ |
1198 /* set the datatype for the operand */ |
1199 |
1199 set_il_operand_datatype(il_operand, symbol->datatype); |
1200 /* NOTE: If there is no IL instruction following this S, R, CALC, CALCN, JMPC, JMPCN, RETC, or RETCN instruction, |
|
1201 * we must still provide a bool_type_name_c datatype (if possible, i.e. if it exists in the candidate datatype list). |
|
1202 * If it is not possible, we set it to NULL |
|
1203 * |
|
1204 * NOTE: Note that this algorithm we are implementing is slightly wrong. |
|
1205 * (a) It ignores that a SAFEBOOL may be needed instead of a BOOL datatype. |
|
1206 * (b) It also ignores that this method gets to be called twice on the same |
|
1207 * object (the narrow algorithm runs through the IL list twice in order to |
|
1208 * handle forward JMPs), so the assumption that we must immediately set our |
|
1209 * own datatype if we get called with a NULL symbol->datatype is incorrect |
|
1210 * (it may be that the second time it is called it will be with the correct datatype!). |
|
1211 * |
|
1212 * These two issues (a) and (b) together means that we should only really be setting our own |
|
1213 * datatype if we are certain that the following IL instructions will never set it for us |
|
1214 * - basically if the following IL instruction is a LD, or a JMP to a LD, or a JMP to a JMP to a LD, |
|
1215 * etc..., or a conditional JMP whose both branches go to LD, etc...!!! |
|
1216 * |
|
1217 * At the moment, it seems to me that we would need to write a visitor class to do this for us! |
|
1218 * I currently have other things on my mind at the moment, so I will leave this for later... |
|
1219 * For the moment we just set it to BOOL, and ignore the support of SAFEBOOL! |
|
1220 */ |
|
1221 if (NULL == symbol->datatype) set_datatype(&get_datatype_info_c::bool_type_name /* datatype*/, symbol /* symbol */); |
|
1222 if (NULL == symbol->datatype) ERROR; // the BOOL is not on the candidate_datatypes! Strange... Probably a bug in fill_candidate_datatype_c |
|
1223 |
|
1224 /* set the required datatype of the previous IL instruction, i.e. a bool_type_name_c! */ |
|
1225 set_datatype_in_prev_il_instructions(symbol->datatype, fake_prev_il_instruction); |
|
1226 return NULL; |
|
1227 } |
|
1228 |
|
1229 |
|
1230 |
|
1231 void *narrow_candidate_datatypes_c::narrow_S_and_R_operator(symbol_c *symbol, const char *param_name, symbol_c *called_fb_declaration) { |
|
1232 if (NULL != called_fb_declaration) |
|
1233 /* FB call semantics */ |
|
1234 return narrow_implicit_il_fb_call(symbol, param_name, called_fb_declaration); |
|
1235 |
|
1236 /* Set/Reset semantics */ |
|
1237 narrow_conditional_operator(symbol); |
|
1238 /* set the datatype for the il_operand */ |
|
1239 if ((NULL != il_operand) && (il_operand->candidate_datatypes.size() > 0)) |
|
1240 set_il_operand_datatype(il_operand, il_operand->candidate_datatypes[0]); |
1200 return NULL; |
1241 return NULL; |
1201 } |
1242 } |
1202 |
1243 |
1203 |
1244 |
1204 |
1245 |
1236 /* set the datatype for the operand */ |
1277 /* set the datatype for the operand */ |
1237 set_il_operand_datatype(il_operand, symbol->datatype); |
1278 set_il_operand_datatype(il_operand, symbol->datatype); |
1238 return NULL; |
1279 return NULL; |
1239 } |
1280 } |
1240 |
1281 |
1241 void *narrow_candidate_datatypes_c::visit(NOT_operator_c *symbol) { |
1282 |
1242 /* NOTE: the standard allows syntax in which the NOT operator is followed by an optional <il_operand> |
1283 |
1243 * NOT [<il_operand>] |
1284 /* NOTE: the standard allows syntax in which the NOT operator is followed by an optional <il_operand> |
1244 * However, it does not define the semantic of the NOT operation when the <il_operand> is specified. |
1285 * NOT [<il_operand>] |
1245 * We therefore consider it an error if an il_operand is specified! |
1286 * However, it does not define the semantic of the NOT operation when the <il_operand> is specified. |
1246 * This error will be detected in print_datatypes_error_c!! |
1287 * We therefore consider it an error if an il_operand is specified! |
1247 */ |
1288 * This error will be detected in print_datatypes_error_c!! |
1248 /* This operator does not change the data type, it simply inverts the bits in the ANT_BIT data types! */ |
1289 */ |
1249 /* So, we set the desired datatype of the previous il instruction */ |
1290 /* This operator does not change the data type, it simply inverts the bits in the ANT_BIT data types! */ |
1250 set_datatype_in_prev_il_instructions(symbol->datatype, fake_prev_il_instruction); |
1291 /* So, we merely set the desired datatype of the previous il instruction */ |
1251 return NULL; |
1292 void *narrow_candidate_datatypes_c::visit( NOT_operator_c *symbol) {set_datatype_in_prev_il_instructions(symbol->datatype, fake_prev_il_instruction);return NULL;} |
1252 } |
1293 |
1253 |
1294 void *narrow_candidate_datatypes_c::visit( S_operator_c *symbol) {return narrow_S_and_R_operator (symbol, "S", symbol->called_fb_declaration);} |
1254 void *narrow_candidate_datatypes_c::visit(S_operator_c *symbol) { |
1295 void *narrow_candidate_datatypes_c::visit( R_operator_c *symbol) {return narrow_S_and_R_operator (symbol, "R", symbol->called_fb_declaration);} |
1255 if (NULL != symbol->called_fb_declaration) /* FB call semantics */ return narrow_implicit_il_fb_call(symbol, "S", symbol->called_fb_declaration); |
|
1256 else /* Reset semantics */ return handle_il_instruction(symbol); |
|
1257 } |
|
1258 |
|
1259 void *narrow_candidate_datatypes_c::visit(R_operator_c *symbol) { |
|
1260 if (NULL != symbol->called_fb_declaration) /* FB call semantics */ return narrow_implicit_il_fb_call(symbol, "R", symbol->called_fb_declaration); |
|
1261 else /* Reset semantics */ return handle_il_instruction(symbol); |
|
1262 } |
|
1263 |
1296 |
1264 void *narrow_candidate_datatypes_c::visit( S1_operator_c *symbol) {return narrow_implicit_il_fb_call(symbol, "S1", symbol->called_fb_declaration);} |
1297 void *narrow_candidate_datatypes_c::visit( S1_operator_c *symbol) {return narrow_implicit_il_fb_call(symbol, "S1", symbol->called_fb_declaration);} |
1265 void *narrow_candidate_datatypes_c::visit( R1_operator_c *symbol) {return narrow_implicit_il_fb_call(symbol, "R1", symbol->called_fb_declaration);} |
1298 void *narrow_candidate_datatypes_c::visit( R1_operator_c *symbol) {return narrow_implicit_il_fb_call(symbol, "R1", symbol->called_fb_declaration);} |
1266 void *narrow_candidate_datatypes_c::visit( CLK_operator_c *symbol) {return narrow_implicit_il_fb_call(symbol, "CLK", symbol->called_fb_declaration);} |
1299 void *narrow_candidate_datatypes_c::visit( CLK_operator_c *symbol) {return narrow_implicit_il_fb_call(symbol, "CLK", symbol->called_fb_declaration);} |
1267 void *narrow_candidate_datatypes_c::visit( CU_operator_c *symbol) {return narrow_implicit_il_fb_call(symbol, "CU", symbol->called_fb_declaration);} |
1300 void *narrow_candidate_datatypes_c::visit( CU_operator_c *symbol) {return narrow_implicit_il_fb_call(symbol, "CU", symbol->called_fb_declaration);} |
1287 void *narrow_candidate_datatypes_c::visit( LT_operator_c *symbol) {return narrow_binary_operator(widen_CMP_table, symbol);} |
1320 void *narrow_candidate_datatypes_c::visit( LT_operator_c *symbol) {return narrow_binary_operator(widen_CMP_table, symbol);} |
1288 void *narrow_candidate_datatypes_c::visit( LE_operator_c *symbol) {return narrow_binary_operator(widen_CMP_table, symbol);} |
1321 void *narrow_candidate_datatypes_c::visit( LE_operator_c *symbol) {return narrow_binary_operator(widen_CMP_table, symbol);} |
1289 void *narrow_candidate_datatypes_c::visit( NE_operator_c *symbol) {return narrow_binary_operator(widen_CMP_table, symbol);} |
1322 void *narrow_candidate_datatypes_c::visit( NE_operator_c *symbol) {return narrow_binary_operator(widen_CMP_table, symbol);} |
1290 |
1323 |
1291 |
1324 |
1292 |
1325 /* visitors to CAL_operator_c, CALC_operator_c and CALCN_operator_c are called from visit(il_fb_call_c *) {symbol->il_call_operator->accept(*this)} */ |
1293 |
|
1294 void *narrow_candidate_datatypes_c::narrow_conditional_flow_control_IL_instruction(symbol_c *symbol) { |
|
1295 /* if the next IL instructions needs us to provide a datatype other than a bool, |
|
1296 * then we have an internal compiler error - most likely in fill_candidate_datatypes_c |
|
1297 */ |
|
1298 if ((NULL != symbol->datatype) && (!get_datatype_info_c::is_BOOL_compatible(symbol->datatype))) ERROR; |
|
1299 if (symbol->candidate_datatypes.size() > 1) ERROR; |
|
1300 |
|
1301 /* NOTE: If there is no IL instruction following this CALC, CALCN, JMPC, JMPC, ..., instruction, |
|
1302 * we must still provide a bool_type_name_c datatype (if possible, i.e. if it exists in the candidate datatype list). |
|
1303 * If it is not possible, we set it to NULL |
|
1304 */ |
|
1305 if (symbol->candidate_datatypes.size() == 0) symbol->datatype = NULL; |
|
1306 else symbol->datatype = symbol->candidate_datatypes[0]; /* i.e. a bool_type_name_c! */ |
|
1307 if ((NULL != symbol->datatype) && (!get_datatype_info_c::is_BOOL_compatible(symbol->datatype))) ERROR; |
|
1308 |
|
1309 /* set the required datatype of the previous IL instruction, i.e. a bool_type_name_c! */ |
|
1310 set_datatype_in_prev_il_instructions(symbol->datatype, fake_prev_il_instruction); |
|
1311 return NULL; |
|
1312 } |
|
1313 |
|
1314 |
|
1315 // SYM_REF0(CAL_operator_c) |
|
1316 // SYM_REF0(CALC_operator_c) |
|
1317 // SYM_REF0(CALCN_operator_c) |
|
1318 /* called from visit(il_fb_call_c *) {symbol->il_call_operator->accpet(*this)} */ |
|
1319 /* NOTE: The CAL, JMP and RET instructions simply set the desired datatype of the previous il instruction since they do not change the value in the current/default IL variable */ |
1326 /* NOTE: The CAL, JMP and RET instructions simply set the desired datatype of the previous il instruction since they do not change the value in the current/default IL variable */ |
1320 /* called from il_fb_call_c (symbol->il_call_operator->accpet(*this) ) */ |
|
1321 void *narrow_candidate_datatypes_c::visit( CAL_operator_c *symbol) {set_datatype_in_prev_il_instructions(symbol->datatype, fake_prev_il_instruction); return NULL;} |
1327 void *narrow_candidate_datatypes_c::visit( CAL_operator_c *symbol) {set_datatype_in_prev_il_instructions(symbol->datatype, fake_prev_il_instruction); return NULL;} |
1322 void *narrow_candidate_datatypes_c::visit( RET_operator_c *symbol) {set_datatype_in_prev_il_instructions(symbol->datatype, fake_prev_il_instruction); return NULL;} |
1328 void *narrow_candidate_datatypes_c::visit( RET_operator_c *symbol) {set_datatype_in_prev_il_instructions(symbol->datatype, fake_prev_il_instruction); return NULL;} |
1323 void *narrow_candidate_datatypes_c::visit( JMP_operator_c *symbol) {set_datatype_in_prev_il_instructions(symbol->datatype, fake_prev_il_instruction); return NULL;} |
1329 void *narrow_candidate_datatypes_c::visit( JMP_operator_c *symbol) {set_datatype_in_prev_il_instructions(symbol->datatype, fake_prev_il_instruction); return NULL;} |
1324 void *narrow_candidate_datatypes_c::visit( CALC_operator_c *symbol) {return narrow_conditional_flow_control_IL_instruction(symbol);} |
1330 void *narrow_candidate_datatypes_c::visit( CALC_operator_c *symbol) {return narrow_conditional_operator(symbol);} |
1325 void *narrow_candidate_datatypes_c::visit(CALCN_operator_c *symbol) {return narrow_conditional_flow_control_IL_instruction(symbol);} |
1331 void *narrow_candidate_datatypes_c::visit(CALCN_operator_c *symbol) {return narrow_conditional_operator(symbol);} |
1326 void *narrow_candidate_datatypes_c::visit( RETC_operator_c *symbol) {return narrow_conditional_flow_control_IL_instruction(symbol);} |
1332 void *narrow_candidate_datatypes_c::visit( RETC_operator_c *symbol) {return narrow_conditional_operator(symbol);} |
1327 void *narrow_candidate_datatypes_c::visit(RETCN_operator_c *symbol) {return narrow_conditional_flow_control_IL_instruction(symbol);} |
1333 void *narrow_candidate_datatypes_c::visit(RETCN_operator_c *symbol) {return narrow_conditional_operator(symbol);} |
1328 void *narrow_candidate_datatypes_c::visit( JMPC_operator_c *symbol) {return narrow_conditional_flow_control_IL_instruction(symbol);} |
1334 void *narrow_candidate_datatypes_c::visit( JMPC_operator_c *symbol) {return narrow_conditional_operator(symbol);} |
1329 void *narrow_candidate_datatypes_c::visit(JMPCN_operator_c *symbol) {return narrow_conditional_flow_control_IL_instruction(symbol);} |
1335 void *narrow_candidate_datatypes_c::visit(JMPCN_operator_c *symbol) {return narrow_conditional_operator(symbol);} |
1330 |
1336 |
1331 /* Symbol class handled together with function call checks */ |
1337 /* Symbol class handled together with function call checks */ |
1332 // void *visit(il_assign_operator_c *symbol, variable_name); |
1338 // void *visit(il_assign_operator_c *symbol, variable_name); |
1333 /* Symbol class handled together with function call checks */ |
1339 /* Symbol class handled together with function call checks */ |
1334 // void *visit(il_assign_operator_c *symbol, option, variable_name); |
1340 // void *visit(il_assign_operator_c *symbol, option, variable_name); |