stage3/narrow_candidate_datatypes.cc
changeset 421 840cb1e1e177
parent 417 d48f53715f77
child 423 f4a2d400ddbd
equal deleted inserted replaced
420:866eb35e4e14 421:840cb1e1e177
    63 		}
    63 		}
    64 	}
    64 	}
    65 	return false;
    65 	return false;
    66 }
    66 }
    67 
    67 
    68 void narrow_candidate_datatypes_c::narrow_nonformal_call(symbol_c *f_call, symbol_c *f_decl) {
    68 void narrow_candidate_datatypes_c::narrow_nonformal_call(symbol_c *f_call, symbol_c *f_decl, int *ext_parm_count) {
    69 	symbol_c *call_param_value,  *param_type;
    69 	symbol_c *call_param_value,  *param_type;
    70 	identifier_c *param_name;
    70 	identifier_c *param_name;
    71 	function_param_iterator_c       fp_iterator(f_decl);
    71 	function_param_iterator_c       fp_iterator(f_decl);
    72 	function_call_param_iterator_c fcp_iterator(f_call);
    72 	function_call_param_iterator_c fcp_iterator(f_call);
    73 	int extensible_parameter_highest_index = -1;
    73 	int extensible_parameter_highest_index = -1;
    74 	identifier_c *extensible_parameter_name;
       
    75 	unsigned int i;
    74 	unsigned int i;
    76 
    75 
       
    76 	if (NULL != ext_parm_count) *ext_parm_count = -1;
    77 
    77 
    78 	/* Iterating through the non-formal parameters of the function call */
    78 	/* Iterating through the non-formal parameters of the function call */
    79 	while((call_param_value = fcp_iterator.next_nf()) != NULL) {
    79 	while((call_param_value = fcp_iterator.next_nf()) != NULL) {
    80 		/* Obtaining the type of the value being passed in the function call */
    80 		/* Obtaining the type of the value being passed in the function call */
    81 		/* Iterate to the next parameter of the function being called.
    81 		/* Iterate to the next parameter of the function being called.
    82 		 * Get the name of that parameter, and ignore if EN or ENO.
    82 		 * Get the name of that parameter, and ignore if EN or ENO.
    83 		 */
    83 		 */
    84 		do {
    84 		do {
    85 			param_name = fp_iterator.next();
    85 			param_name = fp_iterator.next();
    86 			/* If there is no other parameter declared, then we are passing too many parameters... */
    86 			/* If there is no other parameter declared, then we are passing too many parameters... */
    87 			if(param_name == NULL) {
    87 			/* This error should have been caught in fill_candidate_datatypes_c */
    88 				return;
    88 			if(param_name == NULL) ERROR;
    89 			}
       
    90 		} while ((strcmp(param_name->value, "EN") == 0) || (strcmp(param_name->value, "ENO") == 0));
    89 		} while ((strcmp(param_name->value, "EN") == 0) || (strcmp(param_name->value, "ENO") == 0));
    91 
    90 
    92 		/* Get the parameter type */
    91 		/* Set the desired datatype for this parameter, and call it recursively. */
    93 		call_param_value->datatype = base_type(fp_iterator.param_type());
    92 		call_param_value->datatype = base_type(fp_iterator.param_type());
    94 		call_param_value->accept(*this);
    93 		call_param_value->accept(*this);
    95 		if (extensible_parameter_highest_index < fp_iterator.extensible_param_index()) {
    94 
       
    95 		if (extensible_parameter_highest_index < fp_iterator.extensible_param_index())
    96 			extensible_parameter_highest_index = fp_iterator.extensible_param_index();
    96 			extensible_parameter_highest_index = fp_iterator.extensible_param_index();
    97 			extensible_parameter_name = param_name;
    97 	}
    98 		}
    98 	/* call is compatible! */
    99 	}
    99 
   100     int extensible_param_count = -1;
   100 	/* In the case of a call to an extensible function, we store the highest index 
   101     if (extensible_parameter_highest_index >=0) /* if call to extensible function */
   101 	 * of the extensible parameters this particular call uses, in the symbol_c object
   102       extensible_param_count = 1 + extensible_parameter_highest_index - fp_iterator.first_extensible_param_index();
   102 	 * of the function call itself!
   103     function_invocation_c  *function_invocation  = dynamic_cast<function_invocation_c  *>(f_call);
   103 	 * In calls to non-extensible functions, this value will be set to -1.
   104     if (function_invocation  != NULL) function_invocation->extensible_param_count = extensible_param_count;
   104 	 * This information is later used in stage4 to correctly generate the
   105 
   105 	 * output code.
   106 }
   106 	 */
   107 
   107 	if ((NULL != ext_parm_count) && (extensible_parameter_highest_index >=0) /* if call to extensible function */)
   108 void narrow_candidate_datatypes_c::narrow_formal_call(symbol_c *f_call, symbol_c *f_decl) {
   108 		*ext_parm_count = 1 + extensible_parameter_highest_index - fp_iterator.first_extensible_param_index();
       
   109 }
       
   110 
       
   111 
       
   112 
       
   113 void narrow_candidate_datatypes_c::narrow_formal_call(symbol_c *f_call, symbol_c *f_decl, int *ext_parm_count) {
   109 	symbol_c *call_param_value, *call_param_name, *param_type;
   114 	symbol_c *call_param_value, *call_param_name, *param_type;
   110 	symbol_c *verify_duplicate_param;
   115 	symbol_c *verify_duplicate_param;
   111 	identifier_c *param_name;
   116 	identifier_c *param_name;
   112 	function_param_iterator_c       fp_iterator(f_decl);
   117 	function_param_iterator_c       fp_iterator(f_decl);
   113 	function_call_param_iterator_c fcp_iterator(f_call);
   118 	function_call_param_iterator_c fcp_iterator(f_call);
   114 	int extensible_parameter_highest_index = -1;
   119 	int extensible_parameter_highest_index = -1;
   115 	identifier_c *extensible_parameter_name;
   120 	identifier_c *extensible_parameter_name;
   116 	unsigned int i;
   121 	unsigned int i;
   117 
   122 
       
   123 	if (NULL != ext_parm_count) *ext_parm_count = -1;
   118 
   124 
   119 	/* Iterating through the formal parameters of the function call */
   125 	/* Iterating through the formal parameters of the function call */
   120 	while((call_param_name = fcp_iterator.next_f()) != NULL) {
   126 	while((call_param_name = fcp_iterator.next_f()) != NULL) {
   121 
   127 
   122 		/* Obtaining the value being passed in the function call */
   128 		/* Obtaining the value being passed in the function call */
   125 		if (NULL == call_param_value) ERROR;
   131 		if (NULL == call_param_value) ERROR;
   126 
   132 
   127 		/* Find the corresponding parameter in function declaration */
   133 		/* Find the corresponding parameter in function declaration */
   128 		param_name = fp_iterator.search(call_param_name);
   134 		param_name = fp_iterator.search(call_param_name);
   129 
   135 
   130 		/* Get the parameter type */
   136 		/* Set the desired datatype for this parameter, and call it recursively. */
   131 		call_param_name->datatype = base_type(fp_iterator.param_type());
   137 		call_param_name->datatype = base_type(fp_iterator.param_type());
   132 		call_param_name->accept(*this);
   138 		call_param_name->accept(*this);
   133 	    /* the first parameter (il_def_variable) is correct */
   139 
   134 	    if (extensible_parameter_highest_index < fp_iterator.extensible_param_index()) {
   140 		if (extensible_parameter_highest_index < fp_iterator.extensible_param_index())
   135 	      extensible_parameter_highest_index = fp_iterator.extensible_param_index();
   141 			extensible_parameter_highest_index = fp_iterator.extensible_param_index();
   136 	    }
   142 	}
   137 	}
   143 	/* call is compatible! */
   138 	/* The function call may not have any errors! */
   144 
   139 	/* In the case of a call to an extensible function, we store the highest index
   145 	/* In the case of a call to an extensible function, we store the highest index 
   140 	 * of the extensible parameters this particular call uses, in the symbol_c object
   146 	 * of the extensible parameters this particular call uses, in the symbol_c object
   141 	 * of the function call itself!
   147 	 * of the function call itself!
   142 	 * In calls to non-extensible functions, this value will be set to -1.
   148 	 * In calls to non-extensible functions, this value will be set to -1.
   143 	 * This information is later used in stage4 to correctly generate the
   149 	 * This information is later used in stage4 to correctly generate the
   144 	 * output code.
   150 	 * output code.
   145 	 */
   151 	 */
   146 	int extensible_param_count = -1;
   152 	if ((NULL != ext_parm_count) && (extensible_parameter_highest_index >=0) /* if call to extensible function */)
   147 	if (extensible_parameter_highest_index >=0) /* if call to extensible function */
   153 		*ext_parm_count = 1 + extensible_parameter_highest_index - fp_iterator.first_extensible_param_index();
   148 		extensible_param_count = 1 + extensible_parameter_highest_index - fp_iterator.first_extensible_param_index();
   154 }
   149 	function_invocation_c  *function_invocation  = dynamic_cast<function_invocation_c  *>(f_call);
   155 
   150 	if (function_invocation  != NULL) function_invocation->extensible_param_count = extensible_param_count;
   156 
   151 }
       
   152 
   157 
   153 /* a helper function... */
   158 /* a helper function... */
   154 symbol_c *narrow_candidate_datatypes_c::base_type(symbol_c *symbol) {
   159 symbol_c *narrow_candidate_datatypes_c::base_type(symbol_c *symbol) {
   155 	/* NOTE: symbol == NULL is valid. It will occur when, for e.g., an undefined/undeclared symbolic_variable is used
   160 	/* NOTE: symbol == NULL is valid. It will occur when, for e.g., an undefined/undeclared symbolic_variable is used
   156 	 *       in the code.
   161 	 *       in the code.
   984 	return NULL;
   989 	return NULL;
   985 }
   990 }
   986 
   991 
   987 
   992 
   988 void *narrow_candidate_datatypes_c::visit(function_invocation_c *symbol) {
   993 void *narrow_candidate_datatypes_c::visit(function_invocation_c *symbol) {
   989 	function_declaration_c *f_decl;
   994 	int  ext_parm_count;
   990 	list_c *parameter_list;
   995 
   991 	list_c *parameter_candidate_datatypes;
   996 	/* set the called_function_declaration taking into account the datatype that we need to return */
   992 	function_symtable_t::iterator lower = function_symtable.lower_bound(symbol->function_name);
   997 	symbol->called_function_declaration = NULL;
   993 	function_symtable_t::iterator upper = function_symtable.upper_bound(symbol->function_name);
   998 	for(unsigned int i = 0; i < symbol->candidate_datatypes.size(); i++) {
   994 
   999 		if (is_type_equal(symbol->candidate_datatypes[i], symbol->datatype)) {
   995 	if (NULL != symbol->formal_param_list)
  1000 			symbol->called_function_declaration = symbol->candidate_functions[i];
   996 		parameter_list = (list_c *)symbol->formal_param_list;
  1001 			break;
   997 	else if (NULL != symbol->nonformal_param_list)
  1002 		}
   998 		parameter_list = (list_c *)symbol->nonformal_param_list;
  1003 	}
   999 	else ERROR;
  1004 	if (NULL == symbol->called_function_declaration) ERROR;
  1000 	for(; lower != upper; lower++) {
  1005 	
  1001 		f_decl = function_symtable.get_value(lower);
  1006 	if (NULL != symbol->nonformal_param_list)  narrow_nonformal_call(symbol, symbol->called_function_declaration, &ext_parm_count);
  1002 		symbol_c * return_type = base_type(f_decl->type_name);
  1007 	if (NULL != symbol->   formal_param_list)     narrow_formal_call(symbol, symbol->called_function_declaration, &ext_parm_count);
  1003 		if (return_type && typeid(*symbol->datatype) != typeid(*return_type))
  1008 	symbol->extensible_param_count = ext_parm_count;
  1004 			continue;
       
  1005 		/* We set which function declaration it'll use in STAGE4 */
       
  1006 		symbol->called_function_declaration = f_decl;
       
  1007 		/* Check if function declaration in symbol_table is compatible with parameters */
       
  1008 		if (NULL != symbol->nonformal_param_list)
       
  1009 			/* nonformal parameter function call */
       
  1010 			narrow_nonformal_call(symbol, f_decl);
       
  1011 		else
       
  1012 			/* formal parameter function call */
       
  1013 			narrow_formal_call (symbol, f_decl);
       
  1014 		break;
       
  1015 	}
       
  1016 
  1009 
  1017 	return NULL;
  1010 	return NULL;
  1018 }
  1011 }
  1019 
  1012 
  1020 /********************/
  1013 /********************/