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() { |
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 || |
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 |