stage4/generate_c/generate_c_inlinefcall.cc
changeset 375 7a11f9e9e703
parent 355 30db860bd3bd
child 380 b78e59ed4269
equal deleted inserted replaced
349:b826f13c260e 375:7a11f9e9e703
   134       while ((function_call = fc_iterator.next()) != NULL) {
   134       while ((function_call = fc_iterator.next()) != NULL) {
   135     	function_call->accept(*this);
   135     	function_call->accept(*this);
   136       }
   136       }
   137     }
   137     }
   138 
   138 
       
   139 
       
   140 
   139     void generate_inline(symbol_c *function_name,
   141     void generate_inline(symbol_c *function_name,
   140             symbol_c *function_type_prefix,
   142             symbol_c *function_type_prefix,
   141             symbol_c *function_type_suffix,
   143             symbol_c *function_type_suffix,
   142             std::list<FUNCTION_PARAM*> param_list) {
   144             std::list<FUNCTION_PARAM*> param_list,
       
   145             function_declaration_c *f_decl = NULL) {
   143             std::list<FUNCTION_PARAM*>::iterator pt;
   146             std::list<FUNCTION_PARAM*>::iterator pt;
   144 
   147 
   145       fcall_number++;
   148       fcall_number++;
   146       function_type_prefix = search_expression_type->default_literal_type(function_type_prefix);
   149       function_type_prefix = search_expression_type->default_literal_type(function_type_prefix);
   147       if (function_type_suffix) {
   150       if (function_type_suffix) {
   153       function_type_prefix->accept(*this);
   156       function_type_prefix->accept(*this);
   154       s4o.print(" __");
   157       s4o.print(" __");
   155       fbname->accept(*this);
   158       fbname->accept(*this);
   156       s4o.print("_");
   159       s4o.print("_");
   157       function_name->accept(*this);
   160       function_name->accept(*this);
       
   161       if (f_decl != NULL) {
       
   162 printf("generate_inline(): calling print_function_parameter_data_types_c !!!!!!!!!!!!!!!!!!!!!!\n");
       
   163         print_function_parameter_data_types_c overloaded_func_suf(&s4o);
       
   164         f_decl->accept(overloaded_func_suf);
       
   165       }	
   158       if (function_type_suffix) {
   166       if (function_type_suffix) {
   159     	function_type_suffix->accept(*this);
   167         function_type_suffix->accept(*this);
   160       }
   168       }
   161       s4o.print_integer(fcall_number);
   169       s4o.print_integer(fcall_number);
   162       s4o.print("(");
   170       s4o.print("(");
   163       s4o.indent_right();
   171       s4o.indent_right();
   164 
   172 
   169           PARAM_NAME->accept(*this);
   177           PARAM_NAME->accept(*this);
   170           s4o.print(",\n" + s4o.indent_spaces);
   178           s4o.print(",\n" + s4o.indent_spaces);
   171         }
   179         }
   172       }
   180       }
   173       fbname->accept(*this);
   181       fbname->accept(*this);
   174 	  s4o.print(" *");
   182       s4o.print(" *");
   175 	  s4o.print(FB_FUNCTION_PARAM);
   183       s4o.print(FB_FUNCTION_PARAM);
   176 	  s4o.indent_left();
   184       s4o.indent_left();
   177 	  s4o.print(")\n" + s4o.indent_spaces);
   185       s4o.print(")\n" + s4o.indent_spaces);
   178 	  s4o.print("{\n");
   186       s4o.print("{\n");
   179       s4o.indent_right();
   187       s4o.indent_right();
   180 
   188 
   181       s4o.print(s4o.indent_spaces);
   189       s4o.print(s4o.indent_spaces);
   182       function_type_prefix->accept(*this);
   190       function_type_prefix->accept(*this);
   183       s4o.print(" "),
   191       s4o.print(" "),
   184       s4o.print(INLINE_RESULT_TEMP_VAR);
   192       s4o.print(INLINE_RESULT_TEMP_VAR);
   185       s4o.print(";\n");
   193       s4o.print(";\n");
   186 
   194 
   187 	  PARAM_LIST_ITERATOR() {
   195       PARAM_LIST_ITERATOR() {
   188 		if ((PARAM_DIRECTION == function_param_iterator_c::direction_out ||
   196         if ((PARAM_DIRECTION == function_param_iterator_c::direction_out ||
   189 		     PARAM_DIRECTION == function_param_iterator_c::direction_inout) &&
   197              PARAM_DIRECTION == function_param_iterator_c::direction_inout) &&
   190 		    PARAM_VALUE != NULL) {
   198              PARAM_VALUE != NULL) {
   191 		  s4o.print(s4o.indent_spaces);
   199           s4o.print(s4o.indent_spaces);
   192 		  PARAM_TYPE->accept(*this);
   200           PARAM_TYPE->accept(*this);
   193           s4o.print(" ");
   201           s4o.print(" ");
   194           s4o.print(TEMP_VAR);
   202           s4o.print(TEMP_VAR);
   195           PARAM_NAME->accept(*this);
   203           PARAM_NAME->accept(*this);
   196           s4o.print(" = ");
   204           s4o.print(" = ");
   197           print_check_function(PARAM_TYPE, PARAM_VALUE);
   205           print_check_function(PARAM_TYPE, PARAM_VALUE);
   198           s4o.print(";\n");
   206           s4o.print(";\n");
   199 		}
   207           }
   200 	  }
   208         }
   201 
   209 
   202 	  s4o.print(s4o.indent_spaces + INLINE_RESULT_TEMP_VAR),
   210       s4o.print(s4o.indent_spaces + INLINE_RESULT_TEMP_VAR),
   203 			  s4o.print(" = ");
   211       s4o.print(" = ");
   204 	  function_name->accept(*this);
   212       function_name->accept(*this);
   205 	  if (function_type_suffix)
   213       if (f_decl != NULL) {
       
   214 printf("generate_inline(): calling print_function_parameter_data_types_c !!!!!!!!!!!!!!!!!!!!!!\n");
       
   215         print_function_parameter_data_types_c overloaded_func_suf(&s4o);
       
   216         f_decl->accept(overloaded_func_suf);
       
   217       }
       
   218 
       
   219       if (function_type_suffix)
   206         function_type_suffix->accept(*this);
   220         function_type_suffix->accept(*this);
   207 	  s4o.print("(");
   221       s4o.print("(");
   208 	  s4o.indent_right();
   222       s4o.indent_right();
   209 
   223 
   210 	  PARAM_LIST_ITERATOR() {
   224       PARAM_LIST_ITERATOR() {
   211 		if (pt != param_list.begin())
   225         if (pt != param_list.begin())
   212 		  s4o.print(",\n" + s4o.indent_spaces);
   226         s4o.print(",\n" + s4o.indent_spaces);
   213 		if (PARAM_DIRECTION == function_param_iterator_c::direction_in)
   227         if (PARAM_DIRECTION == function_param_iterator_c::direction_in)
   214 		  PARAM_NAME->accept(*this);
   228           PARAM_NAME->accept(*this);
   215 		else if (PARAM_VALUE != NULL){
   229         else if (PARAM_VALUE != NULL){
   216           s4o.print("&");
   230           s4o.print("&");
   217           s4o.print(TEMP_VAR);
   231           s4o.print(TEMP_VAR);
   218           PARAM_NAME->accept(*this);
   232           PARAM_NAME->accept(*this);
   219         }
   233         } else {
   220 		else {
   234           s4o.print("NULL");
   221 		  s4o.print("NULL");
   235          }
   222 		}
   236       }
   223 	  }
   237       s4o.print(");\n");
   224 	  s4o.print(");\n");
   238       s4o.indent_left();
   225 	  s4o.indent_left();
   239 
   226 
   240       PARAM_LIST_ITERATOR() {
   227 	  PARAM_LIST_ITERATOR() {
       
   228         if ((PARAM_DIRECTION == function_param_iterator_c::direction_out ||
   241         if ((PARAM_DIRECTION == function_param_iterator_c::direction_out ||
   229         	 PARAM_DIRECTION == function_param_iterator_c::direction_inout) &&
   242              PARAM_DIRECTION == function_param_iterator_c::direction_inout) &&
   230         	PARAM_VALUE != NULL) {
   243              PARAM_VALUE != NULL) {
   231 
       
   232           s4o.print(s4o.indent_spaces);
   244           s4o.print(s4o.indent_spaces);
   233           print_setter(PARAM_VALUE, PARAM_TYPE, PARAM_NAME);
   245           print_setter(PARAM_VALUE, PARAM_TYPE, PARAM_NAME);
   234           s4o.print(";\n");
   246           s4o.print(";\n");
   235 		}
   247         }
   236 	  }
   248       }
   237 	  s4o.print(s4o.indent_spaces + "return ");
   249       s4o.print(s4o.indent_spaces + "return ");
   238 	  s4o.print(INLINE_RESULT_TEMP_VAR);
   250       s4o.print(INLINE_RESULT_TEMP_VAR);
   239 	  s4o.print(";\n");
   251       s4o.print(";\n");
   240 
   252 
   241       s4o.indent_left();
   253       s4o.indent_left();
   242       s4o.print(s4o.indent_spaces + "}\n\n");
   254       s4o.print(s4o.indent_spaces + "}\n\n");
   243     }
   255     }
   244 
   256 
   458       return NULL;
   470       return NULL;
   459     }
   471     }
   460 
   472 
   461     void *visit(il_function_call_c *symbol) {
   473     void *visit(il_function_call_c *symbol) {
   462       symbol_c* function_type_prefix = NULL;
   474       symbol_c* function_type_prefix = NULL;
   463       symbol_c* function_name = NULL;
   475       symbol_c* function_name = NULL;     
   464       symbol_c* function_type_suffix = NULL;
   476       symbol_c* function_type_suffix = NULL;
   465       DECLARE_PARAM_LIST()
   477       DECLARE_PARAM_LIST()
   466 
   478 
   467       symbol_c *param_data_type = default_variable_name.current_type;
   479       symbol_c *param_data_type = default_variable_name.current_type;
   468 
   480 
   469       function_call_param_iterator_c function_call_param_iterator(symbol);
   481       function_call_param_iterator_c function_call_param_iterator(symbol);
   470 
   482 
   471       function_declaration_c *f_decl = function_symtable.find_value(symbol->function_name);
   483       function_declaration_c *f_decl = (function_declaration_c *)symbol->called_function_declaration;
   472 	  if (f_decl == function_symtable.end_value()) {
   484       if (f_decl == NULL) ERROR;
   473         function_type_t current_function_type = get_function_type((identifier_c *)symbol->function_name);
   485       
   474         if (current_function_type == function_none) ERROR;
   486       /* determine the base data type returned by the function being called... */
   475 
   487       search_base_type_c search_base_type;
   476         function_type_prefix = (symbol_c *)search_expression_type->compute_standard_function_il(symbol, param_data_type);
   488       function_type_prefix = (symbol_c *)f_decl->type_name->accept(search_base_type);
   477 
   489       
   478         symbol_c *en_param_name = (symbol_c *)(new identifier_c("EN"));
   490       function_name = symbol->function_name;      
   479         /* Add the value from EN param */
   491       
   480         ADD_PARAM_LIST(en_param_name,
   492       /* loop through each function parameter, find the value we should pass
   481                        (symbol_c*)(new boolean_literal_c((symbol_c*)(new bool_type_name_c()), new boolean_true_c())),
   493        * to it, and then output the c equivalent...
   482                        (symbol_c*)(new bool_type_name_c()),
   494        */
   483                        function_param_iterator_c::direction_in)
   495       
   484 
   496       function_param_iterator_c fp_iterator(f_decl);
   485         symbol_c *eno_param_name = (symbol_c *)(new identifier_c("ENO"));
   497       identifier_c *param_name;
   486         /* Add the value from ENO param */
   498         /* flag to remember whether we have already used the value stored in the default variable to pass to the first parameter */
   487         ADD_PARAM_LIST(eno_param_name, NULL, (symbol_c*)(new bool_type_name_c()), function_param_iterator_c::direction_out)
   499       bool used_defvar = false;       
   488 
   500         /* flag to cirreclty handle calls to extensible standard functions (i.e. functions with variable number of input parameters) */
   489         int nb_param = 1;
   501       bool found_first_extensible_parameter = false;  
   490         if (symbol->il_operand_list != NULL)
   502       for(int i = 1; (param_name = fp_iterator.next()) != NULL; i++) {
   491           nb_param += ((list_c *)symbol->il_operand_list)->n;
   503         if (fp_iterator.is_extensible_param() && (!found_first_extensible_parameter)) {
   492 
   504           /* We are calling an extensible function. Before passing the extensible
   493         #include "il_code_gen.c"
   505            * parameters, we must add a dummy paramater value to tell the called
   494 
   506            * function how many extensible parameters we will be passing.
   495       }
   507            *
   496 	  else {
   508            * Note that stage 3 has already determined the number of extensible
   497 		function_name = symbol->function_name;
   509            * paramters, and stored that info in the abstract syntax tree. We simply
   498 
   510            * re-use that value.
   499 		/* determine the base data type returned by the function being called... */
   511            */
   500 		search_base_type_c search_base_type;
   512           /* NOTE: we are not freeing the malloc'd memory. This is not really a bug.
   501 		function_type_prefix = (symbol_c *)f_decl->type_name->accept(search_base_type);
   513            *       Since we are writing a compiler, which runs to termination quickly,
   502 
   514            *       we can consider this as just memory required for the compilation process
   503 		/* loop through each function parameter, find the value we should pass
   515            *       that will be free'd when the program terminates.
   504 		 * to it, and then output the c equivalent...
   516            */
   505 		 */
   517           char *tmp = (char *)malloc(32); /* enough space for a call with 10^31 (larger than 2^64) input parameters! */
   506 
   518           if (tmp == NULL) ERROR;
   507 		function_param_iterator_c fp_iterator(f_decl);
   519           int res = snprintf(tmp, 32, "%d", symbol->extensible_param_count);
   508 		identifier_c *param_name;
   520           if ((res >= 32) || (res < 0)) ERROR;
   509 		for(int i = 1; (param_name = fp_iterator.next()) != NULL; i++) {
   521           identifier_c *param_value = new identifier_c(tmp);
   510 		  symbol_c *param_type = fp_iterator.param_type();
   522           uint_type_name_c *param_type  = new uint_type_name_c();
   511 		  if (param_type == NULL) ERROR;
   523           identifier_c *param_name = new identifier_c("");
   512 
   524           ADD_PARAM_LIST(param_name, param_value, param_type, function_param_iterator_c::direction_in)
   513 		  function_param_iterator_c::param_direction_t param_direction = fp_iterator.param_direction();
   525           found_first_extensible_parameter = true;
   514 
   526         }
   515 		  symbol_c *param_value = NULL;
   527     
   516 
   528         symbol_c *param_type = fp_iterator.param_type();
   517 		  /* if it is the first parameter, semantics specifies that we should
   529         if (param_type == NULL) ERROR;
   518 		   * get the value off the IL default variable!
   530       
   519 		   */
   531         function_param_iterator_c::param_direction_t param_direction = fp_iterator.param_direction();
   520 		  if (1 == i)
   532       
   521 		    param_value = &this->default_variable_name;
   533         symbol_c *param_value = NULL;
   522 
   534       
   523 		  /* Get the value from a foo(<param_name> = <param_value>) style call */
   535         /* Get the value from a foo(<param_name> = <param_value>) style call */
   524 		  /* NOTE: the following line of code is not required in this case, but it doesn't
   536         /* NOTE: the following line of code is not required in this case, but it doesn't
   525 		   * harm to leave it in, as in the case of a non-formal syntax function call,
   537          * harm to leave it in, as in the case of a non-formal syntax function call,
   526 		   * it will always return NULL.
   538          * it will always return NULL.
   527 		   * We leave it in in case we later decide to merge this part of the code together
   539          * We leave it in in case we later decide to merge this part of the code together
   528 		   * with the function calling code in generate_c_st_c, which does require
   540          * with the function calling code in generate_c_st_c, which does require
   529 		   * the following line...
   541          * the following line...
   530 		   */
   542          */
   531 		  if (param_value == NULL)
   543         if (param_value == NULL)
   532 			param_value = function_call_param_iterator.search_f(param_name);
   544           param_value = function_call_param_iterator.search_f(param_name);
   533 
   545 
   534 		  /* Get the value from a foo(<param_value>) style call */
   546         /* if it is the first parameter in a non-formal function call (which is the
   535           if (param_value == NULL) {
   547          * case being handled!), semantics specifies that we should
   536             param_value = function_call_param_iterator.next_nf();
   548          * get the value off the IL default variable!
   537             if (param_value != NULL && fp_iterator.is_en_eno_param_implicit()) ERROR;
   549          *
   538           }
   550          * However, if the parameter is an implicitly defined EN or ENO parameter, we should not
   539 
   551          * use the default variable as a source of data to pass to those parameters!
   540 		  if (param_value == NULL && param_direction == function_param_iterator_c::direction_in) {
   552          */
   541 			/* No value given for parameter, so we must use the default... */
   553         if ((param_value == NULL) && (!used_defvar) && !fp_iterator.is_en_eno_param_implicit()) {
   542 			/* First check whether default value specified in function declaration...*/
   554           param_value = &this->default_variable_name;
   543 			param_value = fp_iterator.default_value();
   555           used_defvar = true;
   544 		  }
   556         }
   545 
   557 
   546 		  ADD_PARAM_LIST(param_name, param_value, param_type, fp_iterator.param_direction())
   558         /* Get the value from a foo(<param_value>) style call */
   547 		} /* for(...) */
   559         if ((param_value == NULL) && !fp_iterator.is_en_eno_param_implicit()) {
   548 	  }
   560           param_value = function_call_param_iterator.next_nf();
   549 
   561         }
   550 	  if (function_call_param_iterator.next_nf() != NULL) ERROR;
   562         
       
   563         /* if no more parameter values in function call, and the current parameter
       
   564          * of the function declaration is an extensible parameter, we
       
   565          * have reached the end, and should simply jump out of the for loop.
       
   566          */
       
   567         if ((param_value == NULL) && (fp_iterator.is_extensible_param())) {
       
   568           break;
       
   569         }
       
   570       
       
   571         if ((param_value == NULL) && (param_direction == function_param_iterator_c::direction_in)) {
       
   572           /* No value given for parameter, so we must use the default... */
       
   573           /* First check whether default value specified in function declaration...*/
       
   574           param_value = fp_iterator.default_value();
       
   575         }
       
   576       
       
   577         ADD_PARAM_LIST(param_name, param_value, param_type, fp_iterator.param_direction())
       
   578       } /* for(...) */
       
   579 
       
   580       if (function_call_param_iterator.next_nf() != NULL) ERROR;
   551       if (NULL == function_type_prefix) ERROR;
   581       if (NULL == function_type_prefix) ERROR;
   552 
   582 
   553       bool has_output_params = false;
   583       bool has_output_params = false;
   554 
   584 
   555       PARAM_LIST_ITERATOR() {
   585       PARAM_LIST_ITERATOR() {
   558              PARAM_VALUE != NULL) {
   588              PARAM_VALUE != NULL) {
   559           has_output_params = true;
   589           has_output_params = true;
   560         }
   590         }
   561       }
   591       }
   562 
   592 
       
   593       /* Check whether we are calling an overloaded function! */
       
   594       /* (fdecl_mutiplicity==2)  => calling overloaded function */
       
   595       int fdecl_mutiplicity =  function_symtable.multiplicity(symbol->function_name);
       
   596       if (fdecl_mutiplicity == 0) ERROR;
       
   597       if (fdecl_mutiplicity == 1) 
       
   598         /* function being called is NOT overloaded! */
       
   599         f_decl = NULL; 
       
   600 
   563       if (has_output_params)
   601       if (has_output_params)
   564         generate_inline(function_name, function_type_prefix, function_type_suffix, param_list);
   602         generate_inline(function_name, function_type_prefix, function_type_suffix, param_list, f_decl);
   565 
   603 
   566       CLEAR_PARAM_LIST()
   604       CLEAR_PARAM_LIST()
   567 
   605 
   568       /* the data type resulting from this operation... */
   606       /* the data type resulting from this operation... */
   569       default_variable_name.current_type = function_type_prefix;
   607       default_variable_name.current_type = function_type_prefix;
   623       symbol_c* function_type_suffix = NULL;
   661       symbol_c* function_type_suffix = NULL;
   624       DECLARE_PARAM_LIST()
   662       DECLARE_PARAM_LIST()
   625 
   663 
   626       function_call_param_iterator_c function_call_param_iterator(symbol);
   664       function_call_param_iterator_c function_call_param_iterator(symbol);
   627 
   665 
   628       function_declaration_c *f_decl = function_symtable.find_value(symbol->function_name);
   666       function_declaration_c *f_decl = (function_declaration_c *)symbol->called_function_declaration;
   629       if (f_decl == function_symtable.end_value()) {
   667       if (f_decl == NULL) ERROR;
   630         function_type_t current_function_type = get_function_type((identifier_c *)symbol->function_name);
   668 
   631         if (current_function_type == function_none) ERROR;
   669       /* determine the base data type returned by the function being called... */
   632 
   670       search_base_type_c search_base_type;
   633         function_type_prefix = (symbol_c *)search_expression_type->compute_standard_function_default(NULL, symbol);
   671       function_type_prefix = (symbol_c *)f_decl->type_name->accept(search_base_type);
   634 
   672       if (NULL == function_type_prefix) ERROR;
   635         int nb_param = 0;
   673       
   636         if (symbol->il_param_list != NULL)
   674       function_name = symbol->function_name;
   637           nb_param += ((list_c *)symbol->il_param_list)->n;
   675 
   638 
   676       /* loop through each function parameter, find the value we should pass
   639         symbol_c *en_param_name = (symbol_c *)(new identifier_c("EN"));
   677        * to it, and then output the c equivalent...
   640         /* Get the value from EN param */
   678        */
   641         symbol_c *EN_param_value = function_call_param_iterator.search_f(en_param_name);
   679       function_param_iterator_c fp_iterator(f_decl);
   642         if (EN_param_value == NULL)
   680       identifier_c *param_name;
   643           EN_param_value = (symbol_c*)(new boolean_literal_c((symbol_c*)(new bool_type_name_c()), new boolean_true_c()));
   681 
   644         else
   682         /* flag to cirreclty handle calls to extensible standard functions (i.e. functions with variable number of input parameters) */
   645           nb_param --;
   683       bool found_first_extensible_parameter = false;
   646         ADD_PARAM_LIST(en_param_name, EN_param_value, (symbol_c*)(new bool_type_name_c()), function_param_iterator_c::direction_in)
   684       for(int i = 1; (param_name = fp_iterator.next()) != NULL; i++) {
   647 
   685         if (fp_iterator.is_extensible_param() && (!found_first_extensible_parameter)) {
   648         symbol_c *eno_param_name = (symbol_c *)(new identifier_c("ENO"));
   686           /* We are calling an extensible function. Before passing the extensible
   649         /* Get the value from ENO param */
   687            * parameters, we must add a dummy paramater value to tell the called
   650         symbol_c *ENO_param_value = function_call_param_iterator.search_f(eno_param_name);
   688            * function how many extensible parameters we will be passing.
   651         if (ENO_param_value != NULL)
   689            *
   652           nb_param --;
   690            * Note that stage 3 has already determined the number of extensible
   653         ADD_PARAM_LIST(eno_param_name, ENO_param_value, (symbol_c*)(new bool_type_name_c()), function_param_iterator_c::direction_out)
   691            * paramters, and stored that info in the abstract syntax tree. We simply
   654 
   692            * re-use that value.
   655         #include "st_code_gen.c"
   693            */
   656 
   694           /* NOTE: we are not freeing the malloc'd memory. This is not really a bug.
   657       }
   695            *       Since we are writing a compiler, which runs to termination quickly,
   658       else {
   696            *       we can consider this as just memory required for the compilation process
   659         function_name = symbol->function_name;
   697            *       that will be free'd when the program terminates.
   660 
   698            */
   661 		/* determine the base data type returned by the function being called... */
   699           char *tmp = (char *)malloc(32); /* enough space for a call with 10^31 (larger than 2^64) input parameters! */
   662 		search_base_type_c search_base_type;
   700           if (tmp == NULL) ERROR;
   663 		function_type_prefix = (symbol_c *)f_decl->type_name->accept(search_base_type);
   701           int res = snprintf(tmp, 32, "%d", symbol->extensible_param_count);
   664 
   702           if ((res >= 32) || (res < 0)) ERROR;
   665 		/* loop through each function parameter, find the value we should pass
   703           identifier_c *param_value = new identifier_c(tmp);
   666 		 * to it, and then output the c equivalent...
   704           uint_type_name_c *param_type  = new uint_type_name_c();
   667 		 */
   705           identifier_c *param_name = new identifier_c("");
   668 
   706           ADD_PARAM_LIST(param_name, param_value, param_type, function_param_iterator_c::direction_in)
   669 		function_param_iterator_c fp_iterator(f_decl);
   707           found_first_extensible_parameter = true;
   670 		identifier_c *param_name;
   708         }
   671 		for(int i = 1; (param_name = fp_iterator.next()) != NULL; i++) {
   709         
   672 		  symbol_c *param_type = fp_iterator.param_type();
   710         if (fp_iterator.is_extensible_param()) {      
   673 		  if (param_type == NULL) ERROR;
   711           /* since we are handling an extensible parameter, we must add the index to the
   674 
   712            * parameter name so we can go looking for the value passed to the correct
   675 		  function_param_iterator_c::param_direction_t param_direction = fp_iterator.param_direction();
   713            * extended parameter (e.g. IN1, IN2, IN3, IN4, ...)
   676 
   714            */
   677 
   715           char *tmp = (char *)malloc(32); /* enough space for a call with 10^31 (larger than 2^64) input parameters! */
   678 		  symbol_c *param_value = NULL;
   716           int res = snprintf(tmp, 32, "%d", fp_iterator.extensible_param_index());
   679 
   717           if ((res >= 32) || (res < 0)) ERROR;
   680 		  /* Get the value from a foo(<param_name> = <param_value>) style call */
   718           param_name = new identifier_c(strdup2(param_name->value, tmp));
   681 		  if (param_value == NULL)
   719           if (param_name->value == NULL) ERROR;
   682 			param_value = function_call_param_iterator.search_f(param_name);
   720         }
   683 
   721     
   684 		  /* Get the value from a foo(<param_value>) style call */
   722         symbol_c *param_type = fp_iterator.param_type();
   685 		  /* NOTE: the following line of code is not required in this case, but it doesn't
   723         if (param_type == NULL) ERROR;
   686 		   * harm to leave it in, as in the case of a formal syntax function call,
   724       
   687 		   * it will always return NULL.
   725         function_param_iterator_c::param_direction_t param_direction = fp_iterator.param_direction();
   688 		   * We leave it in in case we later decide to merge this part of the code together
   726       
   689 		   * with the function calling code in generate_c_st_c, which does require
   727         symbol_c *param_value = NULL;
   690 		   * the following line...
   728       
   691 		   */
   729         /* Get the value from a foo(<param_name> = <param_value>) style call */
   692 		  if (param_value == NULL) {
   730         if (param_value == NULL)
   693             param_value = function_call_param_iterator.next_nf();
   731           param_value = function_call_param_iterator.search_f(param_name);
   694             if (param_value != NULL && fp_iterator.is_en_eno_param_implicit()) ERROR;
   732       
   695           }
   733         /* Get the value from a foo(<param_value>) style call */
   696 
   734         /* NOTE: the following line of code is not required in this case, but it doesn't
   697 		  if (param_value == NULL) {
   735          * harm to leave it in, as in the case of a formal syntax function call,
   698 			/* No value given for parameter, so we must use the default... */
   736          * it will always return NULL.
   699 			/* First check whether default value specified in function declaration...*/
   737          * We leave it in in case we later decide to merge this part of the code together
   700 			param_value = fp_iterator.default_value();
   738          * with the function calling code in generate_c_st_c, which does require
   701 		  }
   739          * the following line...
   702 
   740          */
   703 		  ADD_PARAM_LIST(param_name, param_value, param_type, fp_iterator.param_direction())
   741         if ((param_value == NULL) && !fp_iterator.is_en_eno_param_implicit()) {
   704 		}
   742           param_value = function_call_param_iterator.next_nf();
       
   743         }
       
   744         
       
   745         /* if no more parameter values in function call, and the current parameter
       
   746          * of the function declaration is an extensible parameter, we
       
   747          * have reached the end, and should simply jump out of the for loop.
       
   748          */
       
   749         if ((param_value == NULL) && (fp_iterator.is_extensible_param())) {
       
   750           break;
       
   751         }
       
   752     
       
   753         if ((param_value == NULL) && (param_direction == function_param_iterator_c::direction_in)) {
       
   754           /* No value given for parameter, so we must use the default... */
       
   755           /* First check whether default value specified in function declaration...*/
       
   756           param_value = fp_iterator.default_value();
       
   757         }
       
   758 
       
   759         ADD_PARAM_LIST(param_name, param_value, param_type, fp_iterator.param_direction())
   705       }
   760       }
   706 
   761 
   707       if (function_call_param_iterator.next_nf() != NULL) ERROR;
   762       if (function_call_param_iterator.next_nf() != NULL) ERROR;
   708       if (NULL == function_type_prefix) ERROR;
       
   709 
   763 
   710       bool has_output_params = false;
   764       bool has_output_params = false;
   711 
   765 
   712       PARAM_LIST_ITERATOR() {
   766       PARAM_LIST_ITERATOR() {
   713         if ((PARAM_DIRECTION == function_param_iterator_c::direction_out ||
   767         if ((PARAM_DIRECTION == function_param_iterator_c::direction_out ||
   715              PARAM_VALUE != NULL) {
   769              PARAM_VALUE != NULL) {
   716           has_output_params = true;
   770           has_output_params = true;
   717         }
   771         }
   718       }
   772       }
   719 
   773 
       
   774       /* Check whether we are calling an overloaded function! */
       
   775       /* (fdecl_mutiplicity==2)  => calling overloaded function */
       
   776       int fdecl_mutiplicity =  function_symtable.multiplicity(symbol->function_name);
       
   777       if (fdecl_mutiplicity == 0) ERROR;
       
   778       if (fdecl_mutiplicity == 1) 
       
   779         /* function being called is NOT overloaded! */
       
   780         f_decl = NULL; 
       
   781 
   720       if (has_output_params)
   782       if (has_output_params)
   721         generate_inline(function_name, function_type_prefix, function_type_suffix, param_list);
   783         generate_inline(function_name, function_type_prefix, function_type_suffix, param_list, f_decl);
   722 
   784 
   723       CLEAR_PARAM_LIST()
   785       CLEAR_PARAM_LIST()
   724 
   786 
   725       /* the data type resulting from this operation... */
   787       /* the data type resulting from this operation... */
   726       default_variable_name.current_type = function_type_prefix;
   788       default_variable_name.current_type = function_type_prefix;
   966       if (NULL != symbol->nonformal_param_list) parameter_assignment_list = symbol->nonformal_param_list;
  1028       if (NULL != symbol->nonformal_param_list) parameter_assignment_list = symbol->nonformal_param_list;
   967       if (NULL == parameter_assignment_list) ERROR;
  1029       if (NULL == parameter_assignment_list) ERROR;
   968 
  1030 
   969       function_call_param_iterator_c function_call_param_iterator(symbol);
  1031       function_call_param_iterator_c function_call_param_iterator(symbol);
   970 
  1032 
   971       function_declaration_c *f_decl = function_symtable.find_value(symbol->function_name);
  1033       function_declaration_c *f_decl = (function_declaration_c *)symbol->called_function_declaration;
   972       if (f_decl == function_symtable.end_value()) {
  1034       if (f_decl == NULL) ERROR;
   973         /* The function called is not in the symtable, so we test if it is a
  1035 
   974          * standard function defined in standard */
  1036       function_name = symbol->function_name;
   975 
  1037 
   976         function_type_t current_function_type = get_function_type((identifier_c *)symbol->function_name);
  1038       /* determine the base data type returned by the function being called... */
   977         if (current_function_type == function_none) ERROR;
  1039       search_base_type_c search_base_type;
   978 
  1040       function_type_prefix = (symbol_c *)f_decl->type_name->accept(search_base_type);
   979         function_type_prefix = search_expression_type->get_type(symbol);
  1041       if (NULL == function_type_prefix) ERROR;
   980 
  1042 
   981         int nb_param = ((list_c *)parameter_assignment_list)->n;
  1043       /* loop through each function parameter, find the value we should pass
   982 
  1044        * to it, and then output the c equivalent...
   983         symbol_c *en_param_name = (symbol_c *)(new identifier_c("EN"));
  1045        */
   984         /* Get the value from EN param */
  1046       function_param_iterator_c fp_iterator(f_decl);
   985         symbol_c *EN_param_value = function_call_param_iterator.search_f(en_param_name);
  1047       identifier_c *param_name;
   986         if (EN_param_value == NULL)
  1048         /* flag to cirreclty handle calls to extensible standard functions (i.e. functions with variable number of input parameters) */
   987           EN_param_value = (symbol_c*)(new boolean_literal_c((symbol_c*)(new bool_type_name_c()), new boolean_true_c()));
  1049       bool found_first_extensible_parameter = false;  
   988         else
  1050       for(int i = 1; (param_name = fp_iterator.next()) != NULL; i++) {
   989           nb_param --;
  1051         if (fp_iterator.is_extensible_param() && (!found_first_extensible_parameter)) {
   990         ADD_PARAM_LIST(en_param_name, EN_param_value, (symbol_c*)(new bool_type_name_c()), function_param_iterator_c::direction_in)
  1052           /* We are calling an extensible function. Before passing the extensible
   991 
  1053            * parameters, we must add a dummy paramater value to tell the called
   992         symbol_c *eno_param_name = (symbol_c *)(new identifier_c("ENO"));
  1054            * function how many extensible parameters we will be passing.
   993         /* Get the value from ENO param */
  1055            *
   994         symbol_c *ENO_param_value = function_call_param_iterator.search_f(eno_param_name);
  1056            * Note that stage 3 has already determined the number of extensible
   995         if (ENO_param_value != NULL)
  1057            * paramters, and stored that info in the abstract syntax tree. We simply
   996           nb_param --;
  1058            * re-use that value.
   997         ADD_PARAM_LIST(eno_param_name, ENO_param_value, (symbol_c*)(new bool_type_name_c()), function_param_iterator_c::direction_out)
  1059            */
   998 
  1060           /* NOTE: we are not freeing the malloc'd memory. This is not really a bug.
   999         #include "st_code_gen.c"
  1061            *       Since we are writing a compiler, which runs to termination quickly,
  1000 
  1062            *       we can consider this as just memory required for the compilation process
  1001       }
  1063            *       that will be free'd when the program terminates.
  1002       else {
  1064            */
  1003         function_name = symbol->function_name;
  1065           char *tmp = (char *)malloc(32); /* enough space for a call with 10^31 (larger than 2^64) input parameters! */
  1004 
  1066           if (tmp == NULL) ERROR;
  1005 	    /* determine the base data type returned by the function being called... */
  1067           int res = snprintf(tmp, 32, "%d", symbol->extensible_param_count);
  1006 		search_base_type_c search_base_type;
  1068           if ((res >= 32) || (res < 0)) ERROR;
  1007 		function_type_prefix = (symbol_c *)f_decl->type_name->accept(search_base_type);
  1069           identifier_c *param_value = new identifier_c(tmp);
  1008 
  1070           uint_type_name_c *param_type  = new uint_type_name_c();
  1009     	/* loop through each function parameter, find the value we should pass
  1071           identifier_c *param_name = new identifier_c("");
  1010          * to it, and then output the c equivalent...
  1072           ADD_PARAM_LIST(param_name, param_value, param_type, function_param_iterator_c::direction_in)
       
  1073           found_first_extensible_parameter = true;
       
  1074         }
       
  1075     
       
  1076         if (fp_iterator.is_extensible_param()) {      
       
  1077           /* since we are handling an extensible parameter, we must add the index to the
       
  1078            * parameter name so we can go looking for the value passed to the correct
       
  1079            * extended parameter (e.g. IN1, IN2, IN3, IN4, ...)
       
  1080            */
       
  1081           char *tmp = (char *)malloc(32); /* enough space for a call with 10^31 (larger than 2^64) input parameters! */
       
  1082           int res = snprintf(tmp, 32, "%d", fp_iterator.extensible_param_index());
       
  1083           if ((res >= 32) || (res < 0)) ERROR;
       
  1084           param_name = new identifier_c(strdup2(param_name->value, tmp));
       
  1085           if (param_name->value == NULL) ERROR;
       
  1086         }
       
  1087         
       
  1088         symbol_c *param_type = fp_iterator.param_type();
       
  1089         if (param_type == NULL) ERROR;
       
  1090 
       
  1091         function_param_iterator_c::param_direction_t param_direction = fp_iterator.param_direction();
       
  1092 
       
  1093         symbol_c *param_value = NULL;
       
  1094     
       
  1095         /* Get the value from a foo(<param_name> = <param_value>) style call */
       
  1096         if (param_value == NULL)
       
  1097           param_value = function_call_param_iterator.search_f(param_name);
       
  1098 
       
  1099         /* Get the value from a foo(<param_value>) style call */
       
  1100         if ((param_value == NULL) && !fp_iterator.is_en_eno_param_implicit()) {
       
  1101           param_value = function_call_param_iterator.next_nf();
       
  1102         }
       
  1103         
       
  1104         /* if no more parameter values in function call, and the current parameter
       
  1105          * of the function declaration is an extensible parameter, we
       
  1106          * have reached the end, and should simply jump out of the for loop.
  1011          */
  1107          */
  1012         function_param_iterator_c fp_iterator(f_decl);
  1108         if ((param_value == NULL) && (fp_iterator.is_extensible_param())) {
  1013         identifier_c *param_name;
  1109           break;
  1014         for(int i = 1; (param_name = fp_iterator.next()) != NULL; i++) {
  1110         }
  1015           symbol_c *param_type = fp_iterator.param_type();
  1111     
  1016           if (param_type == NULL) ERROR;
  1112         if ((param_value == NULL) && (param_direction == function_param_iterator_c::direction_in)) {
  1017 
  1113           /* No value given for parameter, so we must use the default... */
  1018           function_param_iterator_c::param_direction_t param_direction = fp_iterator.param_direction();
  1114           /* First check whether default value specified in function declaration...*/
  1019 
  1115           param_value = fp_iterator.default_value();
  1020           /* Get the value from a foo(<param_name> = <param_value>) style call */
  1116         }
  1021           symbol_c *param_value = function_call_param_iterator.search_f(param_name);
  1117 
  1022 
  1118         ADD_PARAM_LIST(param_name, param_value, param_type, param_direction)
  1023           /* Get the value from a foo(<param_value>) style call */
  1119       } /* for(...) */
  1024           if (param_value == NULL) {
  1120       // symbol->parameter_assignment->accept(*this);
  1025             param_value = function_call_param_iterator.next_nf();
       
  1026             if (param_value != NULL && fp_iterator.is_en_eno_param_implicit()) ERROR;
       
  1027           }
       
  1028 
       
  1029           if (param_value == NULL && param_direction == function_param_iterator_c::direction_in) {
       
  1030             /* No value given for parameter, so we must use the default... */
       
  1031             /* First check whether default value specified in function declaration...*/
       
  1032             param_value = fp_iterator.default_value();
       
  1033           }
       
  1034 
       
  1035           ADD_PARAM_LIST(param_name, param_value, param_type, param_direction)
       
  1036         } /* for(...) */
       
  1037         // symbol->parameter_assignment->accept(*this);
       
  1038       }
       
  1039 
  1121 
  1040       if (function_call_param_iterator.next_nf() != NULL) ERROR;
  1122       if (function_call_param_iterator.next_nf() != NULL) ERROR;
  1041       if (NULL == function_type_prefix) ERROR;
  1123 
  1042 
  1124       bool has_output_params = false;
  1043 	  bool has_output_params = false;
  1125 
  1044 
  1126       PARAM_LIST_ITERATOR() {
  1045 	  PARAM_LIST_ITERATOR() {
       
  1046         if ((PARAM_DIRECTION == function_param_iterator_c::direction_out ||
  1127         if ((PARAM_DIRECTION == function_param_iterator_c::direction_out ||
  1047              PARAM_DIRECTION == function_param_iterator_c::direction_inout) &&
  1128              PARAM_DIRECTION == function_param_iterator_c::direction_inout) &&
  1048              PARAM_VALUE != NULL) {
  1129              PARAM_VALUE != NULL) {
  1049           has_output_params = true;
  1130           has_output_params = true;
  1050         }
  1131         }
  1051       }
  1132       }
  1052 
  1133 
       
  1134       /* Check whether we are calling an overloaded function! */
       
  1135       /* (fdecl_mutiplicity==2)  => calling overloaded function */
       
  1136       int fdecl_mutiplicity =  function_symtable.multiplicity(symbol->function_name);
       
  1137       if (fdecl_mutiplicity == 0) ERROR;
       
  1138       if (fdecl_mutiplicity == 1) 
       
  1139         /* function being called is NOT overloaded! */
       
  1140         f_decl = NULL; 
       
  1141 
  1053       if (has_output_params)
  1142       if (has_output_params)
  1054         generate_inline(function_name, function_type_prefix, function_type_suffix, param_list);
  1143         generate_inline(function_name, function_type_prefix, function_type_suffix, param_list, f_decl);
  1055 
  1144 
  1056       CLEAR_PARAM_LIST()
  1145       CLEAR_PARAM_LIST()
  1057 
  1146 
  1058       return NULL;
  1147       return NULL;
  1059     }
  1148     }