stage4/generate_c/generate_c_inlinefcall.cc
changeset 350 2c3c4dc34979
parent 336 229eb3e29216
child 355 30db860bd3bd
equal deleted inserted replaced
341:ba80c3ceb6fb 350:2c3c4dc34979
    82       while ((function_call = fc_iterator.next()) != NULL) {
    82       while ((function_call = fc_iterator.next()) != NULL) {
    83     	function_call->accept(*this);
    83     	function_call->accept(*this);
    84       }
    84       }
    85     }
    85     }
    86 
    86 
       
    87 
       
    88 
    87     void generate_inline(symbol_c *function_name,
    89     void generate_inline(symbol_c *function_name,
    88             symbol_c *function_type_prefix,
    90             symbol_c *function_type_prefix,
    89             symbol_c *function_type_suffix,
    91             symbol_c *function_type_suffix,
    90             std::list<FUNCTION_PARAM*> param_list) {
    92             std::list<FUNCTION_PARAM*> param_list,
       
    93             function_declaration_c *f_decl = NULL) {
    91             std::list<FUNCTION_PARAM*>::iterator pt;
    94             std::list<FUNCTION_PARAM*>::iterator pt;
    92 
    95 
    93       fcall_number++;
    96       fcall_number++;
    94       function_type_prefix = search_expression_type->default_literal_type(function_type_prefix);
    97       function_type_prefix = search_expression_type->default_literal_type(function_type_prefix);
    95       if (function_type_suffix) {
    98       if (function_type_suffix) {
   101       function_type_prefix->accept(*this);
   104       function_type_prefix->accept(*this);
   102       s4o.print(" __");
   105       s4o.print(" __");
   103       fbname->accept(*this);
   106       fbname->accept(*this);
   104       s4o.print("_");
   107       s4o.print("_");
   105       function_name->accept(*this);
   108       function_name->accept(*this);
       
   109       if (f_decl != NULL) {
       
   110 printf("generate_inline(): calling print_function_parameter_data_types_c !!!!!!!!!!!!!!!!!!!!!!\n");
       
   111         print_function_parameter_data_types_c overloaded_func_suf(&s4o);
       
   112         f_decl->accept(overloaded_func_suf);
       
   113       }	
   106       if (function_type_suffix) {
   114       if (function_type_suffix) {
   107     	function_type_suffix->accept(*this);
   115         function_type_suffix->accept(*this);
   108       }
   116       }
   109       s4o.print_integer(fcall_number);
   117       s4o.print_integer(fcall_number);
   110       s4o.print("(");
   118       s4o.print("(");
   111       s4o.indent_right();
   119       s4o.indent_right();
   112 
   120 
   117           PARAM_NAME->accept(*this);
   125           PARAM_NAME->accept(*this);
   118           s4o.print(",\n" + s4o.indent_spaces);
   126           s4o.print(",\n" + s4o.indent_spaces);
   119         }
   127         }
   120       }
   128       }
   121       fbname->accept(*this);
   129       fbname->accept(*this);
   122 	  s4o.print(" *");
   130       s4o.print(" *");
   123 	  s4o.print(FB_FUNCTION_PARAM);
   131       s4o.print(FB_FUNCTION_PARAM);
   124 	  s4o.indent_left();
   132       s4o.indent_left();
   125 	  s4o.print(")\n" + s4o.indent_spaces);
   133       s4o.print(")\n" + s4o.indent_spaces);
   126 	  s4o.print("{\n");
   134       s4o.print("{\n");
   127       s4o.indent_right();
   135       s4o.indent_right();
   128 
   136 
   129       s4o.print(s4o.indent_spaces);
   137       s4o.print(s4o.indent_spaces);
   130       function_type_prefix->accept(*this);
   138       function_type_prefix->accept(*this);
   131       s4o.print(" "),
   139       s4o.print(" "),
   132       s4o.print(INLINE_RESULT_TEMP_VAR);
   140       s4o.print(INLINE_RESULT_TEMP_VAR);
   133       s4o.print(";\n");
   141       s4o.print(";\n");
   134 
   142 
   135 	  PARAM_LIST_ITERATOR() {
   143       PARAM_LIST_ITERATOR() {
   136 		if ((PARAM_DIRECTION == function_param_iterator_c::direction_out ||
   144         if ((PARAM_DIRECTION == function_param_iterator_c::direction_out ||
   137 		     PARAM_DIRECTION == function_param_iterator_c::direction_inout) &&
   145              PARAM_DIRECTION == function_param_iterator_c::direction_inout) &&
   138 		    PARAM_VALUE != NULL) {
   146              PARAM_VALUE != NULL) {
   139 		  s4o.print(s4o.indent_spaces);
   147           s4o.print(s4o.indent_spaces);
   140 		  PARAM_TYPE->accept(*this);
   148           PARAM_TYPE->accept(*this);
   141           s4o.print(" ");
   149           s4o.print(" ");
   142           s4o.print(TEMP_VAR);
   150           s4o.print(TEMP_VAR);
   143           PARAM_NAME->accept(*this);
   151           PARAM_NAME->accept(*this);
   144           s4o.print(" = ");
   152           s4o.print(" = ");
   145           print_check_function(PARAM_TYPE, PARAM_VALUE);
   153           print_check_function(PARAM_TYPE, PARAM_VALUE);
   146           s4o.print(";\n");
   154           s4o.print(";\n");
   147 		}
   155           }
   148 	  }
   156         }
   149 
   157 
   150 	  s4o.print(s4o.indent_spaces + INLINE_RESULT_TEMP_VAR),
   158       s4o.print(s4o.indent_spaces + INLINE_RESULT_TEMP_VAR),
   151 			  s4o.print(" = ");
   159       s4o.print(" = ");
   152 	  function_name->accept(*this);
   160       function_name->accept(*this);
   153 	  if (function_type_suffix)
   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       }
       
   166 
       
   167       if (function_type_suffix)
   154         function_type_suffix->accept(*this);
   168         function_type_suffix->accept(*this);
   155 	  s4o.print("(");
   169       s4o.print("(");
   156 	  s4o.indent_right();
   170       s4o.indent_right();
   157 
   171 
   158 	  PARAM_LIST_ITERATOR() {
   172       PARAM_LIST_ITERATOR() {
   159 		if (pt != param_list.begin())
   173         if (pt != param_list.begin())
   160 		  s4o.print(",\n" + s4o.indent_spaces);
   174         s4o.print(",\n" + s4o.indent_spaces);
   161 		if (PARAM_DIRECTION == function_param_iterator_c::direction_in)
   175         if (PARAM_DIRECTION == function_param_iterator_c::direction_in)
   162 		  PARAM_NAME->accept(*this);
   176           PARAM_NAME->accept(*this);
   163 		else if (PARAM_VALUE != NULL){
   177         else if (PARAM_VALUE != NULL){
   164           s4o.print("&");
   178           s4o.print("&");
   165           s4o.print(TEMP_VAR);
   179           s4o.print(TEMP_VAR);
   166           PARAM_NAME->accept(*this);
   180           PARAM_NAME->accept(*this);
   167         }
   181         } else {
   168 		else {
   182           s4o.print("NULL");
   169 		  s4o.print("NULL");
   183          }
   170 		}
   184       }
   171 	  }
   185       s4o.print(");\n");
   172 	  s4o.print(");\n");
   186       s4o.indent_left();
   173 	  s4o.indent_left();
   187 
   174 
   188       PARAM_LIST_ITERATOR() {
   175 	  PARAM_LIST_ITERATOR() {
       
   176         if ((PARAM_DIRECTION == function_param_iterator_c::direction_out ||
   189         if ((PARAM_DIRECTION == function_param_iterator_c::direction_out ||
   177         	 PARAM_DIRECTION == function_param_iterator_c::direction_inout) &&
   190              PARAM_DIRECTION == function_param_iterator_c::direction_inout) &&
   178         	PARAM_VALUE != NULL) {
   191              PARAM_VALUE != NULL) {
   179 
       
   180           s4o.print(s4o.indent_spaces);
   192           s4o.print(s4o.indent_spaces);
   181           print_setter(PARAM_VALUE, PARAM_TYPE, PARAM_NAME);
   193           print_setter(PARAM_VALUE, PARAM_TYPE, PARAM_NAME);
   182           s4o.print(";\n");
   194           s4o.print(";\n");
   183 		}
   195         }
   184 	  }
   196       }
   185 	  s4o.print(s4o.indent_spaces + "return ");
   197       s4o.print(s4o.indent_spaces + "return ");
   186 	  s4o.print(INLINE_RESULT_TEMP_VAR);
   198       s4o.print(INLINE_RESULT_TEMP_VAR);
   187 	  s4o.print(";\n");
   199       s4o.print(";\n");
   188 
   200 
   189       s4o.indent_left();
   201       s4o.indent_left();
   190       s4o.print(s4o.indent_spaces + "}\n\n");
   202       s4o.print(s4o.indent_spaces + "}\n\n");
   191     }
   203     }
   192 
   204 
   340     /* B 2.1 Instructions and Operands */
   352     /* B 2.1 Instructions and Operands */
   341     /***********************************/
   353     /***********************************/
   342 
   354 
   343     void *visit(il_function_call_c *symbol) {
   355     void *visit(il_function_call_c *symbol) {
   344       symbol_c* function_type_prefix = NULL;
   356       symbol_c* function_type_prefix = NULL;
   345       symbol_c* function_name = NULL;
   357       symbol_c* function_name = NULL;     
   346       symbol_c* function_type_suffix = NULL;
   358       symbol_c* function_type_suffix = NULL;
   347       DECLARE_PARAM_LIST()
   359       DECLARE_PARAM_LIST()
   348 
   360 
   349       symbol_c *param_data_type = default_variable_name.current_type;
   361       symbol_c *param_data_type = default_variable_name.current_type;
   350 
   362 
   351       function_call_param_iterator_c function_call_param_iterator(symbol);
   363       function_call_param_iterator_c function_call_param_iterator(symbol);
   352 
   364 
   353       function_declaration_c *f_decl = function_symtable.find_value(symbol->function_name);
   365       function_declaration_c *f_decl = (function_declaration_c *)symbol->called_function_declaration;
   354 	  if (f_decl == function_symtable.end_value()) {
   366       if (f_decl == NULL) ERROR;
   355         function_type_t current_function_type = get_function_type((identifier_c *)symbol->function_name);
   367       
   356         if (current_function_type == function_none) ERROR;
   368       /* determine the base data type returned by the function being called... */
   357 
   369       search_base_type_c search_base_type;
   358         function_type_prefix = (symbol_c *)search_expression_type->compute_standard_function_il(symbol, param_data_type);
   370       function_type_prefix = (symbol_c *)f_decl->type_name->accept(search_base_type);
   359 
   371       
   360         symbol_c *en_param_name = (symbol_c *)(new identifier_c("EN"));
   372       function_name = symbol->function_name;      
   361         /* Add the value from EN param */
   373       
   362         ADD_PARAM_LIST(en_param_name,
   374       /* loop through each function parameter, find the value we should pass
   363                        (symbol_c*)(new boolean_literal_c((symbol_c*)(new bool_type_name_c()), new boolean_true_c())),
   375        * to it, and then output the c equivalent...
   364                        (symbol_c*)(new bool_type_name_c()),
   376        */
   365                        function_param_iterator_c::direction_in)
   377       
   366 
   378       function_param_iterator_c fp_iterator(f_decl);
   367         symbol_c *eno_param_name = (symbol_c *)(new identifier_c("ENO"));
   379       identifier_c *param_name;
   368         /* Add the value from ENO param */
   380         /* flag to remember whether we have already used the value stored in the default variable to pass to the first parameter */
   369         ADD_PARAM_LIST(eno_param_name, NULL, (symbol_c*)(new bool_type_name_c()), function_param_iterator_c::direction_out)
   381       bool used_defvar = false;       
   370 
   382         /* flag to cirreclty handle calls to extensible standard functions (i.e. functions with variable number of input parameters) */
   371         int nb_param = 1;
   383       bool found_first_extensible_parameter = false;  
   372         if (symbol->il_operand_list != NULL)
   384       for(int i = 1; (param_name = fp_iterator.next()) != NULL; i++) {
   373           nb_param += ((list_c *)symbol->il_operand_list)->n;
   385         if (fp_iterator.is_extensible_param() && (!found_first_extensible_parameter)) {
   374 
   386           /* We are calling an extensible function. Before passing the extensible
   375         #include "il_code_gen.c"
   387            * parameters, we must add a dummy paramater value to tell the called
   376 
   388            * function how many extensible parameters we will be passing.
   377       }
   389            *
   378 	  else {
   390            * Note that stage 3 has already determined the number of extensible
   379 		function_name = symbol->function_name;
   391            * paramters, and stored that info in the abstract syntax tree. We simply
   380 
   392            * re-use that value.
   381 		/* determine the base data type returned by the function being called... */
   393            */
   382 		search_base_type_c search_base_type;
   394           /* NOTE: we are not freeing the malloc'd memory. This is not really a bug.
   383 		function_type_prefix = (symbol_c *)f_decl->type_name->accept(search_base_type);
   395            *       Since we are writing a compiler, which runs to termination quickly,
   384 
   396            *       we can consider this as just memory required for the compilation process
   385 		/* loop through each function parameter, find the value we should pass
   397            *       that will be free'd when the program terminates.
   386 		 * to it, and then output the c equivalent...
   398            */
   387 		 */
   399           char *tmp = (char *)malloc(32); /* enough space for a call with 10^31 (larger than 2^64) input parameters! */
   388 
   400           if (tmp == NULL) ERROR;
   389 		function_param_iterator_c fp_iterator(f_decl);
   401           int res = snprintf(tmp, 32, "%d", symbol->extensible_param_count);
   390 		identifier_c *param_name;
   402           if ((res >= 32) || (res < 0)) ERROR;
   391 		for(int i = 1; (param_name = fp_iterator.next()) != NULL; i++) {
   403           identifier_c *param_value = new identifier_c(tmp);
   392 		  symbol_c *param_type = fp_iterator.param_type();
   404           uint_type_name_c *param_type  = new uint_type_name_c();
   393 		  if (param_type == NULL) ERROR;
   405           identifier_c *param_name = new identifier_c("");
   394 
   406           ADD_PARAM_LIST(param_name, param_value, param_type, function_param_iterator_c::direction_in)
   395 		  function_param_iterator_c::param_direction_t param_direction = fp_iterator.param_direction();
   407           found_first_extensible_parameter = true;
   396 
   408         }
   397 		  symbol_c *param_value = NULL;
   409     
   398 
   410         symbol_c *param_type = fp_iterator.param_type();
   399 		  /* if it is the first parameter, semantics specifies that we should
   411         if (param_type == NULL) ERROR;
   400 		   * get the value off the IL default variable!
   412       
   401 		   */
   413         function_param_iterator_c::param_direction_t param_direction = fp_iterator.param_direction();
   402 		  if (1 == i)
   414       
   403 		    param_value = &this->default_variable_name;
   415         symbol_c *param_value = NULL;
   404 
   416       
   405 		  /* Get the value from a foo(<param_name> = <param_value>) style call */
   417         /* Get the value from a foo(<param_name> = <param_value>) style call */
   406 		  /* NOTE: the following line of code is not required in this case, but it doesn't
   418         /* NOTE: the following line of code is not required in this case, but it doesn't
   407 		   * harm to leave it in, as in the case of a non-formal syntax function call,
   419          * harm to leave it in, as in the case of a non-formal syntax function call,
   408 		   * it will always return NULL.
   420          * it will always return NULL.
   409 		   * We leave it in in case we later decide to merge this part of the code together
   421          * We leave it in in case we later decide to merge this part of the code together
   410 		   * with the function calling code in generate_c_st_c, which does require
   422          * with the function calling code in generate_c_st_c, which does require
   411 		   * the following line...
   423          * the following line...
   412 		   */
   424          */
   413 		  if (param_value == NULL)
   425         if (param_value == NULL)
   414 			param_value = function_call_param_iterator.search_f(param_name);
   426           param_value = function_call_param_iterator.search_f(param_name);
   415 
   427 
   416 		  /* Get the value from a foo(<param_value>) style call */
   428         /* if it is the first parameter in a non-formal function call (which is the
   417           if (param_value == NULL) {
   429          * case being handled!), semantics specifies that we should
   418             param_value = function_call_param_iterator.next_nf();
   430          * get the value off the IL default variable!
   419             if (param_value != NULL && fp_iterator.is_en_eno_param_implicit()) ERROR;
   431          *
   420           }
   432          * However, if the parameter is an implicitly defined EN or ENO parameter, we should not
   421 
   433          * use the default variable as a source of data to pass to those parameters!
   422 		  if (param_value == NULL && param_direction == function_param_iterator_c::direction_in) {
   434          */
   423 			/* No value given for parameter, so we must use the default... */
   435         if ((param_value == NULL) && (!used_defvar) && !fp_iterator.is_en_eno_param_implicit()) {
   424 			/* First check whether default value specified in function declaration...*/
   436           param_value = &this->default_variable_name;
   425 			param_value = fp_iterator.default_value();
   437           used_defvar = true;
   426 		  }
   438         }
   427 
   439 
   428 		  ADD_PARAM_LIST(param_name, param_value, param_type, fp_iterator.param_direction())
   440         /* Get the value from a foo(<param_value>) style call */
   429 		} /* for(...) */
   441         if ((param_value == NULL) && !fp_iterator.is_en_eno_param_implicit()) {
   430 	  }
   442           param_value = function_call_param_iterator.next_nf();
   431 
   443         }
   432 	  if (function_call_param_iterator.next_nf() != NULL) ERROR;
   444         
       
   445         /* if no more parameter values in function call, and the current parameter
       
   446          * of the function declaration is an extensible parameter, we
       
   447          * have reached the end, and should simply jump out of the for loop.
       
   448          */
       
   449         if ((param_value == NULL) && (fp_iterator.is_extensible_param())) {
       
   450           break;
       
   451         }
       
   452       
       
   453         if ((param_value == NULL) && (param_direction == function_param_iterator_c::direction_in)) {
       
   454           /* No value given for parameter, so we must use the default... */
       
   455           /* First check whether default value specified in function declaration...*/
       
   456           param_value = fp_iterator.default_value();
       
   457         }
       
   458       
       
   459         ADD_PARAM_LIST(param_name, param_value, param_type, fp_iterator.param_direction())
       
   460       } /* for(...) */
       
   461 
       
   462       if (function_call_param_iterator.next_nf() != NULL) ERROR;
   433       if (NULL == function_type_prefix) ERROR;
   463       if (NULL == function_type_prefix) ERROR;
   434 
   464 
   435       bool has_output_params = false;
   465       bool has_output_params = false;
   436 
   466 
   437       PARAM_LIST_ITERATOR() {
   467       PARAM_LIST_ITERATOR() {
   440              PARAM_VALUE != NULL) {
   470              PARAM_VALUE != NULL) {
   441           has_output_params = true;
   471           has_output_params = true;
   442         }
   472         }
   443       }
   473       }
   444 
   474 
       
   475       /* Check whether we are calling an overloaded function! */
       
   476       /* (fdecl_mutiplicity==2)  => calling overloaded function */
       
   477       int fdecl_mutiplicity =  function_symtable.multiplicity(symbol->function_name);
       
   478       if (fdecl_mutiplicity == 0) ERROR;
       
   479       if (fdecl_mutiplicity == 1) 
       
   480         /* function being called is NOT overloaded! */
       
   481         f_decl = NULL; 
       
   482 
   445       if (has_output_params)
   483       if (has_output_params)
   446         generate_inline(function_name, function_type_prefix, function_type_suffix, param_list);
   484         generate_inline(function_name, function_type_prefix, function_type_suffix, param_list, f_decl);
   447 
   485 
   448       CLEAR_PARAM_LIST()
   486       CLEAR_PARAM_LIST()
   449 
   487 
   450       return NULL;
   488       return NULL;
   451     }
   489     }
   458       symbol_c* function_type_suffix = NULL;
   496       symbol_c* function_type_suffix = NULL;
   459       DECLARE_PARAM_LIST()
   497       DECLARE_PARAM_LIST()
   460 
   498 
   461       function_call_param_iterator_c function_call_param_iterator(symbol);
   499       function_call_param_iterator_c function_call_param_iterator(symbol);
   462 
   500 
   463       function_declaration_c *f_decl = function_symtable.find_value(symbol->function_name);
   501       function_declaration_c *f_decl = (function_declaration_c *)symbol->called_function_declaration;
   464       if (f_decl == function_symtable.end_value()) {
   502       if (f_decl == NULL) ERROR;
   465         function_type_t current_function_type = get_function_type((identifier_c *)symbol->function_name);
   503 
   466         if (current_function_type == function_none) ERROR;
   504       /* determine the base data type returned by the function being called... */
   467 
   505       search_base_type_c search_base_type;
   468         function_type_prefix = (symbol_c *)search_expression_type->compute_standard_function_default(NULL, symbol);
   506       function_type_prefix = (symbol_c *)f_decl->type_name->accept(search_base_type);
   469 
   507       if (NULL == function_type_prefix) ERROR;
   470         int nb_param = 0;
   508       
   471         if (symbol->il_param_list != NULL)
   509       function_name = symbol->function_name;
   472           nb_param += ((list_c *)symbol->il_param_list)->n;
   510 
   473 
   511       /* loop through each function parameter, find the value we should pass
   474         symbol_c *en_param_name = (symbol_c *)(new identifier_c("EN"));
   512        * to it, and then output the c equivalent...
   475         /* Get the value from EN param */
   513        */
   476         symbol_c *EN_param_value = function_call_param_iterator.search_f(en_param_name);
   514       function_param_iterator_c fp_iterator(f_decl);
   477         if (EN_param_value == NULL)
   515       identifier_c *param_name;
   478           EN_param_value = (symbol_c*)(new boolean_literal_c((symbol_c*)(new bool_type_name_c()), new boolean_true_c()));
   516 
   479         else
   517         /* flag to cirreclty handle calls to extensible standard functions (i.e. functions with variable number of input parameters) */
   480           nb_param --;
   518       bool found_first_extensible_parameter = false;
   481         ADD_PARAM_LIST(en_param_name, EN_param_value, (symbol_c*)(new bool_type_name_c()), function_param_iterator_c::direction_in)
   519       for(int i = 1; (param_name = fp_iterator.next()) != NULL; i++) {
   482 
   520         if (fp_iterator.is_extensible_param() && (!found_first_extensible_parameter)) {
   483         symbol_c *eno_param_name = (symbol_c *)(new identifier_c("ENO"));
   521           /* We are calling an extensible function. Before passing the extensible
   484         /* Get the value from ENO param */
   522            * parameters, we must add a dummy paramater value to tell the called
   485         symbol_c *ENO_param_value = function_call_param_iterator.search_f(eno_param_name);
   523            * function how many extensible parameters we will be passing.
   486         if (ENO_param_value != NULL)
   524            *
   487           nb_param --;
   525            * Note that stage 3 has already determined the number of extensible
   488         ADD_PARAM_LIST(eno_param_name, ENO_param_value, (symbol_c*)(new bool_type_name_c()), function_param_iterator_c::direction_out)
   526            * paramters, and stored that info in the abstract syntax tree. We simply
   489 
   527            * re-use that value.
   490         #include "st_code_gen.c"
   528            */
   491 
   529           /* NOTE: we are not freeing the malloc'd memory. This is not really a bug.
   492       }
   530            *       Since we are writing a compiler, which runs to termination quickly,
   493       else {
   531            *       we can consider this as just memory required for the compilation process
   494         function_name = symbol->function_name;
   532            *       that will be free'd when the program terminates.
   495 
   533            */
   496 		/* determine the base data type returned by the function being called... */
   534           char *tmp = (char *)malloc(32); /* enough space for a call with 10^31 (larger than 2^64) input parameters! */
   497 		search_base_type_c search_base_type;
   535           if (tmp == NULL) ERROR;
   498 		function_type_prefix = (symbol_c *)f_decl->type_name->accept(search_base_type);
   536           int res = snprintf(tmp, 32, "%d", symbol->extensible_param_count);
   499 
   537           if ((res >= 32) || (res < 0)) ERROR;
   500 		/* loop through each function parameter, find the value we should pass
   538           identifier_c *param_value = new identifier_c(tmp);
   501 		 * to it, and then output the c equivalent...
   539           uint_type_name_c *param_type  = new uint_type_name_c();
   502 		 */
   540           identifier_c *param_name = new identifier_c("");
   503 
   541           ADD_PARAM_LIST(param_name, param_value, param_type, function_param_iterator_c::direction_in)
   504 		function_param_iterator_c fp_iterator(f_decl);
   542           found_first_extensible_parameter = true;
   505 		identifier_c *param_name;
   543         }
   506 		for(int i = 1; (param_name = fp_iterator.next()) != NULL; i++) {
   544         
   507 		  symbol_c *param_type = fp_iterator.param_type();
   545         if (fp_iterator.is_extensible_param()) {      
   508 		  if (param_type == NULL) ERROR;
   546           /* since we are handling an extensible parameter, we must add the index to the
   509 
   547            * parameter name so we can go looking for the value passed to the correct
   510 		  function_param_iterator_c::param_direction_t param_direction = fp_iterator.param_direction();
   548            * extended parameter (e.g. IN1, IN2, IN3, IN4, ...)
   511 
   549            */
   512 
   550           char *tmp = (char *)malloc(32); /* enough space for a call with 10^31 (larger than 2^64) input parameters! */
   513 		  symbol_c *param_value = NULL;
   551           int res = snprintf(tmp, 32, "%d", fp_iterator.extensible_param_index());
   514 
   552           if ((res >= 32) || (res < 0)) ERROR;
   515 		  /* Get the value from a foo(<param_name> = <param_value>) style call */
   553           param_name = new identifier_c(strdup2(param_name->value, tmp));
   516 		  if (param_value == NULL)
   554           if (param_name->value == NULL) ERROR;
   517 			param_value = function_call_param_iterator.search_f(param_name);
   555         }
   518 
   556     
   519 		  /* Get the value from a foo(<param_value>) style call */
   557         symbol_c *param_type = fp_iterator.param_type();
   520 		  /* NOTE: the following line of code is not required in this case, but it doesn't
   558         if (param_type == NULL) ERROR;
   521 		   * harm to leave it in, as in the case of a formal syntax function call,
   559       
   522 		   * it will always return NULL.
   560         function_param_iterator_c::param_direction_t param_direction = fp_iterator.param_direction();
   523 		   * We leave it in in case we later decide to merge this part of the code together
   561       
   524 		   * with the function calling code in generate_c_st_c, which does require
   562         symbol_c *param_value = NULL;
   525 		   * the following line...
   563       
   526 		   */
   564         /* Get the value from a foo(<param_name> = <param_value>) style call */
   527 		  if (param_value == NULL) {
   565         if (param_value == NULL)
   528             param_value = function_call_param_iterator.next_nf();
   566           param_value = function_call_param_iterator.search_f(param_name);
   529             if (param_value != NULL && fp_iterator.is_en_eno_param_implicit()) ERROR;
   567       
   530           }
   568         /* Get the value from a foo(<param_value>) style call */
   531 
   569         /* NOTE: the following line of code is not required in this case, but it doesn't
   532 		  if (param_value == NULL) {
   570          * harm to leave it in, as in the case of a formal syntax function call,
   533 			/* No value given for parameter, so we must use the default... */
   571          * it will always return NULL.
   534 			/* First check whether default value specified in function declaration...*/
   572          * We leave it in in case we later decide to merge this part of the code together
   535 			param_value = fp_iterator.default_value();
   573          * with the function calling code in generate_c_st_c, which does require
   536 		  }
   574          * the following line...
   537 
   575          */
   538 		  ADD_PARAM_LIST(param_name, param_value, param_type, fp_iterator.param_direction())
   576         if ((param_value == NULL) && !fp_iterator.is_en_eno_param_implicit()) {
   539 		}
   577           param_value = function_call_param_iterator.next_nf();
       
   578         }
       
   579         
       
   580         /* if no more parameter values in function call, and the current parameter
       
   581          * of the function declaration is an extensible parameter, we
       
   582          * have reached the end, and should simply jump out of the for loop.
       
   583          */
       
   584         if ((param_value == NULL) && (fp_iterator.is_extensible_param())) {
       
   585           break;
       
   586         }
       
   587     
       
   588         if ((param_value == NULL) && (param_direction == function_param_iterator_c::direction_in)) {
       
   589           /* No value given for parameter, so we must use the default... */
       
   590           /* First check whether default value specified in function declaration...*/
       
   591           param_value = fp_iterator.default_value();
       
   592         }
       
   593 
       
   594         ADD_PARAM_LIST(param_name, param_value, param_type, fp_iterator.param_direction())
   540       }
   595       }
   541 
   596 
   542       if (function_call_param_iterator.next_nf() != NULL) ERROR;
   597       if (function_call_param_iterator.next_nf() != NULL) ERROR;
   543       if (NULL == function_type_prefix) ERROR;
       
   544 
   598 
   545       bool has_output_params = false;
   599       bool has_output_params = false;
   546 
   600 
   547       PARAM_LIST_ITERATOR() {
   601       PARAM_LIST_ITERATOR() {
   548         if ((PARAM_DIRECTION == function_param_iterator_c::direction_out ||
   602         if ((PARAM_DIRECTION == function_param_iterator_c::direction_out ||
   550              PARAM_VALUE != NULL) {
   604              PARAM_VALUE != NULL) {
   551           has_output_params = true;
   605           has_output_params = true;
   552         }
   606         }
   553       }
   607       }
   554 
   608 
       
   609       /* Check whether we are calling an overloaded function! */
       
   610       /* (fdecl_mutiplicity==2)  => calling overloaded function */
       
   611       int fdecl_mutiplicity =  function_symtable.multiplicity(symbol->function_name);
       
   612       if (fdecl_mutiplicity == 0) ERROR;
       
   613       if (fdecl_mutiplicity == 1) 
       
   614         /* function being called is NOT overloaded! */
       
   615         f_decl = NULL; 
       
   616 
   555       if (has_output_params)
   617       if (has_output_params)
   556         generate_inline(function_name, function_type_prefix, function_type_suffix, param_list);
   618         generate_inline(function_name, function_type_prefix, function_type_suffix, param_list, f_decl);
   557 
   619 
   558       CLEAR_PARAM_LIST()
   620       CLEAR_PARAM_LIST()
   559 
   621 
   560       return NULL;
   622       return NULL;
   561     }
   623     }
   578       if (NULL != symbol->nonformal_param_list) parameter_assignment_list = symbol->nonformal_param_list;
   640       if (NULL != symbol->nonformal_param_list) parameter_assignment_list = symbol->nonformal_param_list;
   579       if (NULL == parameter_assignment_list) ERROR;
   641       if (NULL == parameter_assignment_list) ERROR;
   580 
   642 
   581       function_call_param_iterator_c function_call_param_iterator(symbol);
   643       function_call_param_iterator_c function_call_param_iterator(symbol);
   582 
   644 
   583       function_declaration_c *f_decl = function_symtable.find_value(symbol->function_name);
   645       function_declaration_c *f_decl = (function_declaration_c *)symbol->called_function_declaration;
   584       if (f_decl == function_symtable.end_value()) {
   646       if (f_decl == NULL) ERROR;
   585         /* The function called is not in the symtable, so we test if it is a
   647 
   586          * standard function defined in standard */
   648       function_name = symbol->function_name;
   587 
   649 
   588         function_type_t current_function_type = get_function_type((identifier_c *)symbol->function_name);
   650       /* determine the base data type returned by the function being called... */
   589         if (current_function_type == function_none) ERROR;
   651       search_base_type_c search_base_type;
   590 
   652       function_type_prefix = (symbol_c *)f_decl->type_name->accept(search_base_type);
   591         function_type_prefix = search_expression_type->get_type(symbol);
   653       if (NULL == function_type_prefix) ERROR;
   592 
   654 
   593         int nb_param = ((list_c *)parameter_assignment_list)->n;
   655       /* loop through each function parameter, find the value we should pass
   594 
   656        * to it, and then output the c equivalent...
   595         symbol_c *en_param_name = (symbol_c *)(new identifier_c("EN"));
   657        */
   596         /* Get the value from EN param */
   658       function_param_iterator_c fp_iterator(f_decl);
   597         symbol_c *EN_param_value = function_call_param_iterator.search_f(en_param_name);
   659       identifier_c *param_name;
   598         if (EN_param_value == NULL)
   660         /* flag to cirreclty handle calls to extensible standard functions (i.e. functions with variable number of input parameters) */
   599           EN_param_value = (symbol_c*)(new boolean_literal_c((symbol_c*)(new bool_type_name_c()), new boolean_true_c()));
   661       bool found_first_extensible_parameter = false;  
   600         else
   662       for(int i = 1; (param_name = fp_iterator.next()) != NULL; i++) {
   601           nb_param --;
   663         if (fp_iterator.is_extensible_param() && (!found_first_extensible_parameter)) {
   602         ADD_PARAM_LIST(en_param_name, EN_param_value, (symbol_c*)(new bool_type_name_c()), function_param_iterator_c::direction_in)
   664           /* We are calling an extensible function. Before passing the extensible
   603 
   665            * parameters, we must add a dummy paramater value to tell the called
   604         symbol_c *eno_param_name = (symbol_c *)(new identifier_c("ENO"));
   666            * function how many extensible parameters we will be passing.
   605         /* Get the value from ENO param */
   667            *
   606         symbol_c *ENO_param_value = function_call_param_iterator.search_f(eno_param_name);
   668            * Note that stage 3 has already determined the number of extensible
   607         if (ENO_param_value != NULL)
   669            * paramters, and stored that info in the abstract syntax tree. We simply
   608           nb_param --;
   670            * re-use that value.
   609         ADD_PARAM_LIST(eno_param_name, ENO_param_value, (symbol_c*)(new bool_type_name_c()), function_param_iterator_c::direction_out)
   671            */
   610 
   672           /* NOTE: we are not freeing the malloc'd memory. This is not really a bug.
   611         #include "st_code_gen.c"
   673            *       Since we are writing a compiler, which runs to termination quickly,
   612 
   674            *       we can consider this as just memory required for the compilation process
   613       }
   675            *       that will be free'd when the program terminates.
   614       else {
   676            */
   615         function_name = symbol->function_name;
   677           char *tmp = (char *)malloc(32); /* enough space for a call with 10^31 (larger than 2^64) input parameters! */
   616 
   678           if (tmp == NULL) ERROR;
   617 	    /* determine the base data type returned by the function being called... */
   679           int res = snprintf(tmp, 32, "%d", symbol->extensible_param_count);
   618 		search_base_type_c search_base_type;
   680           if ((res >= 32) || (res < 0)) ERROR;
   619 		function_type_prefix = (symbol_c *)f_decl->type_name->accept(search_base_type);
   681           identifier_c *param_value = new identifier_c(tmp);
   620 
   682           uint_type_name_c *param_type  = new uint_type_name_c();
   621     	/* loop through each function parameter, find the value we should pass
   683           identifier_c *param_name = new identifier_c("");
   622          * to it, and then output the c equivalent...
   684           ADD_PARAM_LIST(param_name, param_value, param_type, function_param_iterator_c::direction_in)
       
   685           found_first_extensible_parameter = true;
       
   686         }
       
   687     
       
   688         if (fp_iterator.is_extensible_param()) {      
       
   689           /* since we are handling an extensible parameter, we must add the index to the
       
   690            * parameter name so we can go looking for the value passed to the correct
       
   691            * extended parameter (e.g. IN1, IN2, IN3, IN4, ...)
       
   692            */
       
   693           char *tmp = (char *)malloc(32); /* enough space for a call with 10^31 (larger than 2^64) input parameters! */
       
   694           int res = snprintf(tmp, 32, "%d", fp_iterator.extensible_param_index());
       
   695           if ((res >= 32) || (res < 0)) ERROR;
       
   696           param_name = new identifier_c(strdup2(param_name->value, tmp));
       
   697           if (param_name->value == NULL) ERROR;
       
   698         }
       
   699         
       
   700         symbol_c *param_type = fp_iterator.param_type();
       
   701         if (param_type == NULL) ERROR;
       
   702 
       
   703         function_param_iterator_c::param_direction_t param_direction = fp_iterator.param_direction();
       
   704 
       
   705         symbol_c *param_value = NULL;
       
   706     
       
   707         /* Get the value from a foo(<param_name> = <param_value>) style call */
       
   708         if (param_value == NULL)
       
   709           param_value = function_call_param_iterator.search_f(param_name);
       
   710 
       
   711         /* Get the value from a foo(<param_value>) style call */
       
   712         if ((param_value == NULL) && !fp_iterator.is_en_eno_param_implicit()) {
       
   713           param_value = function_call_param_iterator.next_nf();
       
   714         }
       
   715         
       
   716         /* if no more parameter values in function call, and the current parameter
       
   717          * of the function declaration is an extensible parameter, we
       
   718          * have reached the end, and should simply jump out of the for loop.
   623          */
   719          */
   624         function_param_iterator_c fp_iterator(f_decl);
   720         if ((param_value == NULL) && (fp_iterator.is_extensible_param())) {
   625         identifier_c *param_name;
   721           break;
   626         for(int i = 1; (param_name = fp_iterator.next()) != NULL; i++) {
   722         }
   627           symbol_c *param_type = fp_iterator.param_type();
   723     
   628           if (param_type == NULL) ERROR;
   724         if ((param_value == NULL) && (param_direction == function_param_iterator_c::direction_in)) {
   629 
   725           /* No value given for parameter, so we must use the default... */
   630           function_param_iterator_c::param_direction_t param_direction = fp_iterator.param_direction();
   726           /* First check whether default value specified in function declaration...*/
   631 
   727           param_value = fp_iterator.default_value();
   632           /* Get the value from a foo(<param_name> = <param_value>) style call */
   728         }
   633           symbol_c *param_value = function_call_param_iterator.search_f(param_name);
   729 
   634 
   730         ADD_PARAM_LIST(param_name, param_value, param_type, param_direction)
   635           /* Get the value from a foo(<param_value>) style call */
   731       } /* for(...) */
   636           if (param_value == NULL) {
   732       // symbol->parameter_assignment->accept(*this);
   637             param_value = function_call_param_iterator.next_nf();
       
   638             if (param_value != NULL && fp_iterator.is_en_eno_param_implicit()) ERROR;
       
   639           }
       
   640 
       
   641           if (param_value == NULL && param_direction == function_param_iterator_c::direction_in) {
       
   642             /* No value given for parameter, so we must use the default... */
       
   643             /* First check whether default value specified in function declaration...*/
       
   644             param_value = fp_iterator.default_value();
       
   645           }
       
   646 
       
   647           ADD_PARAM_LIST(param_name, param_value, param_type, param_direction)
       
   648         } /* for(...) */
       
   649         // symbol->parameter_assignment->accept(*this);
       
   650       }
       
   651 
   733 
   652       if (function_call_param_iterator.next_nf() != NULL) ERROR;
   734       if (function_call_param_iterator.next_nf() != NULL) ERROR;
   653       if (NULL == function_type_prefix) ERROR;
   735 
   654 
   736       bool has_output_params = false;
   655 	  bool has_output_params = false;
   737 
   656 
   738       PARAM_LIST_ITERATOR() {
   657 	  PARAM_LIST_ITERATOR() {
       
   658         if ((PARAM_DIRECTION == function_param_iterator_c::direction_out ||
   739         if ((PARAM_DIRECTION == function_param_iterator_c::direction_out ||
   659              PARAM_DIRECTION == function_param_iterator_c::direction_inout) &&
   740              PARAM_DIRECTION == function_param_iterator_c::direction_inout) &&
   660              PARAM_VALUE != NULL) {
   741              PARAM_VALUE != NULL) {
   661           has_output_params = true;
   742           has_output_params = true;
   662         }
   743         }
   663       }
   744       }
   664 
   745 
       
   746       /* Check whether we are calling an overloaded function! */
       
   747       /* (fdecl_mutiplicity==2)  => calling overloaded function */
       
   748       int fdecl_mutiplicity =  function_symtable.multiplicity(symbol->function_name);
       
   749       if (fdecl_mutiplicity == 0) ERROR;
       
   750       if (fdecl_mutiplicity == 1) 
       
   751         /* function being called is NOT overloaded! */
       
   752         f_decl = NULL; 
       
   753 
   665       if (has_output_params)
   754       if (has_output_params)
   666         generate_inline(function_name, function_type_prefix, function_type_suffix, param_list);
   755         generate_inline(function_name, function_type_prefix, function_type_suffix, param_list, f_decl);
   667 
   756 
   668       CLEAR_PARAM_LIST()
   757       CLEAR_PARAM_LIST()
   669 
   758 
   670 	  return NULL;
   759       return NULL;
   671     }
   760     }
   672 
   761 
   673 };  /* generate_c_inlinefcall_c */
   762 };  /* generate_c_inlinefcall_c */
   674 
   763 
   675 
   764