stage3/fill_candidate_datatypes.cc
changeset 451 a1b87eb155e4
parent 450 eb1b28acec2e
child 452 79ac274d1cc4
equal deleted inserted replaced
450:eb1b28acec2e 451:a1b87eb155e4
   291 	 * However, we do not place that object directly in the fake il_param_list_c that we will be
   291 	 * However, we do not place that object directly in the fake il_param_list_c that we will be
   292 	 * creating, since the visit(il_fb_call_c *) method will recursively call every object in that list.
   292 	 * creating, since the visit(il_fb_call_c *) method will recursively call every object in that list.
   293 	 * The il_prev_intruction object has already been visited. We DO NOT want to visit it again.
   293 	 * The il_prev_intruction object has already been visited. We DO NOT want to visit it again.
   294 	 * The easiest way to work around this is to simply use a new object, and copy the relevant details to that object!
   294 	 * The easiest way to work around this is to simply use a new object, and copy the relevant details to that object!
   295 	 */
   295 	 */
   296 	symbol_c param_value;
   296 	symbol_c param_value = *prev_il_instruction;
   297 	copy_candidate_datatype_list(prev_il_instruction/*from*/, &param_value/*to*/);
       
   298 	
   297 	
   299 	identifier_c variable_name(param_name);
   298 	identifier_c variable_name(param_name);
   300 	// SYM_REF1(il_assign_operator_c, variable_name)
   299 	// SYM_REF1(il_assign_operator_c, variable_name)
   301 	il_assign_operator_c il_assign_operator(&variable_name);  
   300 	il_assign_operator_c il_assign_operator(&variable_name);  
   302 	// SYM_REF3(il_param_assignment_c, il_assign_operator, il_operand, simple_instr_list)
   301 	// SYM_REF3(il_param_assignment_c, il_assign_operator, il_operand, simple_instr_list)
   859 /* NOTE: The parameters 'called_function_declaration' and 'extensible_param_count' are used to pass data between the stage 3 and stage 4. */
   858 /* NOTE: The parameters 'called_function_declaration' and 'extensible_param_count' are used to pass data between the stage 3 and stage 4. */
   860 // SYM_REF2(il_function_call_c, function_name, il_operand_list, symbol_c *called_function_declaration; int extensible_param_count;)
   859 // SYM_REF2(il_function_call_c, function_name, il_operand_list, symbol_c *called_function_declaration; int extensible_param_count;)
   861 void *fill_candidate_datatypes_c::visit(il_function_call_c *symbol) {
   860 void *fill_candidate_datatypes_c::visit(il_function_call_c *symbol) {
   862 	/* The first parameter of a non formal function call in IL will be the 'current value' (i.e. the prev_il_instruction)
   861 	/* The first parameter of a non formal function call in IL will be the 'current value' (i.e. the prev_il_instruction)
   863 	 * In order to be able to handle this without coding special cases, we will simply prepend that symbol
   862 	 * In order to be able to handle this without coding special cases, we will simply prepend that symbol
   864 	 * to the il_operand_list, and remove it later (in the print_datatypes_error_c).
   863 	 * to the il_operand_list, and remove it after calling handle_function_call().
   865 	 *
   864 	 *
   866 	 * However, if no further paramters are given, then il_operand_list will be NULL, and we will
   865 	 * However, if no further paramters are given, then il_operand_list will be NULL, and we will
   867 	 * need to create a new object to hold the pointer to prev_il_instruction.
   866 	 * need to create a new object to hold the pointer to prev_il_instruction.
   868 	 * This change will also be undone later in print_datatypes_error_c.
   867 	 * This change will also be undone later in print_datatypes_error_c.
   869 	 */
   868 	 */
   870 	if (NULL == symbol->il_operand_list)  symbol->il_operand_list = new il_operand_list_c;
   869 	if (NULL == symbol->il_operand_list)  symbol->il_operand_list = new il_operand_list_c;
   871 	if (NULL == symbol->il_operand_list)  ERROR;
   870 	if (NULL == symbol->il_operand_list)  ERROR;
   872 
   871 
   873 	symbol->il_operand_list->accept(*this);
   872 	symbol->il_operand_list->accept(*this);
   874 
   873 
   875 	if (NULL == prev_il_instruction)      return NULL;
   874 	if (NULL != prev_il_instruction) {
   876 	((list_c *)symbol->il_operand_list)->insert_element(prev_il_instruction, 0);	
   875 		((list_c *)symbol->il_operand_list)->insert_element(prev_il_instruction, 0);	
   877 
   876 
   878 	generic_function_call_t fcall_param = {
   877 		generic_function_call_t fcall_param = {
   879 		/* fcall_param.function_name               = */ symbol->function_name,
   878 			/* fcall_param.function_name               = */ symbol->function_name,
   880 		/* fcall_param.nonformal_operand_list      = */ symbol->il_operand_list,
   879 			/* fcall_param.nonformal_operand_list      = */ symbol->il_operand_list,
   881 		/* fcall_param.formal_operand_list         = */ NULL,
   880 			/* fcall_param.formal_operand_list         = */ NULL,
   882 		/* enum {POU_FB, POU_function} POU_type    = */ generic_function_call_t::POU_function,
   881 			/* enum {POU_FB, POU_function} POU_type    = */ generic_function_call_t::POU_function,
   883 		/* fcall_param.candidate_functions         = */ symbol->candidate_functions,
   882 			/* fcall_param.candidate_functions         = */ symbol->candidate_functions,
   884 		/* fcall_param.called_function_declaration = */ symbol->called_function_declaration,
   883 			/* fcall_param.called_function_declaration = */ symbol->called_function_declaration,
   885 		/* fcall_param.extensible_param_count      = */ symbol->extensible_param_count
   884 			/* fcall_param.extensible_param_count      = */ symbol->extensible_param_count
   886 	};
   885 		};
   887 	handle_function_call(symbol, fcall_param);
   886 		handle_function_call(symbol, fcall_param);
   888 
   887 
       
   888 		/* Undo the changes to the abstract syntax tree we made above... */
       
   889 		((list_c *)symbol->il_operand_list)->remove_element(0);
       
   890 	}
       
   891 
       
   892 	/* Undo the changes to the abstract syntax tree we made above... */
       
   893 	if (((list_c *)symbol->il_operand_list)->n == 0) {
       
   894 		/* if the list becomes empty, then that means that it did not exist before we made these changes, so we delete it! */
       
   895 		delete 	symbol->il_operand_list;
       
   896 		symbol->il_operand_list = NULL;
       
   897 	}
       
   898 	
   889 	if (debug) std::cout << "il_function_call_c [" << symbol->candidate_datatypes.size() << "] result.\n";
   899 	if (debug) std::cout << "il_function_call_c [" << symbol->candidate_datatypes.size() << "] result.\n";
   890 	return NULL;
   900 	return NULL;
   891 }
   901 }
   892 
   902 
   893 
   903