stage3/fill_candidate_datatypes.cc
changeset 420 866eb35e4e14
parent 419 6384168a8e95
child 421 840cb1e1e177
equal deleted inserted replaced
419:6384168a8e95 420:866eb35e4e14
    61 		if ((typeid(*left_type) == typeid(*widen_table[k].left)) && (typeid(*right_type) == typeid(*widen_table[k].right)))
    61 		if ((typeid(*left_type) == typeid(*widen_table[k].left)) && (typeid(*right_type) == typeid(*widen_table[k].right)))
    62 			return widen_table[k].result;
    62 			return widen_table[k].result;
    63 	return NULL;
    63 	return NULL;
    64 }
    64 }
    65 
    65 
    66 void fill_candidate_datatypes_c::match_nonformal_call(symbol_c *f_call, symbol_c *f_decl, int *error_count) {
    66 /* returns true if compatible function/FB invocation, otherwise returns false */
       
    67 bool fill_candidate_datatypes_c::match_nonformal_call(symbol_c *f_call, symbol_c *f_decl) {
    67 	symbol_c *call_param_value,  *param_type;
    68 	symbol_c *call_param_value,  *param_type;
    68 	identifier_c *param_name;
    69 	identifier_c *param_name;
    69 	function_param_iterator_c       fp_iterator(f_decl);
    70 	function_param_iterator_c       fp_iterator(f_decl);
    70 	function_call_param_iterator_c fcp_iterator(f_call);
    71 	function_call_param_iterator_c fcp_iterator(f_call);
    71 	int extensible_parameter_highest_index = -1;
    72 	int extensible_parameter_highest_index = -1;
    72 	unsigned int i;
    73 	unsigned int i;
    73 
    74 
    74 	/* reset error counter */
       
    75 	if (error_count != NULL) *error_count = 0;
       
    76 	/* Iterating through the non-formal parameters of the function call */
    75 	/* Iterating through the non-formal parameters of the function call */
    77 	while((call_param_value = fcp_iterator.next_nf()) != NULL) {
    76 	while((call_param_value = fcp_iterator.next_nf()) != NULL) {
    78 		/* Obtaining the type of the value being passed in the function call */
       
    79 		std::vector <symbol_c *>&call_param_types = call_param_value->candidate_datatypes;
       
    80 		/* Iterate to the next parameter of the function being called.
    77 		/* Iterate to the next parameter of the function being called.
    81 		 * Get the name of that parameter, and ignore if EN or ENO.
    78 		 * Get the name of that parameter, and ignore if EN or ENO.
    82 		 */
    79 		 */
    83 		do {
    80 		do {
    84 			param_name = fp_iterator.next();
    81 			param_name = fp_iterator.next();
    85 			/* If there is no other parameter declared, then we are passing too many parameters... */
    82 			/* If there is no other parameter declared, then we are passing too many parameters... */
    86 			if(param_name == NULL) {
    83 			if(param_name == NULL) return false;
    87 				(*error_count)++;
       
    88 				return;
       
    89 			}
       
    90 		} while ((strcmp(param_name->value, "EN") == 0) || (strcmp(param_name->value, "ENO") == 0));
    84 		} while ((strcmp(param_name->value, "EN") == 0) || (strcmp(param_name->value, "ENO") == 0));
    91 
    85 
    92 		/* Get the parameter type */
    86 		/* Get the parameter type */
    93 		param_type = base_type(fp_iterator.param_type());
    87 		param_type = base_type(fp_iterator.param_type());
    94 		for(i = 0; i < call_param_types.size(); i++) {
    88 		
    95 			/* If the declared parameter and the parameter from the function call do not have the same type */
    89 		/* check whether one of the candidate_data_types of the value being passed is the same as the param_type */
    96 			if(is_type_equal(param_type, call_param_types[i])) {
    90 		for(i = 0; i < call_param_value->candidate_datatypes.size(); i++) {
    97 				break;
    91 			/* If found (correct data type being passed), then stop the search */
    98 			}
    92 			if(is_type_equal(param_type, call_param_value->candidate_datatypes[i])) break;
    99 		}
    93 		}
   100 		if (i >= call_param_types.size()) (*error_count)++;
    94 		/* if we reached the end of the loop, and no compatible type found, then return false */
   101 	}
    95 		if (i >= call_param_value->candidate_datatypes.size()) return false;
   102 }
    96 	}
   103 
    97 	/* call is compatible! */
   104 void fill_candidate_datatypes_c::match_formal_call(symbol_c *f_call, symbol_c *f_decl, int *error_count) {
    98 	return true;
       
    99 }
       
   100 
       
   101 /* returns true if compatible function/FB invocation, otherwise returns false */
       
   102 bool fill_candidate_datatypes_c::match_formal_call(symbol_c *f_call, symbol_c *f_decl) {
   105 	symbol_c *call_param_value, *call_param_name, *param_type;
   103 	symbol_c *call_param_value, *call_param_name, *param_type;
   106 	symbol_c *verify_duplicate_param;
   104 	symbol_c *verify_duplicate_param;
   107 	identifier_c *param_name;
   105 	identifier_c *param_name;
   108 	function_param_iterator_c       fp_iterator(f_decl);
   106 	function_param_iterator_c       fp_iterator(f_decl);
   109 	function_call_param_iterator_c fcp_iterator(f_call);
   107 	function_call_param_iterator_c fcp_iterator(f_call);
   110 	int extensible_parameter_highest_index = -1;
   108 	int extensible_parameter_highest_index = -1;
   111 	identifier_c *extensible_parameter_name;
   109 	identifier_c *extensible_parameter_name;
   112 	unsigned int i;
   110 	unsigned int i;
   113 
   111 
   114 	/* reset error counter */
       
   115 	if (error_count != NULL) *error_count = 0;
       
   116 
       
   117 	/* Iterating through the formal parameters of the function call */
   112 	/* Iterating through the formal parameters of the function call */
   118 	while((call_param_name = fcp_iterator.next_f()) != NULL) {
   113 	while((call_param_name = fcp_iterator.next_f()) != NULL) {
   119 
   114 
   120 		/* Obtaining the value being passed in the function call */
   115 		/* Obtaining the value being passed in the function call */
   121 		call_param_value = fcp_iterator.get_current_value();
   116 		call_param_value = fcp_iterator.get_current_value();
   123 		if (NULL == call_param_value) ERROR;
   118 		if (NULL == call_param_value) ERROR;
   124 
   119 
   125 		/* Checking if there are duplicated parameter values */
   120 		/* Checking if there are duplicated parameter values */
   126 		verify_duplicate_param = fcp_iterator.search_f(call_param_name);
   121 		verify_duplicate_param = fcp_iterator.search_f(call_param_name);
   127 		if(verify_duplicate_param != call_param_value)
   122 		if(verify_duplicate_param != call_param_value)
   128 			(*error_count)++;
   123 			return false;
   129 
   124 
   130 		/* Obtaining the type of the value being passed in the function call */
   125 		/* Obtaining the type of the value being passed in the function call */
   131 		std::vector <symbol_c *>&call_param_types = call_param_value->candidate_datatypes;
   126 		std::vector <symbol_c *>&call_param_types = call_param_value->candidate_datatypes;
   132 
   127 
   133 
   128 
   134 		/* Find the corresponding parameter in function declaration */
   129 		/* Find the corresponding parameter in function declaration */
   135 		param_name = fp_iterator.search(call_param_name);
   130 		param_name = fp_iterator.search(call_param_name);
   136 		if(param_name == NULL) {
   131 		if(param_name == NULL) {
   137 			(*error_count)++;
   132 			return false;
   138 		} else {
   133 		} else {
   139 			/* Get the parameter type */
   134 			/* Get the parameter type */
   140 			param_type = base_type(fp_iterator.param_type());
   135 			param_type = base_type(fp_iterator.param_type());
   141 			for (i = 0; i < call_param_types.size(); i++) {
   136 			for (i = 0; i < call_param_types.size(); i++) {
   142 				/* If the declared parameter and the parameter from the function call have the same type */
   137 				/* If the declared parameter and the parameter from the function call have the same type */
   143 				if(is_type_equal(param_type, call_param_types[i]))
   138 				if(is_type_equal(param_type, call_param_types[i]))
   144 					break;
   139 					break;
   145 			}
   140 			}
   146 			if (i >= call_param_types.size()) (*error_count)++;
   141 			if (i >= call_param_types.size())
   147 		}
   142 				return false;;
   148 	}
   143 		}
   149 
   144 	}
       
   145 	return true;
   150 }
   146 }
   151 
   147 
   152 /* a helper function... */
   148 /* a helper function... */
   153 symbol_c *fill_candidate_datatypes_c::base_type(symbol_c *symbol) {
   149 symbol_c *fill_candidate_datatypes_c::base_type(symbol_c *symbol) {
   154 	/* NOTE: symbol == NULL is valid. It will occur when, for e.g., an undefined/undeclared symbolic_variable is used
   150 	/* NOTE: symbol == NULL is valid. It will occur when, for e.g., an undefined/undeclared symbolic_variable is used
  1665 
  1661 
  1666 void *fill_candidate_datatypes_c::visit(function_invocation_c *symbol) {
  1662 void *fill_candidate_datatypes_c::visit(function_invocation_c *symbol) {
  1667 	function_declaration_c *f_decl;
  1663 	function_declaration_c *f_decl;
  1668 	list_c *parameter_list;
  1664 	list_c *parameter_list;
  1669 	list_c *parameter_candidate_datatypes;
  1665 	list_c *parameter_candidate_datatypes;
  1670 	symbol_c *parameter_type;
  1666 	symbol_c *returned_parameter_type;
  1671 	function_symtable_t::iterator lower = function_symtable.lower_bound(symbol->function_name);
  1667 	function_symtable_t::iterator lower = function_symtable.lower_bound(symbol->function_name);
  1672 	function_symtable_t::iterator upper = function_symtable.upper_bound(symbol->function_name);
  1668 	function_symtable_t::iterator upper = function_symtable.upper_bound(symbol->function_name);
  1673 	/* If the name of the function being called is not found in the function symbol table, then this is an invalid call */
  1669 	/* If the name of the function being called is not found in the function symbol table, then this is an invalid call */
  1674 	/* Since the lexical parser already checks for this, then if this occurs then we have an internal compiler error. */
  1670 	/* Since the lexical parser already checks for this, then if this occurs then we have an internal compiler error. */
  1675 	if (lower == function_symtable.end()) ERROR;
  1671 	if (lower == function_symtable.end()) ERROR;
  1681 	else ERROR;
  1677 	else ERROR;
  1682 	
  1678 	
  1683 	if (debug) std::cout << "function()\n";
  1679 	if (debug) std::cout << "function()\n";
  1684 	parameter_list->accept(*this);
  1680 	parameter_list->accept(*this);
  1685 	for(; lower != upper; lower++) {
  1681 	for(; lower != upper; lower++) {
  1686 		int error_count = 0;
  1682 		bool compatible = false;
  1687 		f_decl = function_symtable.get_value(lower);
  1683 		f_decl = function_symtable.get_value(lower);
  1688 		/* Check if function declaration in symbol_table is compatible with parameters */
  1684 		/* Check if function declaration in symbol_table is compatible with parameters */
  1689 		if (NULL != symbol->nonformal_param_list)  match_nonformal_call(symbol, f_decl, &error_count);
  1685 		if (NULL != symbol->nonformal_param_list)  compatible=match_nonformal_call(symbol, f_decl);
  1690 		if (NULL != symbol->   formal_param_list)     match_formal_call(symbol, f_decl, &error_count);
  1686 		if (NULL != symbol->   formal_param_list)  compatible=   match_formal_call(symbol, f_decl);
  1691 		if (0 == error_count) {
  1687 		if (compatible) {
  1692 			/* Add basetype matching function only if not present */
  1688 			/* Add the data type returned by the called functions. 
       
  1689 			 * However, only do this if this data type is not already present in the candidate_datatypes list_c
       
  1690 			 */
  1693 			unsigned int k;
  1691 			unsigned int k;
  1694 			parameter_type = base_type(f_decl->type_name);
  1692 			returned_parameter_type = base_type(f_decl->type_name);
  1695 			for(k = 0; k < symbol->candidate_datatypes.size(); k++) {
  1693 			for(k = 0; k < symbol->candidate_datatypes.size(); k++) {
  1696 				if (is_type_equal(parameter_type, symbol->candidate_datatypes[k]))
  1694 				if (is_type_equal(returned_parameter_type, symbol->candidate_datatypes[k]))
  1697 					break;
  1695 					break;
  1698 			}
  1696 			}
  1699 			if (k >= symbol->candidate_datatypes.size())
  1697 			if (k >= symbol->candidate_datatypes.size()) {
  1700 				symbol->candidate_datatypes.push_back(parameter_type);
  1698 				symbol->candidate_datatypes.push_back(returned_parameter_type);
       
  1699 				symbol->candidate_functions.push_back(f_decl);
       
  1700 			}
  1701 		}
  1701 		}
  1702 	}
  1702 	}
  1703 	if (debug) std::cout << "end_function() [" << symbol->candidate_datatypes.size() << "] result.\n";
  1703 	if (debug) std::cout << "end_function() [" << symbol->candidate_datatypes.size() << "] result.\n";
  1704 	return NULL;
  1704 	return NULL;
  1705 }
  1705 }
  1736 
  1736 
  1737 /*****************************************/
  1737 /*****************************************/
  1738 /* B 3.2.2 Subprogram Control Statements */
  1738 /* B 3.2.2 Subprogram Control Statements */
  1739 /*****************************************/
  1739 /*****************************************/
  1740 void *fill_candidate_datatypes_c::visit(fb_invocation_c *symbol) {
  1740 void *fill_candidate_datatypes_c::visit(fb_invocation_c *symbol) {
       
  1741 	bool compatible = false;
  1741 	symbol_c *fb_decl = search_varfb_instance_type->get_basetype_decl(symbol->fb_name);
  1742 	symbol_c *fb_decl = search_varfb_instance_type->get_basetype_decl(symbol->fb_name);
  1742 
  1743 	
  1743 	if (NULL == fb_decl) ERROR;
  1744 	if (NULL == fb_decl) ERROR;
  1744 	if (symbol->   formal_param_list != NULL) match_formal_call(symbol, fb_decl);
  1745 	if (symbol->   formal_param_list != NULL) {
  1745 	if (symbol->nonformal_param_list != NULL) match_nonformal_call(symbol, fb_decl);
  1746 		symbol->formal_param_list->accept(*this);
       
  1747 		compatible = match_formal_call(symbol, fb_decl);
       
  1748 	}
       
  1749 	if (symbol->nonformal_param_list != NULL) {
       
  1750 		symbol->nonformal_param_list->accept(*this);
       
  1751 		compatible = match_nonformal_call(symbol, fb_decl);
       
  1752 	}
  1746 	if (debug) std::cout << "FB [] ==> "  << symbol->candidate_datatypes.size() << " result.\n";
  1753 	if (debug) std::cout << "FB [] ==> "  << symbol->candidate_datatypes.size() << " result.\n";
  1747 	return NULL;
  1754 	return NULL;
  1748 }
  1755 }
  1749 
  1756 
  1750 
  1757