stage3/narrow_candidate_datatypes.cc
changeset 838 13ea7c080018
parent 836 149398f525a7
child 839 99d9ef4d210b
equal deleted inserted replaced
837:e0184feaebd2 838:13ea7c080018
  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);