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