stage3/fill_candidate_datatypes.cc
changeset 455 933c0dccc82f
parent 454 099aa5d655de
child 456 ca8d98289ff9
equal deleted inserted replaced
454:099aa5d655de 455:933c0dccc82f
    89 			param_name = fp_iterator.next();
    89 			param_name = fp_iterator.next();
    90 			/* If there is no other parameter declared, then we are passing too many parameters... */
    90 			/* If there is no other parameter declared, then we are passing too many parameters... */
    91 			if(param_name == NULL) return false;
    91 			if(param_name == NULL) return false;
    92 		} while ((strcmp(param_name->value, "EN") == 0) || (strcmp(param_name->value, "ENO") == 0));
    92 		} while ((strcmp(param_name->value, "EN") == 0) || (strcmp(param_name->value, "ENO") == 0));
    93 
    93 
       
    94 		/* TODO: verify if it is lvalue when INOUT or OUTPUT parameters! */
    94 		/* Get the parameter type */
    95 		/* Get the parameter type */
    95 		param_datatype = base_type(fp_iterator.param_type());
    96 		param_datatype = base_type(fp_iterator.param_type());
    96 		
    97 		
    97 		/* check whether one of the candidate_data_types of the value being passed is the same as the param_type */
    98 		/* check whether one of the candidate_data_types of the value being passed is the same as the param_type */
    98 		if (search_in_candidate_datatype_list(param_datatype, call_param_value->candidate_datatypes) < 0)
    99 		if (search_in_candidate_datatype_list(param_datatype, call_param_value->candidate_datatypes) < 0)
   104 
   105 
   105 
   106 
   106 
   107 
   107 /* returns true if compatible function/FB invocation, otherwise returns false */
   108 /* returns true if compatible function/FB invocation, otherwise returns false */
   108 /* Assumes that the candidate_datatype lists of all the parameters being passed haved already been filled in */
   109 /* Assumes that the candidate_datatype lists of all the parameters being passed haved already been filled in */
   109 bool fill_candidate_datatypes_c::match_formal_call(symbol_c *f_call, symbol_c *f_decl) {
   110 bool fill_candidate_datatypes_c::match_formal_call(symbol_c *f_call, symbol_c *f_decl, symbol_c **first_param_datatype) {
   110 	symbol_c *call_param_value, *call_param_name, *param_datatype;
   111 	symbol_c *call_param_value, *call_param_name, *param_datatype;
   111 	symbol_c *verify_duplicate_param;
   112 	symbol_c *verify_duplicate_param;
   112 	identifier_c *param_name;
   113 	identifier_c *param_name;
   113 	function_param_iterator_c       fp_iterator(f_decl);
   114 	function_param_iterator_c       fp_iterator(f_decl);
   114 	function_call_param_iterator_c fcp_iterator(f_call);
   115 	function_call_param_iterator_c fcp_iterator(f_call);
   115 	int extensible_parameter_highest_index = -1;
   116 	int extensible_parameter_highest_index = -1;
   116 	identifier_c *extensible_parameter_name;
   117 	identifier_c *extensible_parameter_name;
   117 	unsigned int i;
   118 	unsigned int i;
       
   119 	bool is_first_param = true;
   118 
   120 
   119 	/* Iterating through the formal parameters of the function call */
   121 	/* Iterating through the formal parameters of the function call */
   120 	while((call_param_name = fcp_iterator.next_f()) != NULL) {
   122 	while((call_param_name = fcp_iterator.next_f()) != NULL) {
   121 		/* Obtaining the value being passed in the function call */
   123 		/* Obtaining the value being passed in the function call */
   122 		call_param_value = fcp_iterator.get_current_value();
   124 		call_param_value = fcp_iterator.get_current_value();
   153 		} else ERROR;
   155 		} else ERROR;
   154 		
   156 		
   155 		/* check whether one of the candidate_data_types of the value being passed is the same as the param_type */
   157 		/* check whether one of the candidate_data_types of the value being passed is the same as the param_type */
   156 		if (search_in_candidate_datatype_list(param_datatype, call_param_types) < 0)
   158 		if (search_in_candidate_datatype_list(param_datatype, call_param_types) < 0)
   157 			return false; /* return false if param_type not in the list! */
   159 			return false; /* return false if param_type not in the list! */
       
   160 		
       
   161 		/* If this is the first parameter, then copy the datatype to *first_param_datatype */
       
   162 		if (is_first_param)
       
   163 			if (NULL != first_param_datatype)
       
   164 				*first_param_datatype = param_datatype;
       
   165 		is_first_param = false;
   158 	}
   166 	}
   159 	/* call is compatible! */
   167 	/* call is compatible! */
   160 	return true;
   168 	return true;
   161 }
   169 }
   162 
   170 
   253 
   261 
   254 
   262 
   255 /* handle implicit FB call in IL.
   263 /* handle implicit FB call in IL.
   256  * e.g.  CLK ton_var
   264  * e.g.  CLK ton_var
   257  *        CU counter_var
   265  *        CU counter_var
   258  *
       
   259  * The algorithm will be to build a fake il_fb_call_c equivalent to the implicit IL FB call, and let 
       
   260  * the visit(il_fb_call_c *) method handle it!
       
   261  */
   266  */
   262 void fill_candidate_datatypes_c::handle_implicit_il_fb_call(symbol_c *il_instruction, const char *param_name, symbol_c *&called_fb_declaration) {
   267 void fill_candidate_datatypes_c::handle_implicit_il_fb_call(symbol_c *il_instruction, const char *param_name, symbol_c *&called_fb_declaration) {
   263 	if (NULL == il_operand)
       
   264 		/* No FB to call was specified. There is nothing we can do... */
       
   265 		return;
       
   266 
       
   267 	symbol_c *fb_type_id = search_varfb_instance_type->get_basetype_id(il_operand);
   268 	symbol_c *fb_type_id = search_varfb_instance_type->get_basetype_id(il_operand);
   268 	/* This is a call to a non-declared FB/Variable is a semantic error (which is currently caught by stage 2, so this should never occur)
   269   	/* Although a call to a non-declared FB is a semantic error, this is currently caught by stage 2! */
   269 	 * or no operand was given (il_operand == NULL). In this case, we just give up!
   270 	if (NULL == fb_type_id) ERROR;
   270 	 */
       
   271 	if (NULL == fb_type_id)
       
   272 		return;
       
   273 
   271 
   274 	function_block_declaration_c *fb_decl = function_block_type_symtable.find_value(fb_type_id);
   272 	function_block_declaration_c *fb_decl = function_block_type_symtable.find_value(fb_type_id);
   275 	if (function_block_type_symtable.end_value() == fb_decl)
   273 	if (function_block_type_symtable.end_value() == fb_decl)
   276 		/* The il_operand is not the name of a FB instance. Most probably it is the name of a variable of some other type.
   274 		/* The il_operand is not the name of a FB instance. Most probably it is the name of a variable of some other type.
   277 		 * this is a smeantic error, so there is no way we can evaluate the rest of the code. We simply give up, and leave
   275 		 * this is a semantic error.
   278 		 * the candidate_datatype_list empty, and the called_fb_declaration pointing to NULL
       
   279 		 */
   276 		 */
   280 		return;
   277 		fb_decl = NULL;
   281 
   278 	
   282 	if (NULL == prev_il_instruction) {
   279 	/* The narrow_candidate_datatypes_c does not rely on this called_fb_declaration pointer being == NULL to conclude that
   283 		/* This IL implicit FB call (e.g. CLK ton_var) is not preceded by another IL instruction
   280 	 * we have a datatype incompatibility error, so we set it to fb_decl to allow the print_datatype_error_c to print out
   284 		 * (or list of instructions) that will set the IL current/default value.
   281 	 * more informative error messages!
   285 		 * We cannot proceed verifying type compatibility of something that does not ecist.
       
   286 		 */
       
   287 		return;
       
   288 	}
       
   289 
       
   290 	/* The value being passed to the 'param_name' parameter is actually the prev_il_instruction.
       
   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.
       
   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!
       
   295 	 */
   282 	 */
   296 	symbol_c param_value = *prev_il_instruction;
   283 	called_fb_declaration = fb_decl;
   297 	
   284 
   298 	identifier_c variable_name(param_name);
   285 	/* This implicit FB call does not change the value stored in the current/default IL variable */
   299 	// SYM_REF1(il_assign_operator_c, variable_name)
   286 	if (NULL != prev_il_instruction)
   300 	il_assign_operator_c il_assign_operator(&variable_name);  
   287 		copy_candidate_datatype_list(prev_il_instruction/*from*/, il_instruction/*to*/);
   301 	// SYM_REF3(il_param_assignment_c, il_assign_operator, il_operand, simple_instr_list)
   288 
   302 	il_param_assignment_c il_param_assignment(&il_assign_operator, &param_value/*il_operand*/, NULL);
   289 	if (debug) std::cout << "handle_implicit_il_fb_call() [" << prev_il_instruction->candidate_datatypes.size() << "] ==> " << il_instruction->candidate_datatypes.size() << " result.\n";
   303 	il_param_list_c il_param_list;
       
   304 	il_param_list.add_element(&il_param_assignment);
       
   305 	// SYM_REF4(il_fb_call_c, il_call_operator, fb_name, il_operand_list, il_param_list, symbol_c *called_fb_declaration)
       
   306 	il_fb_call_c il_fb_call(NULL, il_operand, NULL, &il_param_list);
       
   307 	
       
   308 	il_fb_call.accept(*this);
       
   309 	copy_candidate_datatype_list(&il_fb_call/*from*/, il_instruction/*to*/);
       
   310 	called_fb_declaration = il_fb_call.called_fb_declaration;
       
   311 }
   290 }
   312 
   291 
   313 
   292 
   314 /* a helper function... */
   293 /* a helper function... */
   315 symbol_c *fill_candidate_datatypes_c::base_type(symbol_c *symbol) {
   294 symbol_c *fill_candidate_datatypes_c::base_type(symbol_c *symbol) {
   721 
   700 
   722 
   701 
   723 /* subscript_list ',' subscript */
   702 /* subscript_list ',' subscript */
   724 // SYM_LIST(subscript_list_c)
   703 // SYM_LIST(subscript_list_c)
   725 /* NOTE: we inherit from iterator visitor, so we do not need to implement this method... */
   704 /* NOTE: we inherit from iterator visitor, so we do not need to implement this method... */
   726 #if 0
   705 // void *fill_candidate_datatypes_c::visit(subscript_list_c *symbol)
   727 void *fill_candidate_datatypes_c::visit(subscript_list_c *symbol) {
       
   728 }
       
   729 #endif
       
   730 
   706 
   731 
   707 
   732 /*  record_variable '.' field_selector */
   708 /*  record_variable '.' field_selector */
   733 /*  WARNING: input and/or output variables of function blocks
   709 /*  WARNING: input and/or output variables of function blocks
   734  *           may be accessed as fields of a structured variable!
   710  *           may be accessed as fields of a structured variable!
   794 
   770 
   795 /********************************/
   771 /********************************/
   796 /* B 1.7 Configuration elements */
   772 /* B 1.7 Configuration elements */
   797 /********************************/
   773 /********************************/
   798 void *fill_candidate_datatypes_c::visit(configuration_declaration_c *symbol) {
   774 void *fill_candidate_datatypes_c::visit(configuration_declaration_c *symbol) {
   799 #if 0
       
   800 	// TODO !!!
   775 	// TODO !!!
   801 	/* for the moment we must return NULL so semantic analysis of remaining code is not interrupted! */
   776 	/* for the moment we must return NULL so semantic analysis of remaining code is not interrupted! */
   802 #endif
       
   803 	return NULL;
   777 	return NULL;
   804 }
   778 }
   805 
   779 
   806 /****************************************/
   780 /****************************************/
   807 /* B.2 - Language IL (Instruction List) */
   781 /* B.2 - Language IL (Instruction List) */
   943  * | il_call_operator prev_declared_fb_name '(' eol_list il_param_list ')'
   917  * | il_call_operator prev_declared_fb_name '(' eol_list il_param_list ')'
   944  */
   918  */
   945 /* 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 */
   919 /* 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 */
   946 // SYM_REF4(il_fb_call_c, il_call_operator, fb_name, il_operand_list, il_param_list, symbol_c *called_fb_declaration)
   920 // SYM_REF4(il_fb_call_c, il_call_operator, fb_name, il_operand_list, il_param_list, symbol_c *called_fb_declaration)
   947 void *fill_candidate_datatypes_c::visit(il_fb_call_c *symbol) {
   921 void *fill_candidate_datatypes_c::visit(il_fb_call_c *symbol) {
   948 	bool compatible = false;
   922 	/* We do not call
   949 	symbol_c *fb_decl = search_varfb_instance_type->get_basetype_decl(symbol->fb_name);
   923 	 * fb_decl = search_varfb_instance_type->get_basetype_decl(symbol->fb_name);
       
   924 	 * because we want to make sure it is a FB instance, and not some other data type...
       
   925 	 */
       
   926 	symbol_c *fb_type_id = search_varfb_instance_type->get_basetype_id(symbol->fb_name);
       
   927 	/* Although a call to a non-declared FB is a semantic error, this is currently caught by stage 2! */
       
   928 	if (NULL == fb_type_id) ERROR;
       
   929 
       
   930  	function_block_declaration_c *fb_decl = function_block_type_symtable.find_value(fb_type_id);
       
   931 	if (function_block_type_symtable.end_value() == fb_decl) 
       
   932 		/* The fb_name not the name of a FB instance. Most probably it is the name of a variable of some other type. */
       
   933 		fb_decl = NULL;
       
   934 
   950 	/* Although a call to a non-declared FB is a semantic error, this is currently caught by stage 2! */
   935 	/* Although a call to a non-declared FB is a semantic error, this is currently caught by stage 2! */
   951 	if (NULL == fb_decl) ERROR;
   936 	if (NULL == fb_decl) ERROR;
   952 
   937 
   953 	if (symbol->  il_param_list != NULL) {
   938 	if (symbol->  il_param_list != NULL) symbol->il_param_list->accept(*this);
   954 		symbol->il_param_list->accept(*this);
   939 	if (symbol->il_operand_list != NULL) symbol->il_operand_list->accept(*this);
   955 		compatible = match_formal_call(symbol, fb_decl);
       
   956 	}
       
   957 	if (symbol->il_operand_list != NULL) {
       
   958 		symbol->il_operand_list->accept(*this);
       
   959 		compatible = match_nonformal_call(symbol, fb_decl);
       
   960 	}
       
   961 
   940 
   962 	/* The print_datatypes_error_c does not rely on this called_fb_declaration pointer being != NULL to conclude that
   941 	/* The print_datatypes_error_c does not rely on this called_fb_declaration pointer being != NULL to conclude that
   963 	 * we have a datat type incompatibility error, so setting it to the correct fb_decl is actually safe,
   942 	 * we have a datat type incompatibility error, so setting it to the correct fb_decl is actually safe,
   964 	 * as the compiler will never reach the compilation stage!
   943 	 * as the compiler will never reach the compilation stage!
   965 	 */
   944 	 */
   966 	symbol->called_fb_declaration = fb_decl;
   945 	symbol->called_fb_declaration = fb_decl;
   967 
   946 
   968 	/* This object has the same candidate datatypes as the prev_il_instruction, since it does not change the value stored in the current/default IL variable. */
   947 	/* Let the il_call_operator (CAL, CALC, or CALCN) determine the candidate datatypes of the il_fb_call_c... */
   969 	copy_candidate_datatype_list(prev_il_instruction/*from*/, symbol/*to*/);
   948 	/* NOTE: We ignore whether the call is 'compatible' or not when filling in the candidate datatypes list.
       
   949 	 *       Even if it is not compatible, we fill in the candidate datatypes list correctly so that the following
       
   950 	 *       IL instructions may be handled correctly and debuged.
       
   951 	 *       Doing this is actually safe, as the parameter_list will still contain errors that will be found by
       
   952 	 *       print_datatypes_error_c, so the code will never reach stage 4!
       
   953 	 */
       
   954 	symbol->il_call_operator->accept(*this);
       
   955 	copy_candidate_datatype_list(symbol->il_call_operator/*from*/, symbol/*to*/);
   970 
   956 
   971 	if (debug) std::cout << "FB [] ==> "  << symbol->candidate_datatypes.size() << " result.\n";
   957 	if (debug) std::cout << "FB [] ==> "  << symbol->candidate_datatypes.size() << " result.\n";
   972 	return NULL;
   958 	return NULL;
   973 }
   959 }
   974 
   960 
  2000 
  1986 
  2001 /*****************************************/
  1987 /*****************************************/
  2002 /* B 3.2.2 Subprogram Control Statements */
  1988 /* B 3.2.2 Subprogram Control Statements */
  2003 /*****************************************/
  1989 /*****************************************/
  2004 void *fill_candidate_datatypes_c::visit(fb_invocation_c *symbol) {
  1990 void *fill_candidate_datatypes_c::visit(fb_invocation_c *symbol) {
  2005 	bool compatible = false;
  1991 	symbol_c *fb_type_id = search_varfb_instance_type->get_basetype_id(symbol->fb_name);
  2006 	symbol_c *fb_decl = search_varfb_instance_type->get_basetype_decl(symbol->fb_name);
  1992 	/* Although a call to a non-declared FB is a semantic error, this is currently caught by stage 2! */
       
  1993 	if (NULL == fb_type_id) ERROR;
       
  1994 
       
  1995 	function_block_declaration_c *fb_decl = function_block_type_symtable.find_value(fb_type_id);
       
  1996 	if (function_block_type_symtable.end_value() == fb_decl) 
       
  1997 		/* The fb_name not the name of a FB instance. Most probably it is the name of a variable of some other type. */
       
  1998 		fb_decl = NULL;
       
  1999 
  2007 	/* Although a call to a non-declared FB is a semantic error, this is currently caught by stage 2! */
  2000 	/* Although a call to a non-declared FB is a semantic error, this is currently caught by stage 2! */
  2008 	if (NULL == fb_decl) ERROR;
  2001 	if (NULL == fb_decl) ERROR;
  2009 
  2002 	
  2010 	if (symbol->   formal_param_list != NULL) {
  2003 	if (symbol->   formal_param_list != NULL) symbol->formal_param_list->accept(*this);
  2011 		symbol->formal_param_list->accept(*this);
  2004 	if (symbol->nonformal_param_list != NULL) symbol->nonformal_param_list->accept(*this);
  2012 		compatible = match_formal_call(symbol, fb_decl);
       
  2013 	}
       
  2014 	if (symbol->nonformal_param_list != NULL) {
       
  2015 		symbol->nonformal_param_list->accept(*this);
       
  2016 		compatible = match_nonformal_call(symbol, fb_decl);
       
  2017 	}
       
  2018 
  2005 
  2019 	/* The print_datatypes_error_c does not rely on this called_fb_declaration pointer being != NULL to conclude that
  2006 	/* The print_datatypes_error_c does not rely on this called_fb_declaration pointer being != NULL to conclude that
  2020 	 * we have a datat type incompatibility error, so setting it to the correct fb_decl is actually safe,
  2007 	 * we have a datat type incompatibility error, so setting it to the correct fb_decl is actually safe,
  2021 	 * as the compiler will never reach the compilation stage!
  2008 	 * as the compiler will never reach the compilation stage!
  2022 	 */
  2009 	 */