stage3/narrow_candidate_datatypes.cc
changeset 455 933c0dccc82f
parent 454 099aa5d655de
child 456 ca8d98289ff9
equal deleted inserted replaced
454:099aa5d655de 455:933c0dccc82f
   173 		if ((NULL == param_name) && (NULL != desired_datatype)) ERROR;
   173 		if ((NULL == param_name) && (NULL != desired_datatype)) ERROR;
   174 
   174 
   175 		/* set the desired data type for this parameter */
   175 		/* set the desired data type for this parameter */
   176 		set_datatype(desired_datatype, call_param_value);
   176 		set_datatype(desired_datatype, call_param_value);
   177 		/* And recursively call that parameter/expression, so it can propagate that info */
   177 		/* And recursively call that parameter/expression, so it can propagate that info */
   178 		/* However, when handling an implicit IL FB call, the first parameter is fake (a copy of the prev_il_instruction).
       
   179 		 * so the call call_param_value->accept(*this) may actually be calling an object of the base symbol_c .
       
   180 		 */
       
   181 		call_param_value->accept(*this);
   178 		call_param_value->accept(*this);
   182 
   179 
       
   180 		/* set the extensible_parameter_highest_index, which will be needed in stage 4 */
       
   181 		/* This value says how many extensible parameters are being passed to the standard function */
   183 		if (NULL != param_name) 
   182 		if (NULL != param_name) 
   184 			if (extensible_parameter_highest_index < fp_iterator.extensible_param_index())
   183 			if (extensible_parameter_highest_index < fp_iterator.extensible_param_index())
   185 				extensible_parameter_highest_index = fp_iterator.extensible_param_index();
   184 				extensible_parameter_highest_index = fp_iterator.extensible_param_index();
   186 	}
   185 	}
   187 	/* call is compatible! */
   186 	/* call is compatible! */
   259  *
   258  *
   260  * The algorithm will be to build a fake il_fb_call_c equivalent to the implicit IL FB call, and let 
   259  * The algorithm will be to build a fake il_fb_call_c equivalent to the implicit IL FB call, and let 
   261  * the visit(il_fb_call_c *) method handle it!
   260  * the visit(il_fb_call_c *) method handle it!
   262  */
   261  */
   263 void narrow_candidate_datatypes_c::narrow_implicit_il_fb_call(symbol_c *il_instruction, const char *param_name, symbol_c *&called_fb_declaration) {
   262 void narrow_candidate_datatypes_c::narrow_implicit_il_fb_call(symbol_c *il_instruction, const char *param_name, symbol_c *&called_fb_declaration) {
   264 	if (NULL == called_fb_declaration)
   263 
   265 		/* The fill_candidate_datatypes_c was not able to determine which FB is being called!
   264 	/* set the datatype of the il_operand, this is, the FB being called! */
   266 		 * This may be because the il_operand is not the name of a FB instance, or no operand was given. 
   265 	if (NULL != il_operand) {
   267 		 * In that case, we just give up!
   266 		/* only set it if it is in the candidate datatypes list! */  
   268 		 */
   267 		set_datatype(called_fb_declaration, il_operand);
   269 		return;
   268 		il_operand->accept(*this);
       
   269 	}
       
   270 	symbol_c *fb_decl = il_operand->datatype;
       
   271 
   270 	if (NULL == prev_il_instruction) {
   272 	if (NULL == prev_il_instruction) {
   271 		/* This IL implicit FB call (e.g. CLK ton_var) is not preceded by another IL instruction
   273 		/* This IL implicit FB call (e.g. CLK ton_var) is not preceded by another IL instruction
   272 		 * (or list of instructions) that will set the IL current/default value.
   274 		 * (or list of instructions) that will set the IL current/default value.
   273 		 * We cannot proceed verifying type compatibility of something that does not exist.
   275 		 * We cannot proceed verifying type compatibility of something that does not exist.
   274 		 */
   276 		 */
   275 		return;
   277 		return;
   276 	}
   278 	}
       
   279 
       
   280 	if (NULL == fb_decl) {
       
   281 		/* the il_operand is a not FB instance */
       
   282 		/* so we simply pass on the required datatype to the prev_il_instruction */
       
   283 		/* The invalid FB invocation will be caught by the print_datatypes_error_c by analysing NULL value in il_operand->datatype! */
       
   284 		prev_il_instruction->datatype = il_instruction->datatype;
       
   285 		return;
       
   286 	}
       
   287 	
   277 
   288 
   278 	/* The value being passed to the 'param_name' parameter is actually the prev_il_instruction.
   289 	/* The value being passed to the 'param_name' parameter is actually the prev_il_instruction.
   279 	 * However, we do not place that object directly in the fake il_param_list_c that we will be
   290 	 * However, we do not place that object directly in the fake il_param_list_c that we will be
   280 	 * creating, since the visit(il_fb_call_c *) method will recursively call every object in that list.
   291 	 * creating, since the visit(il_fb_call_c *) method will recursively call every object in that list.
   281 	 * The il_prev_intruction object will be visited once we have handled this implici IL FB call
   292 	 * The il_prev_intruction object will be visited once we have handled this implici IL FB call
   283 	 * (Anyway, if we let the visit(il_fb_call_c *) recursively visit the current prev_il_instruction, this pointer
   294 	 * (Anyway, if we let the visit(il_fb_call_c *) recursively visit the current prev_il_instruction, this pointer
   284 	 * would be changed to the IL instruction coming before the current prev_il_instruction! => things would get all messed up!)
   295 	 * would be changed to the IL instruction coming before the current prev_il_instruction! => things would get all messed up!)
   285 	 * The easiest way to work around this is to simply use a new object, and copy the relevant details to that object!
   296 	 * The easiest way to work around this is to simply use a new object, and copy the relevant details to that object!
   286 	 */
   297 	 */
   287 	symbol_c param_value = *prev_il_instruction;
   298 	symbol_c param_value = *prev_il_instruction;
   288 	
   299         
   289 	identifier_c variable_name(param_name);
   300 	identifier_c variable_name(param_name);
   290 	// SYM_REF1(il_assign_operator_c, variable_name)
   301 	// SYM_REF1(il_assign_operator_c, variable_name)
   291 	il_assign_operator_c il_assign_operator(&variable_name);  
   302 	il_assign_operator_c il_assign_operator(&variable_name);  
   292 	// SYM_REF3(il_param_assignment_c, il_assign_operator, il_operand, simple_instr_list)
   303 	// SYM_REF3(il_param_assignment_c, il_assign_operator, il_operand, simple_instr_list)
   293 	il_param_assignment_c il_param_assignment(&il_assign_operator, &param_value/*il_operand*/, NULL);
   304 	il_param_assignment_c il_param_assignment(&il_assign_operator, &param_value/*il_operand*/, NULL);
   294 	il_param_list_c il_param_list;
   305 	il_param_list_c il_param_list;
   295 	il_param_list.add_element(&il_param_assignment);
   306 	il_param_list.add_element(&il_param_assignment);
   296 	// SYM_REF4(il_fb_call_c, il_call_operator, fb_name, il_operand_list, il_param_list, symbol_c *called_fb_declaration)
   307 	// SYM_REF4(il_fb_call_c, il_call_operator, fb_name, il_operand_list, il_param_list, symbol_c *called_fb_declaration)
   297 	il_fb_call_c il_fb_call(NULL, il_operand, NULL, &il_param_list);
   308 	CAL_operator_c CAL_operator;
   298 	
   309 	il_fb_call_c il_fb_call(&CAL_operator, il_operand, NULL, &il_param_list);
       
   310 	        
   299 	/* A FB call does not return any datatype, but the IL instructions that come after this
   311 	/* A FB call does not return any datatype, but the IL instructions that come after this
   300 	 * FB call may require a specific datatype in the il current/default variable, 
   312 	 * FB call may require a specific datatype in the il current/default variable, 
   301 	 * so we must pass this information up to the IL instruction before the FB call, since it will
   313 	 * so we must pass this information up to the IL instruction before the FB call, since it will
   302 	 * be that IL instruction that will be required to produce the desired dtataype.
   314 	 * be that IL instruction that will be required to produce the desired dtataype.
   303 	 *
   315 	 *
   304 	 * The above will be done by the visit(il_fb_call_c *) method, so we must make sure to
   316 	 * The above will be done by the visit(il_fb_call_c *) method, so we must make sure to
   305 	 * correctly set up the il_fb_call.datatype variable!
   317 	 * correctly set up the il_fb_call.datatype variable!
   306 	 */
   318 	 */
   307 	copy_candidate_datatype_list(il_instruction/*from*/, &il_fb_call/*to*/);
   319 // 	copy_candidate_datatype_list(il_instruction/*from*/, &il_fb_call/*to*/);
       
   320 	il_fb_call.called_fb_declaration = called_fb_declaration;
   308 	il_fb_call.accept(*this);
   321 	il_fb_call.accept(*this);
   309 	
   322 
   310 	/* set the required datatype of the previous IL instruction! */
   323 	/* set the required datatype of the previous IL instruction! */
   311 	/* NOTE:
   324 	/* NOTE:
   312 	 * When handling these implicit IL calls, the parameter_value being passed to the FB parameter
   325 	 * When handling these implicit IL calls, the parameter_value being passed to the FB parameter
   313 	 * is actually the prev_il_instruction.
   326 	 * is actually the prev_il_instruction.
   314 	 * 
   327 	 * 
   325 	 *     datatype in the current/default vairable, once this IL FB call returns.
   338 	 *     datatype in the current/default vairable, once this IL FB call returns.
   326 	 *     However, sometimes, (for e.g., this FB call is the last in the IL list) the subsequent FB to not aks this
   339 	 *     However, sometimes, (for e.g., this FB call is the last in the IL list) the subsequent FB to not aks this
   327 	 *     FB call for any datatype. In that case, then the datatype required to pass to the first parameter of the
   340 	 *     FB call for any datatype. In that case, then the datatype required to pass to the first parameter of the
   328 	 *     FB call must be left unchanged!
   341 	 *     FB call must be left unchanged!
   329 	 */
   342 	 */
   330 // 	if (NULL != prev_il_instruction) /* already checked above! */
   343 	if ((NULL == il_instruction->datatype) || (is_type_equal(param_value.datatype, il_instruction->datatype))) {
   331 		if (is_type_equal(param_value.datatype, il_instruction->datatype)) {
   344 		prev_il_instruction->datatype = param_value.datatype;
   332 			prev_il_instruction->datatype = param_value.datatype;
   345 	} else {
   333 		} else {
   346 		prev_il_instruction->datatype = NULL;
   334 			prev_il_instruction->datatype = NULL;
   347 	}
   335 		}
       
   336 
       
   337 }
   348 }
   338 
   349 
   339 
   350 
   340 /* a helper function... */
   351 /* a helper function... */
   341 symbol_c *narrow_candidate_datatypes_c::base_type(symbol_c *symbol) {
   352 symbol_c *narrow_candidate_datatypes_c::base_type(symbol_c *symbol) {
   590  * | il_call_operator prev_declared_fb_name '(' eol_list il_param_list ')'
   601  * | il_call_operator prev_declared_fb_name '(' eol_list il_param_list ')'
   591  */
   602  */
   592 /* 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 */
   603 /* 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 */
   593 // SYM_REF4(il_fb_call_c, il_call_operator, fb_name, il_operand_list, il_param_list, symbol_c *called_fb_declaration)
   604 // SYM_REF4(il_fb_call_c, il_call_operator, fb_name, il_operand_list, il_param_list, symbol_c *called_fb_declaration)
   594 void *narrow_candidate_datatypes_c::visit(il_fb_call_c *symbol) {
   605 void *narrow_candidate_datatypes_c::visit(il_fb_call_c *symbol) {
   595 	/* Note: We do not use the symbol->called_fb_declaration value (set in fill_candidate_datatypes_c)
   606 	symbol_c *fb_decl = symbol->called_fb_declaration;
   596 	 *       because we try to identify any other datatype errors in the expressions used in the 
   607 	
   597 	 *       parameters to the FB call. e.g.
       
   598 	 *          fb_var( 
       
   599 	 *             in1 := var1,
       
   600 	 *             in2 := (
       
   601 	 *                       LD 56
       
   602 	 *                       ADD 43
       
   603 	 *                    )
       
   604 	 *             )
       
   605 	 *       even it the call to the FB is invalid. 
       
   606 	 *       This makes sense because it may be errors in those expressions which are
       
   607 	 *       making this an invalid call, so it makes sense to point them out to the user!
       
   608 	 */
       
   609 	symbol_c *fb_decl = search_varfb_instance_type->get_basetype_decl(symbol->fb_name);
       
   610 
       
   611 	/* Although a call to a non-declared FB is a semantic error, this is currently caught by stage 2! */
   608 	/* Although a call to a non-declared FB is a semantic error, this is currently caught by stage 2! */
   612 	if (NULL == fb_decl) ERROR;
   609 	if (NULL == fb_decl) ERROR;
   613 	if (NULL != symbol->il_operand_list)  narrow_nonformal_call(symbol, fb_decl);
   610 	if (NULL != symbol->il_operand_list)  narrow_nonformal_call(symbol, fb_decl);
   614 	if (NULL != symbol->  il_param_list)     narrow_formal_call(symbol, fb_decl);
   611 	if (NULL != symbol->  il_param_list)     narrow_formal_call(symbol, fb_decl);
   615 
   612 
   616 	/* An IL FB call does not change the default value in the current/default IL variable, so we pass the
   613 	/* Let the il_call_operator (CAL, CALC, or CALCN) set the datatype of prev_il_instruction... */
   617 	 * required datatype up to the previous IL instruction
   614 	symbol->il_call_operator->datatype = symbol->datatype;
   618 	 */
   615 	symbol->il_call_operator->accept(*this);
   619 	if (NULL != prev_il_instruction)
       
   620 		prev_il_instruction->datatype = symbol->datatype;
       
   621 	return NULL;
   616 	return NULL;
   622 }
   617 }
   623 
   618 
   624 
   619 
   625 /* | function_name '(' eol_list [il_param_list] ')' */
   620 /* | function_name '(' eol_list [il_param_list] ')' */
   823 void *narrow_candidate_datatypes_c::visit(LT_operator_c   *symbol)  {return handle_il_instruction(symbol);}
   818 void *narrow_candidate_datatypes_c::visit(LT_operator_c   *symbol)  {return handle_il_instruction(symbol);}
   824 void *narrow_candidate_datatypes_c::visit(LE_operator_c   *symbol)  {return handle_il_instruction(symbol);}
   819 void *narrow_candidate_datatypes_c::visit(LE_operator_c   *symbol)  {return handle_il_instruction(symbol);}
   825 void *narrow_candidate_datatypes_c::visit(NE_operator_c   *symbol)  {return handle_il_instruction(symbol);}
   820 void *narrow_candidate_datatypes_c::visit(NE_operator_c   *symbol)  {return handle_il_instruction(symbol);}
   826 
   821 
   827 
   822 
       
   823 // SYM_REF0(CAL_operator_c)
       
   824 /* called from il_fb_call_c (symbol->il_call_operator->accpet(*this) ) */
   828 void *narrow_candidate_datatypes_c::visit(CAL_operator_c *symbol) {
   825 void *narrow_candidate_datatypes_c::visit(CAL_operator_c *symbol) {
   829 	return NULL;
   826 	/* set the desired datatype of the previous il instruction */
   830 }
   827 	/* This FB call does not change the value in the current/default IL variable, so we pass the required datatype to the previous IL instruction */
   831 
   828 	if (NULL != prev_il_instruction)
       
   829 		prev_il_instruction->datatype = symbol->datatype;
       
   830 	return NULL;
       
   831 }
       
   832 
       
   833 
       
   834 void *narrow_candidate_datatypes_c::narrow_conditional_flow_control_IL_instruction(symbol_c *symbol) {
       
   835 	/* if the next IL instructions needs us to provide a datatype other than a bool, 
       
   836 	 * then we have an internal compiler error - most likely in fill_candidate_datatypes_c 
       
   837 	 */
       
   838 	if ((NULL != symbol->datatype) && (!is_type(symbol->datatype, bool_type_name_c))) ERROR;
       
   839 	if (symbol->candidate_datatypes.size() > 1) ERROR;
       
   840 
       
   841 	/* NOTE: If there is not IL instruction following this CALC, CALCN, JMPC, JMPC, ..., instruction,
       
   842 	 *       we must still provide a bool_type_name_c datatype (if possible, i.e. if it exists in the candidate datatype list).
       
   843 	 *       If it is not possible, we set it to NULL
       
   844 	 */
       
   845 	if (symbol->candidate_datatypes.size() == 0)    symbol->datatype = NULL;
       
   846 	else    symbol->datatype = symbol->candidate_datatypes[0]; /* i.e. a bool_type_name_c! */
       
   847 	if ((NULL != symbol->datatype) && (!is_type(symbol->datatype, bool_type_name_c))) ERROR;
       
   848 
       
   849 	/* set the required datatype of the previous IL instruction, i.e. a bool_type_name_c! */
       
   850 	if (NULL != prev_il_instruction)    prev_il_instruction->datatype = symbol->datatype;
       
   851 	return NULL;
       
   852 }
       
   853 
       
   854 
       
   855 // SYM_REF0(CALC_operator_c)
       
   856 /* called from il_fb_call_c (symbol->il_call_operator->accpet(*this) ) */
   832 void *narrow_candidate_datatypes_c::visit(CALC_operator_c *symbol) {
   857 void *narrow_candidate_datatypes_c::visit(CALC_operator_c *symbol) {
   833 	return NULL;
   858 	return narrow_conditional_flow_control_IL_instruction(symbol);
   834 }
   859 }
   835 
   860 
       
   861 
       
   862 // SYM_REF0(CALCN_operator_c)
       
   863 /* called from il_fb_call_c (symbol->il_call_operator->accpet(*this) ) */
   836 void *narrow_candidate_datatypes_c::visit(CALCN_operator_c *symbol) {
   864 void *narrow_candidate_datatypes_c::visit(CALCN_operator_c *symbol) {
   837 	return NULL;
   865 	return narrow_conditional_flow_control_IL_instruction(symbol);
   838 }
   866 }
       
   867 
   839 
   868 
   840 void *narrow_candidate_datatypes_c::visit(RET_operator_c *symbol) {
   869 void *narrow_candidate_datatypes_c::visit(RET_operator_c *symbol) {
       
   870 	/* set the desired datatype of the previous il instruction */
       
   871 	/* This RET instruction does not change the value in the current/default IL variable, so we pass the required datatype to the previous IL instruction.
       
   872 	 * Actually this should always be NULL, otherwise we have a bug in the flow_control_analysis_c
       
   873 	 * However, since that class has not yet been completely finished, we do not yet check this assertion!
       
   874 	 */
       
   875 // 	if (NULL != symbol->datatype) ERROR;
       
   876 	if (NULL != prev_il_instruction)
       
   877 		prev_il_instruction->datatype = symbol->datatype;
   841 	return NULL;
   878 	return NULL;
   842 }
   879 }
   843 
   880 
   844 void *narrow_candidate_datatypes_c::visit(RETC_operator_c *symbol) {
   881 void *narrow_candidate_datatypes_c::visit(RETC_operator_c *symbol) {
   845 	return NULL;
   882 	return narrow_conditional_flow_control_IL_instruction(symbol);
   846 }
   883 }
   847 
   884 
   848 void *narrow_candidate_datatypes_c::visit(RETCN_operator_c *symbol) {
   885 void *narrow_candidate_datatypes_c::visit(RETCN_operator_c *symbol) {
   849 	return NULL;
   886 	return narrow_conditional_flow_control_IL_instruction(symbol);
   850 }
   887 }
   851 
   888 
   852 void *narrow_candidate_datatypes_c::visit(JMP_operator_c *symbol) {
   889 void *narrow_candidate_datatypes_c::visit(JMP_operator_c *symbol) {
       
   890 	/* set the desired datatype of the previous il instruction */
       
   891 	/* This JMP instruction does not change the value in the current/default IL variable, so we pass the required datatype to the previous IL instruction.
       
   892 	 * Actually this should always be NULL, otherwise we have a bug in the flow_control_analysis_c
       
   893 	 * However, since that class has not yet been completely finished, we do not yet check this assertion!
       
   894 	 */
       
   895 // 	if (NULL != symbol->datatype) ERROR;
       
   896 	if (NULL != prev_il_instruction)
       
   897 		prev_il_instruction->datatype = symbol->datatype;
   853 	return NULL;
   898 	return NULL;
   854 }
   899 }
   855 
   900 
   856 void *narrow_candidate_datatypes_c::visit(JMPC_operator_c *symbol) {
   901 void *narrow_candidate_datatypes_c::visit(JMPC_operator_c *symbol) {
   857 	return NULL;
   902 	return narrow_conditional_flow_control_IL_instruction(symbol);
   858 }
   903 }
   859 
   904 
   860 void *narrow_candidate_datatypes_c::visit(JMPCN_operator_c *symbol) {
   905 void *narrow_candidate_datatypes_c::visit(JMPCN_operator_c *symbol) {
   861 	return NULL;
   906 	return narrow_conditional_flow_control_IL_instruction(symbol);
   862 }
   907 }
   863 
   908 
   864 /* Symbol class handled together with function call checks */
   909 /* Symbol class handled together with function call checks */
   865 // void *visit(il_assign_operator_c *symbol, variable_name);
   910 // void *visit(il_assign_operator_c *symbol, variable_name);
   866 /* Symbol class handled together with function call checks */
   911 /* Symbol class handled together with function call checks */