stage3/narrow_candidate_datatypes.cc
changeset 849 1f8885ae539a
parent 843 f9a059c24aea
child 854 13d0b67de111
equal deleted inserted replaced
823:c95f42f28b69 849:1f8885ae539a
   320  */
   320  */
   321 void *narrow_candidate_datatypes_c::narrow_implicit_il_fb_call(symbol_c *il_instruction, const char *param_name, symbol_c *&called_fb_declaration) {
   321 void *narrow_candidate_datatypes_c::narrow_implicit_il_fb_call(symbol_c *il_instruction, const char *param_name, symbol_c *&called_fb_declaration) {
   322 
   322 
   323 	/* set the datatype of the il_operand, this is, the FB being called! */
   323 	/* set the datatype of the il_operand, this is, the FB being called! */
   324 	if (NULL != il_operand) {
   324 	if (NULL != il_operand) {
   325 		/* only set it if it is in the candidate datatypes list! */  
   325 		set_datatype(called_fb_declaration, il_operand); /* only set it if it is in the candidate datatypes list! */  
   326 		set_datatype(called_fb_declaration, il_operand);
       
   327 		il_operand->accept(*this);
   326 		il_operand->accept(*this);
   328 	}
   327 	}
   329 	symbol_c *fb_decl = il_operand->datatype;
       
   330 
   328 
   331 	if (0 == fake_prev_il_instruction->prev_il_instruction.size()) {
   329 	if (0 == fake_prev_il_instruction->prev_il_instruction.size()) {
   332 		/* This IL implicit FB call (e.g. CLK ton_var) is not preceded by another IL instruction
   330 		/* This IL implicit FB call (e.g. CLK ton_var) is not preceded by another IL instruction
   333 		 * (or list of instructions) that will set the IL current/default value.
   331 		 * (or list of instructions) that will set the IL current/default value.
   334 		 * We cannot proceed verifying type compatibility of something that does not exist.
   332 		 * We cannot proceed verifying type compatibility of something that does not exist.
   335 		 */
   333 		 */
   336 		return NULL;
   334 		return NULL;
   337 	}
   335 	}
   338 
   336 
       
   337 	symbol_c *fb_decl = (NULL == il_operand)? NULL : il_operand->datatype;
       
   338 	
   339 	if (NULL == fb_decl) {
   339 	if (NULL == fb_decl) {
   340 		/* the il_operand is a not FB instance */
   340 		/* the il_operand is a not FB instance, or it simply does not even exist, */
   341 		/* so we simply pass on the required datatype to the prev_il_instructions */
   341 		/* so we simply pass on the required datatype to the prev_il_instructions */
   342 		/* The invalid FB invocation will be caught in the print_datatypes_error_c by analysing NULL value in il_operand->datatype! */
   342 		/* The invalid FB invocation will be caught in the print_datatypes_error_c by analysing NULL value in il_operand->datatype! */
   343 		set_datatype_in_prev_il_instructions(il_instruction->datatype, fake_prev_il_instruction);
   343 		set_datatype_in_prev_il_instructions(il_instruction->datatype, fake_prev_il_instruction);
   344 		return NULL;
   344 		return NULL;
   345 	}
   345 	}
   647 
   647 
   648 
   648 
   649 /*********************/
   649 /*********************/
   650 /* B 1.4 - Variables */
   650 /* B 1.4 - Variables */
   651 /*********************/
   651 /*********************/
   652 
   652 // SYM_REF1(symbolic_variable_c, var_name)
       
   653 void *narrow_candidate_datatypes_c::visit(symbolic_variable_c *symbol) {
       
   654 	symbol->var_name->datatype = symbol->datatype;
       
   655 	return NULL;
       
   656 }
   653 /********************************************/
   657 /********************************************/
   654 /* B 1.4.1 - Directly Represented Variables */
   658 /* B 1.4.1 - Directly Represented Variables */
   655 /********************************************/
   659 /********************************************/
   656 
   660 
   657 /*************************************/
   661 /*************************************/
   660 /*  subscripted_variable '[' subscript_list ']' */
   664 /*  subscripted_variable '[' subscript_list ']' */
   661 // SYM_REF2(array_variable_c, subscripted_variable, subscript_list)
   665 // SYM_REF2(array_variable_c, subscripted_variable, subscript_list)
   662 void *narrow_candidate_datatypes_c::visit(array_variable_c *symbol) {
   666 void *narrow_candidate_datatypes_c::visit(array_variable_c *symbol) {
   663 	/* we need to check the data types of the expressions used for the subscripts... */
   667 	/* we need to check the data types of the expressions used for the subscripts... */
   664 	symbol->subscript_list->accept(*this);
   668 	symbol->subscript_list->accept(*this);
       
   669 
       
   670 	/* Set the datatype of the subscripted variable and visit it recursively. For the reason why we do this,                                                 */
       
   671 	/* Please read the comments in the array_variable_c and structured_variable_c visitors in the fill_candidate_datatypes.cc file! */
       
   672 	symbol->subscripted_variable->accept(*this); // visit recursively
       
   673 
       
   674 	if (symbol->subscripted_variable->candidate_datatypes.size() == 1)
       
   675 	  symbol->subscripted_variable->datatype = symbol->subscripted_variable->candidate_datatypes[0]; // set the datatype
       
   676 
   665 	return NULL;
   677 	return NULL;
   666 }
   678 }
   667 
   679 
   668 
   680 
   669 /* subscript_list ',' subscript */
   681 /* subscript_list ',' subscript */
   678 	}
   690 	}
   679 	return NULL;  
   691 	return NULL;  
   680 }
   692 }
   681 
   693 
   682 
   694 
       
   695 
       
   696 /*  record_variable '.' field_selector */
       
   697 /*  WARNING: input and/or output variables of function blocks
       
   698  *           may be accessed as fields of a structured variable!
       
   699  *           Code handling a structured_variable_c must take
       
   700  *           this into account!
       
   701  */
       
   702 // SYM_REF2(structured_variable_c, record_variable, field_selector)
       
   703 void *narrow_candidate_datatypes_c::visit(structured_variable_c *symbol) {
       
   704 	/* Set the datatype of the record_variable and visit it recursively. For the reason why we do this,                                                      */
       
   705 	/* Please read the comments in the array_variable_c and structured_variable_c visitors in the fill_candidate_datatypes.cc file! */
       
   706 	symbol->record_variable->accept(*this); // visit recursively
       
   707 
       
   708 	if (symbol->record_variable->candidate_datatypes.size() == 1)
       
   709 	  symbol->record_variable->datatype = symbol->record_variable->candidate_datatypes[0]; // set the datatype
       
   710 
       
   711 	return NULL;
       
   712 }
   683 
   713 
   684 
   714 
   685 /******************************************/
   715 /******************************************/
   686 /* B 1.4.3 - Declaration & Initialisation */
   716 /* B 1.4.3 - Declaration & Initialisation */
   687 /******************************************/
   717 /******************************************/
   771 	delete search_varfb_instance_type;
   801 	delete search_varfb_instance_type;
   772 	search_varfb_instance_type = NULL;
   802 	search_varfb_instance_type = NULL;
   773 	return NULL;
   803 	return NULL;
   774 }
   804 }
   775 
   805 
       
   806 /********************************************/
       
   807 /* B 1.6 Sequential function chart elements */
       
   808 /********************************************/
       
   809 
       
   810 void *narrow_candidate_datatypes_c::visit(transition_condition_c *symbol) {
       
   811 	if (symbol->candidate_datatypes.size() != 1)
       
   812 		return NULL;
       
   813 	symbol->datatype = symbol->candidate_datatypes[0];
       
   814 	if (symbol->transition_condition_il != NULL) {
       
   815 		symbol->transition_condition_il->datatype = symbol->datatype;
       
   816 		symbol->transition_condition_il->accept(*this);
       
   817 	}
       
   818 	if (symbol->transition_condition_st != NULL) {
       
   819 		symbol->transition_condition_st->datatype = symbol->datatype;
       
   820 		symbol->transition_condition_st->accept(*this);
       
   821 	}
       
   822 	return NULL;
       
   823 }
   776 
   824 
   777 /********************************/
   825 /********************************/
   778 /* B 1.7 Configuration elements */
   826 /* B 1.7 Configuration elements */
   779 /********************************/
   827 /********************************/
   780 void *narrow_candidate_datatypes_c::visit(configuration_declaration_c *symbol) {
   828 void *narrow_candidate_datatypes_c::visit(configuration_declaration_c *symbol) {
   953  * | il_call_operator prev_declared_fb_name '(' ')'
  1001  * | il_call_operator prev_declared_fb_name '(' ')'
   954  * | il_call_operator prev_declared_fb_name '(' eol_list ')'
  1002  * | il_call_operator prev_declared_fb_name '(' eol_list ')'
   955  * | il_call_operator prev_declared_fb_name '(' il_operand_list ')'
  1003  * | il_call_operator prev_declared_fb_name '(' il_operand_list ')'
   956  * | il_call_operator prev_declared_fb_name '(' eol_list il_param_list ')'
  1004  * | il_call_operator prev_declared_fb_name '(' eol_list il_param_list ')'
   957  */
  1005  */
   958 /* NOTE: The parameter 'called_fb_declaration'is used to pass data between stage 3 and stage4 (although currently it is not used in stage 4 */
  1006 /* NOTE: The parameter 'called_fb_declaration'is used to pass data between stage 3 and stage4 */
   959 // SYM_REF4(il_fb_call_c, il_call_operator, fb_name, il_operand_list, il_param_list, symbol_c *called_fb_declaration)
  1007 // SYM_REF4(il_fb_call_c, il_call_operator, fb_name, il_operand_list, il_param_list, symbol_c *called_fb_declaration)
   960 void *narrow_candidate_datatypes_c::visit(il_fb_call_c *symbol) {
  1008 void *narrow_candidate_datatypes_c::visit(il_fb_call_c *symbol) {
   961 	symbol_c *fb_decl = symbol->called_fb_declaration;
  1009 	symbol_c *fb_decl = symbol->called_fb_declaration;
   962 	
  1010 	
   963 	/* Although a call to a non-declared FB is a semantic error, this is currently caught by stage 2! */
  1011 	/* Although a call to a non-declared FB is a semantic error, this is currently caught by stage 2! */
  1036 
  1084 
  1037 
  1085 
  1038 /*******************/
  1086 /*******************/
  1039 /* B 2.2 Operators */
  1087 /* B 2.2 Operators */
  1040 /*******************/
  1088 /*******************/
       
  1089 /* Sets the datatype of the il_operand, and calls it recursively!
       
  1090  * 
       
  1091  * NOTE 1: the il_operand __may__ be pointing to a parenthesized list of IL instructions. 
       
  1092  * e.g.  LD 33
       
  1093  *       AND ( 45
       
  1094  *            OR 56
       
  1095  *            )
       
  1096  *       When we handle the first 'AND' IL_operator, the il_operand will point to an simple_instr_list_c.
       
  1097  *       In this case, when we call il_operand->accept(*this);, the prev_il_instruction pointer will be overwritten!
       
  1098  *
       
  1099  *       So, if yoy wish to set the prev_il_instruction->datatype = symbol->datatype;
       
  1100  *       do it __before__ calling set_il_operand_datatype() (which in turn calls il_operand->accept(*this)) !!
       
  1101  */
       
  1102 void *narrow_candidate_datatypes_c::set_il_operand_datatype(symbol_c *il_operand, symbol_c *datatype) {
       
  1103 	if (NULL == il_operand) return NULL; /* if no IL operand => error in the source code!! */
       
  1104 
       
  1105 	/* If il_operand already has a non-NULL datatype (remember, narrow algorithm runs twice over IL lists!),
       
  1106 	 * but narrow algorithm has not yet been able to determine what datatype it should take? This is strange,
       
  1107 	 * and most probably an error!
       
  1108 	 */
       
  1109 	if ((NULL != il_operand->datatype) && (NULL == datatype)) ERROR;
       
  1110 
       
  1111 	/* If the il_operand's datatype has already been set previously, and
       
  1112 	 * the narrow algorithm has already determined the datatype the il_operand should take!
       
  1113 	 *   ...we just make sure that the new datatype is the same as the current il_operand's datatype
       
  1114 	 */
       
  1115 	if ((NULL != il_operand->datatype)  && (NULL != datatype)) {
       
  1116 		/* Both datatypes are an invalid_type_name_c. This implies they are the same!! */
       
  1117 		if ((!get_datatype_info_c::is_type_valid(datatype)) && ((!get_datatype_info_c::is_type_valid(il_operand->datatype)))) 
       
  1118 			return NULL;;
       
  1119 		/* OK, so both the datatypes are valid, but are they equal? */
       
  1120 		if ( !get_datatype_info_c::is_type_equal(il_operand->datatype, datatype)) 
       
  1121 			ERROR; 
       
  1122 		/* The datatypes are the same. We have nothing to do, so we simply return! */
       
  1123 		return NULL;
       
  1124 	}
       
  1125 
       
  1126 	/* Set the il_operand's datatype. Note that the new 'datatype' may even be NULL!!! */
       
  1127 	il_operand->datatype = datatype;
       
  1128 	/* Even if we are not able to determine the il_operand's datatype ('datatype' is NULL), we still visit it recursively,
       
  1129 	 * to give a chance of any complex expressions embedded in the il_operand (e.g. expressions inside array subscripts!) 
       
  1130 	 * to be narrowed too.
       
  1131 	 */
       
  1132 	il_operand->accept(*this);
       
  1133 	return NULL;
       
  1134 }
       
  1135 
       
  1136 
       
  1137 
       
  1138 
  1041 void *narrow_candidate_datatypes_c::narrow_binary_operator(const struct widen_entry widen_table[], symbol_c *symbol, bool *deprecated_operation) {
  1139 void *narrow_candidate_datatypes_c::narrow_binary_operator(const struct widen_entry widen_table[], symbol_c *symbol, bool *deprecated_operation) {
  1042 	symbol_c *prev_instruction_type, *operand_type;
  1140 	symbol_c *prev_instruction_type, *operand_type;
  1043 	int count = 0;
  1141 	int count = 0;
  1044 
  1142 
  1045 	if (NULL == symbol->datatype)
       
  1046 		/* next IL instructions were unable to determine the datatype this instruction should produce */
       
  1047 		return NULL;
       
  1048 
       
  1049         if (NULL != deprecated_operation)
  1143         if (NULL != deprecated_operation)
  1050 		*deprecated_operation = false;
  1144 		*deprecated_operation = false;
  1051 
  1145 
  1052 	/* NOTE 1: the il_operand __may__ be pointing to a parenthesized list of IL instructions. 
  1146 	if (NULL == il_operand) return NULL; /* if no IL operand => error in the source code!! */
       
  1147 
       
  1148 	 /* NOTE 1: the il_operand __may__ be pointing to a parenthesized list of IL instructions. 
  1053 	 * e.g.  LD 33
  1149 	 * e.g.  LD 33
  1054 	 *       AND ( 45
  1150 	 *       AND ( 45
  1055 	 *            OR 56
  1151 	 *            OR 56
  1056 	 *            )
  1152 	 *            )
  1057 	 *       When we handle the first 'AND' IL_operator, the il_operand will point to an simple_instr_list_c.
  1153 	 *       When we handle the first 'AND' IL_operator, the il_operand will point to an simple_instr_list_c.
  1062 	 *
  1158 	 *
  1063 	 * NOTE 2: We do not need to call prev_il_instruction->accept(*this), as the object to which prev_il_instruction
  1159 	 * NOTE 2: We do not need to call prev_il_instruction->accept(*this), as the object to which prev_il_instruction
  1064 	 *         is pointing to will be later narrowed by the call from the for() loop of the instruction_list_c
  1160 	 *         is pointing to will be later narrowed by the call from the for() loop of the instruction_list_c
  1065 	 *         (or simple_instr_list_c), which iterates backwards.
  1161 	 *         (or simple_instr_list_c), which iterates backwards.
  1066 	 */
  1162 	 */
  1067 	for(unsigned int i = 0; i < fake_prev_il_instruction->candidate_datatypes.size(); i++) {
  1163 	if (NULL != symbol->datatype) { // next IL instructions were able to determine the datatype this instruction should produce
  1068 		for(unsigned int j = 0; j < il_operand->candidate_datatypes.size(); j++) {
  1164 		for(unsigned int i = 0; i < fake_prev_il_instruction->candidate_datatypes.size(); i++) {
  1069 			prev_instruction_type = fake_prev_il_instruction->candidate_datatypes[i];
  1165 			for(unsigned int j = 0; j < il_operand->candidate_datatypes.size(); j++) {
  1070 			operand_type = il_operand->candidate_datatypes[j];
  1166 				prev_instruction_type = fake_prev_il_instruction->candidate_datatypes[i];
  1071 			if (is_widening_compatible(widen_table, prev_instruction_type, operand_type, symbol->datatype, deprecated_operation)) {
  1167 				operand_type = il_operand->candidate_datatypes[j];
  1072 				/* set the desired datatype of the previous il instruction */
  1168 				if (is_widening_compatible(widen_table, prev_instruction_type, operand_type, symbol->datatype, deprecated_operation)) {
  1073 				set_datatype_in_prev_il_instructions(prev_instruction_type, fake_prev_il_instruction);
  1169 					/* set the desired datatype of the previous il instruction */
  1074 				/* set the datatype for the operand */
  1170 					set_datatype_in_prev_il_instructions(prev_instruction_type, fake_prev_il_instruction);
  1075 				il_operand->datatype = operand_type;
  1171 					/* set the datatype for the operand */
  1076 				il_operand->accept(*this);
  1172 					set_il_operand_datatype(il_operand, operand_type);
  1077 				
  1173 					
  1078 				/* NOTE: DO NOT search any further! Return immediately!
  1174 					/* NOTE: DO NOT search any further! Return immediately!
  1079 				 * Since we support SAFE*** datatypes, multiple entries in the widen_table may be compatible.
  1175 					 * Since we support SAFE*** datatypes, multiple entries in the widen_table may be compatible.
  1080 				 * If we try to set more than one distinct datatype on the same symbol, then the datatype will be set to
  1176 					 * If we try to set more than one distinct datatype on the same symbol, then the datatype will be set to
  1081 				 * an invalid_datatype, which is NOT what we want!
  1177 					 * an invalid_datatype, which is NOT what we want!
  1082 				 */
  1178 					 */
  1083 				return NULL;
  1179 					return NULL;
       
  1180 				}
  1084 			}
  1181 			}
  1085 		}
  1182 		}
  1086 	}
  1183 	}
  1087 	return NULL;
  1184 	/* We were not able to determine the required datatype, but we still give the il_operand a chance to be narrowed! */
  1088 }
  1185 	set_il_operand_datatype(il_operand, NULL);
  1089 
  1186 	return NULL;
  1090 
  1187 }
  1091 
  1188 
  1092 
  1189 
  1093 
  1190 
  1094 void *narrow_candidate_datatypes_c::handle_il_instruction(symbol_c *symbol) {
  1191 
  1095 	if (NULL == symbol->datatype)
  1192 /* Narrow IL operators whose execution is conditional on the boolean value in the accumulator.
  1096 		/* next IL instructions were unable to determine the datatype this instruction should produce */
  1193  * Basically, narrow the JMPC, JMPCN, RETC, RETCN, CALC, and CALCN operators!
  1097 		return NULL;
  1194  * Also does part of the S and R operator narrowing!!!
  1098 	/* NOTE 1: the il_operand __may__ be pointing to a parenthesized list of IL instructions. 
  1195  */
  1099 	 * e.g.  LD 33
  1196 void *narrow_candidate_datatypes_c::narrow_conditional_operator(symbol_c *symbol) {
  1100 	 *       AND ( 45
  1197 	/* if the next IL instructions needs us to provide a datatype other than a BOOL or a SAFEBOOL, 
  1101 	 *            OR 56
  1198 	 * then we have an internal compiler error - most likely in fill_candidate_datatypes_c 
  1102 	 *            )
  1199 	 */
  1103 	 *       When we handle the first 'AND' IL_operator, the il_operand will point to an simple_instr_list_c.
  1200 	// I (mario) am confident the fill/narrow algorithms are working correctly, so for now we can disable the assertions!
  1104 	 *       In this case, when we call il_operand->accept(*this);, the prev_il_instruction pointer will be overwritten!
  1201 	//if ((NULL != symbol->datatype) && (!get_datatype_info_c::is_BOOL_compatible(symbol->datatype))) ERROR;
  1105 	 *
  1202 	//if (symbol->candidate_datatypes.size() > 2) ERROR; /* may contain, at most, a BOOL and a SAFEBOOL */
  1106 	 *       We must therefore set the prev_il_instruction->datatype = symbol->datatype;
  1203 
  1107 	 *       __before__ calling il_operand->accept(*this) !!
  1204 	/* NOTE: If there is no IL instruction following this S, R, CALC, CALCN, JMPC, JMPCN, RETC, or RETCN instruction,
  1108 	 *
  1205 	 *       we must still provide a bool_type_name_c datatype (if possible, i.e. if it exists in the candidate datatype list).
  1109 	 * NOTE 2: We do not need to call prev_il_instruction->accept(*this), as the object to which prev_il_instruction
  1206 	 *       If it is not possible, we set it to NULL
  1110 	 *         is pointing to will be later narrowed by the call from the for() loop of the instruction_list_c
  1207 	 * 
  1111 	 *         (or simple_instr_list_c), which iterates backwards.
  1208 	 * NOTE: Note that this algorithm we are implementing is slightly wrong. 
  1112 	 */
  1209 	 *        (a) It ignores that a SAFEBOOL may be needed instead of a BOOL datatype. 
  1113 	/* set the desired datatype of the previous il instruction */
  1210 	 *        (b) It also ignores that this method gets to be called twice on the same 
       
  1211 	 *            object (the narrow algorithm runs through the IL list twice in order to
       
  1212 	 *            handle forward JMPs), so the assumption that we must immediately set our
       
  1213 	 *            own datatype if we get called with a NULL symbol->datatype is incorrect 
       
  1214 	 *           (it may be that the second time it is called it will be with the correct datatype!).
       
  1215 	 * 
       
  1216 	 *       These two issues (a) and (b) together means that we should only really be setting our own
       
  1217 	 *       datatype if we are certain that the following IL instructions will never set it for us
       
  1218 	 *       - basically if the following IL instruction is a LD, or a JMP to a LD, or a JMP to a JMP to a LD,
       
  1219 	 *        etc..., or a conditional JMP whose both branches go to LD, etc...!!!
       
  1220 	 *       
       
  1221 	 *       At the moment, it seems to me that we would need to write a visitor class to do this for us!
       
  1222 	 *       I currently have other things on my mind at the moment, so I will leave this for later...
       
  1223 	 *       For the moment we just set it to BOOL, and ignore the support of SAFEBOOL!
       
  1224 	 */
       
  1225 	if (NULL == symbol->datatype) set_datatype(&get_datatype_info_c::bool_type_name /* datatype*/, symbol /* symbol */);
       
  1226 	if (NULL == symbol->datatype) ERROR; // the BOOL is not on the candidate_datatypes! Strange... Probably a bug in fill_candidate_datatype_c
       
  1227 
       
  1228 	/* set the required datatype of the previous IL instruction, i.e. a bool_type_name_c! */
  1114 	set_datatype_in_prev_il_instructions(symbol->datatype, fake_prev_il_instruction);
  1229 	set_datatype_in_prev_il_instructions(symbol->datatype, fake_prev_il_instruction);
  1115 	  
  1230 	return NULL;
       
  1231 }
       
  1232 
       
  1233 
       
  1234 
       
  1235 void *narrow_candidate_datatypes_c::narrow_S_and_R_operator(symbol_c *symbol, const char *param_name, symbol_c *called_fb_declaration) {
       
  1236 	if (NULL != called_fb_declaration) 
       
  1237 	  /* FB call semantics */  
       
  1238 	  return narrow_implicit_il_fb_call(symbol, param_name, called_fb_declaration); 
       
  1239 	
       
  1240 	/* Set/Reset semantics */  
       
  1241 	narrow_conditional_operator(symbol);
       
  1242 	/* set the datatype for the il_operand */
       
  1243 	if ((NULL != il_operand) && (il_operand->candidate_datatypes.size() > 0))
       
  1244 		set_il_operand_datatype(il_operand, il_operand->candidate_datatypes[0]);
       
  1245 	return NULL;
       
  1246 }
       
  1247 
       
  1248 
       
  1249 
       
  1250 void *narrow_candidate_datatypes_c::narrow_store_operator(symbol_c *symbol) {
       
  1251 	if (symbol->candidate_datatypes.size() == 1) {
       
  1252 		symbol->datatype = symbol->candidate_datatypes[0];
       
  1253 		/* set the desired datatype of the previous il instruction */
       
  1254 		set_datatype_in_prev_il_instructions(symbol->datatype, fake_prev_il_instruction);
       
  1255 		/* In the case of the ST operator, we must set the datatype of the il_instruction_c object that points to this ST_operator_c ourselves,
       
  1256 		 * since the following il_instruction_c objects have not done it, as is normal/standard for other instructions!
       
  1257 		 */
       
  1258 		current_il_instruction->datatype = symbol->datatype;
       
  1259 	}
       
  1260 	
  1116 	/* set the datatype for the operand */
  1261 	/* set the datatype for the operand */
  1117 	il_operand->datatype = symbol->datatype;
  1262 	set_il_operand_datatype(il_operand, symbol->datatype);
  1118 	il_operand->accept(*this);
  1263 	return NULL;
  1119 	return NULL;
  1264 }
  1120 }
  1265 
  1121 
  1266 
  1122 
  1267 
  1123 
  1268 void *narrow_candidate_datatypes_c::visit(  LD_operator_c *symbol)  {return set_il_operand_datatype(il_operand, symbol->datatype);}
  1124 
  1269 void *narrow_candidate_datatypes_c::visit( LDN_operator_c *symbol)  {return set_il_operand_datatype(il_operand, symbol->datatype);}
  1125 void *narrow_candidate_datatypes_c::visit(LD_operator_c *symbol)   {
  1270 
  1126 	if (NULL == symbol->datatype)
  1271 void *narrow_candidate_datatypes_c::visit(  ST_operator_c *symbol)  {return narrow_store_operator(symbol);}
  1127 		/* next IL instructions were unable to determine the datatype this instruction should produce */
  1272 void *narrow_candidate_datatypes_c::visit( STN_operator_c *symbol)  {return narrow_store_operator(symbol);}
  1128 		return NULL;
  1273 
  1129 	/* set the datatype for the operand */
  1274 
  1130 	il_operand->datatype = symbol->datatype;
  1275 /* NOTE: the standard allows syntax in which the NOT operator is followed by an optional <il_operand>
  1131 	il_operand->accept(*this);
  1276  *              NOT [<il_operand>]
  1132 	return NULL;
  1277  *       However, it does not define the semantic of the NOT operation when the <il_operand> is specified.
  1133 }
  1278  *       We therefore consider it an error if an il_operand is specified!
  1134 
  1279  *       This error will be detected in print_datatypes_error_c!!
  1135 
  1280  */
  1136 void *narrow_candidate_datatypes_c::visit(LDN_operator_c *symbol)  {
  1281 /* This operator does not change the data type, it simply inverts the bits in the ANT_BIT data types! */
  1137 	if (NULL == symbol->datatype)
  1282 /* So, we merely set the desired datatype of the previous il instruction */
  1138 		/* next IL instructions were unable to determine the datatype this instruction should produce */
  1283 void *narrow_candidate_datatypes_c::visit( NOT_operator_c *symbol)  {set_datatype_in_prev_il_instructions(symbol->datatype, fake_prev_il_instruction);return NULL;}
  1139 		return NULL;
  1284 
  1140 	/* set the datatype for the operand */
  1285 void *narrow_candidate_datatypes_c::visit(   S_operator_c *symbol)  {return narrow_S_and_R_operator   (symbol, "S",   symbol->called_fb_declaration);}
  1141 	il_operand->datatype = symbol->datatype;
  1286 void *narrow_candidate_datatypes_c::visit(   R_operator_c *symbol)  {return narrow_S_and_R_operator   (symbol, "R",   symbol->called_fb_declaration);}
  1142 	il_operand->accept(*this);
       
  1143 	return NULL;
       
  1144 }
       
  1145 
       
  1146 void *narrow_candidate_datatypes_c::visit(ST_operator_c *symbol) {
       
  1147 	if (symbol->candidate_datatypes.size() != 1)
       
  1148 		return NULL;
       
  1149 	symbol->datatype = symbol->candidate_datatypes[0];
       
  1150 	/* set the datatype for the operand */
       
  1151 	il_operand->datatype = symbol->datatype;
       
  1152 	il_operand->accept(*this);
       
  1153 	/* set the desired datatype of the previous il instruction */
       
  1154 	set_datatype_in_prev_il_instructions(symbol->datatype, fake_prev_il_instruction);
       
  1155 	/* In the case of the ST operator, we must set the datatype of the il_instruction_c object that points to this ST_operator_c ourselves,
       
  1156 	 * since the following il_instruction_c objects have not done it, as is normal/standard for other instructions!
       
  1157 	 */
       
  1158 	current_il_instruction->datatype = symbol->datatype;
       
  1159 	return NULL;
       
  1160 }
       
  1161 
       
  1162 void *narrow_candidate_datatypes_c::visit(STN_operator_c *symbol) {
       
  1163 	if (symbol->candidate_datatypes.size() != 1)
       
  1164 		return NULL;
       
  1165 	symbol->datatype = symbol->candidate_datatypes[0];
       
  1166 	/* set the datatype for the operand */
       
  1167 	il_operand->datatype = symbol->datatype;
       
  1168 	il_operand->accept(*this);
       
  1169 	/* set the desired datatype of the previous il instruction */
       
  1170 	set_datatype_in_prev_il_instructions(symbol->datatype, fake_prev_il_instruction);
       
  1171 	return NULL;
       
  1172 }
       
  1173 
       
  1174 void *narrow_candidate_datatypes_c::visit(NOT_operator_c *symbol) {
       
  1175 	/* NOTE: the standard allows syntax in which the NOT operator is followed by an optional <il_operand>
       
  1176 	 *              NOT [<il_operand>]
       
  1177 	 *       However, it does not define the semantic of the NOT operation when the <il_operand> is specified.
       
  1178 	 *       We therefore consider it an error if an il_operand is specified!
       
  1179 	 */
       
  1180 	/* We do not change the data type, we simply invert the bits in bit types! */
       
  1181 	/* So, we set the desired datatype of the previous il instruction */
       
  1182 	set_datatype_in_prev_il_instructions(symbol->datatype, fake_prev_il_instruction);
       
  1183 	return NULL;
       
  1184 }
       
  1185 
       
  1186 void *narrow_candidate_datatypes_c::visit(S_operator_c *symbol)  {
       
  1187   /* TODO: what if this is a FB call? */
       
  1188 	return handle_il_instruction(symbol);
       
  1189 }
       
  1190 void *narrow_candidate_datatypes_c::visit(R_operator_c *symbol)  {
       
  1191   /* TODO: what if this is a FB call? */
       
  1192 	return handle_il_instruction(symbol);
       
  1193 }
       
  1194 
       
  1195 
  1287 
  1196 void *narrow_candidate_datatypes_c::visit(  S1_operator_c *symbol)  {return narrow_implicit_il_fb_call(symbol, "S1",  symbol->called_fb_declaration);}
  1288 void *narrow_candidate_datatypes_c::visit(  S1_operator_c *symbol)  {return narrow_implicit_il_fb_call(symbol, "S1",  symbol->called_fb_declaration);}
  1197 void *narrow_candidate_datatypes_c::visit(  R1_operator_c *symbol)  {return narrow_implicit_il_fb_call(symbol, "R1",  symbol->called_fb_declaration);}
  1289 void *narrow_candidate_datatypes_c::visit(  R1_operator_c *symbol)  {return narrow_implicit_il_fb_call(symbol, "R1",  symbol->called_fb_declaration);}
  1198 void *narrow_candidate_datatypes_c::visit( CLK_operator_c *symbol)  {return narrow_implicit_il_fb_call(symbol, "CLK", symbol->called_fb_declaration);}
  1290 void *narrow_candidate_datatypes_c::visit( CLK_operator_c *symbol)  {return narrow_implicit_il_fb_call(symbol, "CLK", symbol->called_fb_declaration);}
  1199 void *narrow_candidate_datatypes_c::visit(  CU_operator_c *symbol)  {return narrow_implicit_il_fb_call(symbol, "CU",  symbol->called_fb_declaration);}
  1291 void *narrow_candidate_datatypes_c::visit(  CU_operator_c *symbol)  {return narrow_implicit_il_fb_call(symbol, "CU",  symbol->called_fb_declaration);}
  1219 void *narrow_candidate_datatypes_c::visit(  LT_operator_c *symbol)  {return narrow_binary_operator(widen_CMP_table, symbol);}
  1311 void *narrow_candidate_datatypes_c::visit(  LT_operator_c *symbol)  {return narrow_binary_operator(widen_CMP_table, symbol);}
  1220 void *narrow_candidate_datatypes_c::visit(  LE_operator_c *symbol)  {return narrow_binary_operator(widen_CMP_table, symbol);}
  1312 void *narrow_candidate_datatypes_c::visit(  LE_operator_c *symbol)  {return narrow_binary_operator(widen_CMP_table, symbol);}
  1221 void *narrow_candidate_datatypes_c::visit(  NE_operator_c *symbol)  {return narrow_binary_operator(widen_CMP_table, symbol);}
  1313 void *narrow_candidate_datatypes_c::visit(  NE_operator_c *symbol)  {return narrow_binary_operator(widen_CMP_table, symbol);}
  1222 
  1314 
  1223 
  1315 
  1224 
  1316 /* 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)} */
  1225 
       
  1226 void *narrow_candidate_datatypes_c::narrow_conditional_flow_control_IL_instruction(symbol_c *symbol) {
       
  1227 	/* if the next IL instructions needs us to provide a datatype other than a bool, 
       
  1228 	 * then we have an internal compiler error - most likely in fill_candidate_datatypes_c 
       
  1229 	 */
       
  1230 	if ((NULL != symbol->datatype) && (!get_datatype_info_c::is_BOOL_compatible(symbol->datatype))) ERROR;
       
  1231 	if (symbol->candidate_datatypes.size() > 1) ERROR;
       
  1232 
       
  1233 	/* NOTE: If there is no IL instruction following this CALC, CALCN, JMPC, JMPC, ..., instruction,
       
  1234 	 *       we must still provide a bool_type_name_c datatype (if possible, i.e. if it exists in the candidate datatype list).
       
  1235 	 *       If it is not possible, we set it to NULL
       
  1236 	 */
       
  1237 	if (symbol->candidate_datatypes.size() == 0)    symbol->datatype = NULL;
       
  1238 	else    symbol->datatype = symbol->candidate_datatypes[0]; /* i.e. a bool_type_name_c! */
       
  1239 	if ((NULL != symbol->datatype) && (!get_datatype_info_c::is_BOOL_compatible(symbol->datatype))) ERROR;
       
  1240 
       
  1241 	/* set the required datatype of the previous IL instruction, i.e. a bool_type_name_c! */
       
  1242 	set_datatype_in_prev_il_instructions(symbol->datatype, fake_prev_il_instruction);
       
  1243 	return NULL;
       
  1244 }
       
  1245 
       
  1246 
       
  1247 // SYM_REF0(CAL_operator_c)
       
  1248 // SYM_REF0(CALC_operator_c)
       
  1249 // SYM_REF0(CALCN_operator_c)
       
  1250 /* called from visit(il_fb_call_c *) {symbol->il_call_operator->accpet(*this)} */
       
  1251 /* 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 */
  1317 /* 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 */
  1252 /* called from il_fb_call_c (symbol->il_call_operator->accpet(*this) ) */
       
  1253 void *narrow_candidate_datatypes_c::visit(  CAL_operator_c *symbol) {set_datatype_in_prev_il_instructions(symbol->datatype, fake_prev_il_instruction); return NULL;}
  1318 void *narrow_candidate_datatypes_c::visit(  CAL_operator_c *symbol) {set_datatype_in_prev_il_instructions(symbol->datatype, fake_prev_il_instruction); return NULL;}
  1254 void *narrow_candidate_datatypes_c::visit(  RET_operator_c *symbol) {set_datatype_in_prev_il_instructions(symbol->datatype, fake_prev_il_instruction); return NULL;}
  1319 void *narrow_candidate_datatypes_c::visit(  RET_operator_c *symbol) {set_datatype_in_prev_il_instructions(symbol->datatype, fake_prev_il_instruction); return NULL;}
  1255 void *narrow_candidate_datatypes_c::visit(  JMP_operator_c *symbol) {set_datatype_in_prev_il_instructions(symbol->datatype, fake_prev_il_instruction); return NULL;}
  1320 void *narrow_candidate_datatypes_c::visit(  JMP_operator_c *symbol) {set_datatype_in_prev_il_instructions(symbol->datatype, fake_prev_il_instruction); return NULL;}
  1256 void *narrow_candidate_datatypes_c::visit( CALC_operator_c *symbol) {return narrow_conditional_flow_control_IL_instruction(symbol);}
  1321 void *narrow_candidate_datatypes_c::visit( CALC_operator_c *symbol) {return narrow_conditional_operator(symbol);}
  1257 void *narrow_candidate_datatypes_c::visit(CALCN_operator_c *symbol) {return narrow_conditional_flow_control_IL_instruction(symbol);}
  1322 void *narrow_candidate_datatypes_c::visit(CALCN_operator_c *symbol) {return narrow_conditional_operator(symbol);}
  1258 void *narrow_candidate_datatypes_c::visit( RETC_operator_c *symbol) {return narrow_conditional_flow_control_IL_instruction(symbol);}
  1323 void *narrow_candidate_datatypes_c::visit( RETC_operator_c *symbol) {return narrow_conditional_operator(symbol);}
  1259 void *narrow_candidate_datatypes_c::visit(RETCN_operator_c *symbol) {return narrow_conditional_flow_control_IL_instruction(symbol);}
  1324 void *narrow_candidate_datatypes_c::visit(RETCN_operator_c *symbol) {return narrow_conditional_operator(symbol);}
  1260 void *narrow_candidate_datatypes_c::visit( JMPC_operator_c *symbol) {return narrow_conditional_flow_control_IL_instruction(symbol);}
  1325 void *narrow_candidate_datatypes_c::visit( JMPC_operator_c *symbol) {return narrow_conditional_operator(symbol);}
  1261 void *narrow_candidate_datatypes_c::visit(JMPCN_operator_c *symbol) {return narrow_conditional_flow_control_IL_instruction(symbol);}
  1326 void *narrow_candidate_datatypes_c::visit(JMPCN_operator_c *symbol) {return narrow_conditional_operator(symbol);}
  1262 
  1327 
  1263 /* Symbol class handled together with function call checks */
  1328 /* Symbol class handled together with function call checks */
  1264 // void *visit(il_assign_operator_c *symbol, variable_name);
  1329 // void *visit(il_assign_operator_c *symbol, variable_name);
  1265 /* Symbol class handled together with function call checks */
  1330 /* Symbol class handled together with function call checks */
  1266 // void *visit(il_assign_operator_c *symbol, option, variable_name);
  1331 // void *visit(il_assign_operator_c *symbol, option, variable_name);