38 /***********************************************************************/ |
38 /***********************************************************************/ |
39 |
39 |
40 |
40 |
41 class generate_c_st_c: public generate_c_typedecl_c { |
41 class generate_c_st_c: public generate_c_typedecl_c { |
42 |
42 |
|
43 public: |
|
44 typedef enum { |
|
45 expression_vg, |
|
46 assignment_vg, |
|
47 fparam_output_vg |
|
48 } variablegeneration_t; |
|
49 |
43 private: |
50 private: |
44 /* When calling a function block, we must first find it's type, |
51 /* When calling a function block, we must first find it's type, |
45 * by searching through the declarations of the variables currently |
52 * by searching through the declarations of the variables currently |
46 * in scope. |
53 * in scope. |
47 * This class does just that... |
54 * This class does just that... |
70 |
77 |
71 search_base_type_c search_base_type; |
78 search_base_type_c search_base_type; |
72 |
79 |
73 symbol_c* current_array_type; |
80 symbol_c* current_array_type; |
74 |
81 |
75 bool current_param_is_pointer; |
82 int fcall_number; |
|
83 symbol_c *fbname; |
|
84 |
|
85 variablegeneration_t wanted_variablegeneration; |
76 |
86 |
77 public: |
87 public: |
78 generate_c_st_c(stage4out_c *s4o_ptr, symbol_c *scope, const char *variable_prefix = NULL) |
88 generate_c_st_c(stage4out_c *s4o_ptr, symbol_c *name, symbol_c *scope, const char *variable_prefix = NULL) |
79 : generate_c_typedecl_c(s4o_ptr) { |
89 : generate_c_typedecl_c(s4o_ptr) { |
80 search_fb_instance_decl = new search_fb_instance_decl_c(scope); |
90 search_fb_instance_decl = new search_fb_instance_decl_c(scope); |
81 search_expression_type = new search_expression_type_c(scope); |
91 search_expression_type = new search_expression_type_c(scope); |
82 search_varfb_instance_type = new search_varfb_instance_type_c(scope); |
92 search_varfb_instance_type = new search_varfb_instance_type_c(scope); |
83 this->set_variable_prefix(variable_prefix); |
93 this->set_variable_prefix(variable_prefix); |
84 current_array_type = NULL; |
94 current_array_type = NULL; |
85 current_param_is_pointer = false; |
95 fcall_number = 0; |
|
96 fbname = name; |
|
97 wanted_variablegeneration = expression_vg; |
86 } |
98 } |
87 |
99 |
88 virtual ~generate_c_st_c(void) { |
100 virtual ~generate_c_st_c(void) { |
89 delete search_fb_instance_decl; |
101 delete search_fb_instance_decl; |
90 delete search_expression_type; |
102 delete search_expression_type; |
103 /*********************/ |
115 /*********************/ |
104 /* B 1.4 - Variables */ |
116 /* B 1.4 - Variables */ |
105 /*********************/ |
117 /*********************/ |
106 void *visit(symbolic_variable_c *symbol) { |
118 void *visit(symbolic_variable_c *symbol) { |
107 unsigned int vartype = search_varfb_instance_type->get_vartype(symbol); |
119 unsigned int vartype = search_varfb_instance_type->get_vartype(symbol); |
108 if (!current_param_is_pointer && (vartype == search_var_instance_decl_c::external_vt || vartype == search_var_instance_decl_c::located_vt)) { |
120 if (this->is_variable_prefix_null()) { |
109 s4o.print("*("); |
121 if (wanted_variablegeneration == fparam_output_vg) { |
110 generate_c_base_c::visit(symbol); |
122 if (vartype == search_var_instance_decl_c::external_vt) { |
111 s4o.print(")"); |
123 s4o.print(GET_EXTERNAL); |
112 } |
124 s4o.print("("); |
113 else if (current_param_is_pointer && vartype != search_var_instance_decl_c::external_vt && vartype != search_var_instance_decl_c::located_vt) { |
125 symbol->var_name->accept(*this); |
114 s4o.print("&("); |
126 } |
115 generate_c_base_c::visit(symbol); |
127 else { |
116 s4o.print(")"); |
128 s4o.print("&("); |
|
129 generate_c_base_c::visit(symbol); |
|
130 } |
|
131 s4o.print(")"); |
|
132 } |
|
133 else { |
|
134 if (vartype == search_var_instance_decl_c::external_vt) { |
|
135 s4o.print(GET_EXTERNAL); |
|
136 s4o.print("("); |
|
137 symbol->var_name->accept(*this); |
|
138 s4o.print(")"); |
|
139 } |
|
140 else |
|
141 generate_c_base_c::visit(symbol); |
|
142 } |
117 } |
143 } |
118 else { |
144 else { |
119 generate_c_base_c::visit(symbol); |
145 switch (wanted_variablegeneration) { |
|
146 case expression_vg: |
|
147 if (vartype == search_var_instance_decl_c::external_vt) { |
|
148 s4o.print(GET_EXTERNAL); |
|
149 s4o.print("("); |
|
150 symbol->var_name->accept(*this); |
|
151 } |
|
152 else { |
|
153 if (vartype == search_var_instance_decl_c::located_vt) |
|
154 s4o.print(GET_LOCATED); |
|
155 else |
|
156 s4o.print(GET_VAR); |
|
157 s4o.print("("); |
|
158 generate_c_base_c::visit(symbol); |
|
159 } |
|
160 s4o.print(")"); |
|
161 break; |
|
162 case fparam_output_vg: |
|
163 if (vartype == search_var_instance_decl_c::external_vt) { |
|
164 s4o.print(GET_EXTERNAL_BY_REF); |
|
165 s4o.print("("); |
|
166 symbol->var_name->accept(*this); |
|
167 } |
|
168 else { |
|
169 if (vartype == search_var_instance_decl_c::located_vt) |
|
170 s4o.print(GET_LOCATED_BY_REF); |
|
171 else |
|
172 s4o.print(GET_VAR_BY_REF); |
|
173 s4o.print("("); |
|
174 generate_c_base_c::visit(symbol); |
|
175 } |
|
176 s4o.print(")"); |
|
177 break; |
|
178 default: |
|
179 if (vartype == search_var_instance_decl_c::external_vt) |
|
180 symbol->var_name->accept(*this); |
|
181 else |
|
182 generate_c_base_c::visit(symbol); |
|
183 break; |
|
184 } |
120 } |
185 } |
121 return NULL; |
186 return NULL; |
122 } |
187 } |
123 |
188 |
124 /********************************************/ |
189 /********************************************/ |
127 // direct_variable: direct_variable_token {$$ = new direct_variable_c($1);}; |
192 // direct_variable: direct_variable_token {$$ = new direct_variable_c($1);}; |
128 void *visit(direct_variable_c *symbol) { |
193 void *visit(direct_variable_c *symbol) { |
129 TRACE("direct_variable_c"); |
194 TRACE("direct_variable_c"); |
130 /* Do not use print_token() as it will change everything into uppercase */ |
195 /* Do not use print_token() as it will change everything into uppercase */ |
131 if (strlen(symbol->value) == 0) ERROR; |
196 if (strlen(symbol->value) == 0) ERROR; |
132 if (!current_param_is_pointer) { |
197 if (this->is_variable_prefix_null()) { |
133 s4o.print("*("); |
198 if (wanted_variablegeneration != fparam_output_vg) |
|
199 s4o.print("*("); |
|
200 } |
|
201 else { |
|
202 switch (wanted_variablegeneration) { |
|
203 case expression_vg: |
|
204 s4o.print(GET_LOCATED); |
|
205 s4o.print("("); |
|
206 break; |
|
207 case fparam_output_vg: |
|
208 s4o.print(GET_LOCATED_BY_REF); |
|
209 s4o.print("("); |
|
210 break; |
|
211 default: |
|
212 break; |
|
213 } |
134 } |
214 } |
135 this->print_variable_prefix(); |
215 this->print_variable_prefix(); |
136 s4o.printlocation(symbol->value + 1); |
216 s4o.printlocation(symbol->value + 1); |
137 if (!current_param_is_pointer) { |
217 if ((this->is_variable_prefix_null() && wanted_variablegeneration != fparam_output_vg) || |
|
218 wanted_variablegeneration != assignment_vg) |
138 s4o.print(")"); |
219 s4o.print(")"); |
139 } |
|
140 return NULL; |
220 return NULL; |
141 } |
221 } |
142 |
222 |
143 /*************************************/ |
223 /*************************************/ |
144 /* B.1.4.2 Multi-element Variables */ |
224 /* B.1.4.2 Multi-element Variables */ |
402 |
482 |
403 void *visit(function_invocation_c *symbol) { |
483 void *visit(function_invocation_c *symbol) { |
404 symbol_c* function_type_prefix = NULL; |
484 symbol_c* function_type_prefix = NULL; |
405 symbol_c* function_name = NULL; |
485 symbol_c* function_name = NULL; |
406 symbol_c* function_type_suffix = NULL; |
486 symbol_c* function_type_suffix = NULL; |
407 std::list<FUNCTION_PARAM> param_list; |
487 DECLARE_PARAM_LIST() |
408 FUNCTION_PARAM *param; |
|
409 |
488 |
410 symbol_c *parameter_assignment_list = NULL; |
489 symbol_c *parameter_assignment_list = NULL; |
411 if (NULL != symbol-> formal_param_list) parameter_assignment_list = symbol-> formal_param_list; |
490 if (NULL != symbol-> formal_param_list) parameter_assignment_list = symbol-> formal_param_list; |
412 if (NULL != symbol->nonformal_param_list) parameter_assignment_list = symbol->nonformal_param_list; |
491 if (NULL != symbol->nonformal_param_list) parameter_assignment_list = symbol->nonformal_param_list; |
413 if (NULL == parameter_assignment_list) ERROR; |
492 if (NULL == parameter_assignment_list) ERROR; |
431 symbol_c *EN_param_value = function_call_param_iterator.search_f(&en_param_name); |
510 symbol_c *EN_param_value = function_call_param_iterator.search_f(&en_param_name); |
432 if (EN_param_value == NULL) |
511 if (EN_param_value == NULL) |
433 EN_param_value = (symbol_c*)(new boolean_literal_c((symbol_c*)(new bool_type_name_c()), new boolean_true_c())); |
512 EN_param_value = (symbol_c*)(new boolean_literal_c((symbol_c*)(new bool_type_name_c()), new boolean_true_c())); |
434 else |
513 else |
435 nb_param --; |
514 nb_param --; |
436 ADD_PARAM_LIST(EN_param_value, (symbol_c*)(new bool_type_name_c()), function_param_iterator_c::direction_in) |
515 ADD_PARAM_LIST(&en_param_name, EN_param_value, (symbol_c*)(new bool_type_name_c()), function_param_iterator_c::direction_in) |
437 |
516 |
438 identifier_c eno_param_name("ENO"); |
517 identifier_c eno_param_name("ENO"); |
439 /* Get the value from ENO param */ |
518 /* Get the value from ENO param */ |
440 symbol_c *ENO_param_value = function_call_param_iterator.search_f(&eno_param_name); |
519 symbol_c *ENO_param_value = function_call_param_iterator.search_f(&eno_param_name); |
441 if (ENO_param_value != NULL) |
520 if (ENO_param_value != NULL) |
442 nb_param --; |
521 nb_param --; |
443 ADD_PARAM_LIST(ENO_param_value, (symbol_c*)(new bool_type_name_c()), function_param_iterator_c::direction_out) |
522 ADD_PARAM_LIST(&eno_param_name, ENO_param_value, (symbol_c*)(new bool_type_name_c()), function_param_iterator_c::direction_out) |
444 |
523 |
445 #include "st_code_gen.c" |
524 #include "st_code_gen.c" |
446 |
525 |
447 } |
526 } |
448 else { |
527 else { |
449 /* loop through each function parameter, find the value we should pass |
528 function_name = symbol->function_name; |
|
529 |
|
530 /* loop through each function parameter, find the value we should pass |
450 * to it, and then output the c equivalent... |
531 * to it, and then output the c equivalent... |
451 */ |
532 */ |
452 function_param_iterator_c fp_iterator(f_decl); |
533 function_param_iterator_c fp_iterator(f_decl); |
453 |
|
454 function_name = symbol->function_name; |
|
455 |
|
456 identifier_c *param_name; |
534 identifier_c *param_name; |
457 function_call_param_iterator_c function_call_param_iterator(symbol); |
535 function_call_param_iterator_c function_call_param_iterator(symbol); |
458 for(int i = 1; (param_name = fp_iterator.next()) != NULL; i++) { |
536 for(int i = 1; (param_name = fp_iterator.next()) != NULL; i++) { |
459 |
537 |
460 function_param_iterator_c::param_direction_t param_direction = fp_iterator.param_direction(); |
538 function_param_iterator_c::param_direction_t param_direction = fp_iterator.param_direction(); |
473 } |
551 } |
474 |
552 |
475 symbol_c *param_type = fp_iterator.param_type(); |
553 symbol_c *param_type = fp_iterator.param_type(); |
476 if (param_type == NULL) ERROR; |
554 if (param_type == NULL) ERROR; |
477 |
555 |
478 ADD_PARAM_LIST(param_value, param_type, param_direction) |
556 ADD_PARAM_LIST(param_name, param_value, param_type, param_direction) |
479 } /* for(...) */ |
557 } /* for(...) */ |
480 // symbol->parameter_assignment->accept(*this); |
558 // symbol->parameter_assignment->accept(*this); |
481 } |
559 } |
482 |
560 |
|
561 bool has_output_params = false; |
|
562 |
|
563 if (!this->is_variable_prefix_null()) { |
|
564 PARAM_LIST_ITERATOR() { |
|
565 if ((PARAM_DIRECTION == function_param_iterator_c::direction_out || |
|
566 PARAM_DIRECTION == function_param_iterator_c::direction_inout) && |
|
567 PARAM_VALUE != NULL) { |
|
568 if (!has_output_params) { |
|
569 has_output_params = true; |
|
570 } |
|
571 } |
|
572 } |
|
573 } |
|
574 |
483 if (function_type_prefix != NULL) { |
575 if (function_type_prefix != NULL) { |
484 s4o.print("("); |
576 s4o.print("("); |
485 function_type_prefix->accept(*this); |
577 function_type_prefix->accept(*this); |
486 s4o.print(")"); |
578 s4o.print(")"); |
487 } |
579 } |
488 if (function_name != NULL) |
580 if (has_output_params) { |
|
581 fcall_number++; |
|
582 s4o.print("__"); |
|
583 fbname->accept(*this); |
|
584 s4o.print("_"); |
489 function_name->accept(*this); |
585 function_name->accept(*this); |
490 if (function_type_suffix != NULL) |
586 s4o.print_integer(fcall_number); |
491 function_type_suffix->accept(*this); |
587 } |
|
588 else { |
|
589 function_name->accept(*this); |
|
590 if (function_type_suffix != NULL) |
|
591 function_type_suffix->accept(*this); |
|
592 } |
492 s4o.print("("); |
593 s4o.print("("); |
493 s4o.indent_right(); |
594 s4o.indent_right(); |
494 |
595 |
495 std::list<FUNCTION_PARAM>::iterator pt; |
596 int nb_param = 0; |
496 for(pt = param_list.begin(); pt != param_list.end(); pt++) { |
597 PARAM_LIST_ITERATOR() { |
497 if (pt != param_list.begin()) |
598 symbol_c *param_value = PARAM_VALUE; |
498 s4o.print(",\n"+s4o.indent_spaces); |
599 symbol_c *param_type = PARAM_TYPE; |
499 symbol_c *param_value = pt->param_value; |
|
500 symbol_c *param_type = pt->param_type; |
|
501 |
600 |
502 switch (pt->param_direction) { |
601 switch (PARAM_DIRECTION) { |
503 case function_param_iterator_c::direction_in: |
602 case function_param_iterator_c::direction_in: |
504 if (param_value == NULL) { |
603 if (nb_param > 0) |
|
604 s4o.print(",\n"+s4o.indent_spaces); |
|
605 if (param_value == NULL) { |
505 /* If not, get the default value of this variable's type */ |
606 /* If not, get the default value of this variable's type */ |
506 param_value = (symbol_c *)param_type->accept(*type_initial_value_c::instance()); |
607 param_value = (symbol_c *)param_type->accept(*type_initial_value_c::instance()); |
507 } |
608 } |
508 if (param_value == NULL) ERROR; |
609 if (param_value == NULL) ERROR; |
509 s4o.print("("); |
610 s4o.print("("); |
513 function_type_suffix->accept(*this); |
614 function_type_suffix->accept(*this); |
514 } |
615 } |
515 else |
616 else |
516 param_type->accept(*this); |
617 param_type->accept(*this); |
517 s4o.print(")"); |
618 s4o.print(")"); |
518 if (search_base_type.type_is_subrange(param_type)) { |
619 print_check_function(param_type, param_value); |
519 s4o.print("__CHECK_"); |
620 nb_param++; |
520 param_type->accept(*this); |
|
521 s4o.print("("); |
|
522 } |
|
523 param_value->accept(*this); |
|
524 if (search_base_type.type_is_subrange(param_type)) |
|
525 s4o.print(")"); |
|
526 break; |
621 break; |
527 case function_param_iterator_c::direction_out: |
622 case function_param_iterator_c::direction_out: |
528 case function_param_iterator_c::direction_inout: |
623 case function_param_iterator_c::direction_inout: |
529 current_param_is_pointer = true; |
624 if (!has_output_params) { |
530 if (param_value == NULL) { |
625 if (nb_param > 0) |
531 s4o.print("NULL"); |
626 s4o.print(",\n"+s4o.indent_spaces); |
532 } else { |
627 if (param_value == NULL) |
533 param_value->accept(*this); |
628 s4o.print("NULL"); |
534 } |
629 else { |
535 current_param_is_pointer = false; |
630 wanted_variablegeneration = fparam_output_vg; |
|
631 param_value->accept(*this); |
|
632 wanted_variablegeneration = expression_vg; |
|
633 } |
|
634 nb_param++; |
|
635 } |
536 break; |
636 break; |
537 case function_param_iterator_c::direction_extref: |
637 case function_param_iterator_c::direction_extref: |
538 /* TODO! */ |
638 /* TODO! */ |
539 ERROR; |
639 ERROR; |
540 break; |
640 break; |
541 } /* switch */ |
641 } /* switch */ |
542 } |
642 } |
543 |
643 if (has_output_params) { |
|
644 if (nb_param > 0) |
|
645 s4o.print(",\n"+s4o.indent_spaces); |
|
646 s4o.print(FB_FUNCTION_PARAM); |
|
647 } |
544 s4o.print(")"); |
648 s4o.print(")"); |
545 s4o.indent_left(); |
649 s4o.indent_left(); |
|
650 |
|
651 CLEAR_PARAM_LIST() |
546 |
652 |
547 return NULL; |
653 return NULL; |
548 } |
654 } |
549 |
655 |
550 /********************/ |
656 /********************/ |
558 /* B 3.2.1 Assignment Statements */ |
664 /* B 3.2.1 Assignment Statements */ |
559 /*********************************/ |
665 /*********************************/ |
560 void *visit(assignment_statement_c *symbol) { |
666 void *visit(assignment_statement_c *symbol) { |
561 symbol_c *left_type = search_varfb_instance_type->get_type(symbol->l_exp, false); |
667 symbol_c *left_type = search_varfb_instance_type->get_type(symbol->l_exp, false); |
562 |
668 |
563 symbol->l_exp->accept(*this); |
669 if (!this->is_variable_prefix_null()) { |
564 s4o.print(" = "); |
670 unsigned int vartype = search_varfb_instance_type->get_vartype(symbol->l_exp); |
565 if (search_base_type.type_is_subrange(left_type)) { |
671 if (vartype == search_var_instance_decl_c::external_vt) |
566 s4o.print("__CHECK_"); |
672 s4o.print(SET_EXTERNAL); |
567 left_type->accept(*this); |
673 else if (vartype == search_var_instance_decl_c::located_vt) |
|
674 s4o.print(SET_LOCATED); |
|
675 else |
|
676 s4o.print(SET_VAR); |
568 s4o.print("("); |
677 s4o.print("("); |
569 } |
678 |
570 symbol->r_exp->accept(*this); |
679 wanted_variablegeneration = assignment_vg; |
571 if (search_base_type.type_is_subrange(left_type)) |
680 symbol->l_exp->accept(*this); |
|
681 wanted_variablegeneration = expression_vg; |
|
682 |
|
683 s4o.print(","); |
|
684 } |
|
685 else { |
|
686 symbol->l_exp->accept(*this); |
|
687 |
|
688 s4o.print(" = "); |
|
689 } |
|
690 print_check_function(left_type, symbol->r_exp); |
|
691 if (!this->is_variable_prefix_null()) |
572 s4o.print(")"); |
692 s4o.print(")"); |
573 return NULL; |
693 return NULL; |
574 } |
694 } |
575 |
695 |
576 /*****************************************/ |
696 /*****************************************/ |
615 |
735 |
616 /* now output the value assignment */ |
736 /* now output the value assignment */ |
617 if (param_value != NULL) |
737 if (param_value != NULL) |
618 if ((param_direction == function_param_iterator_c::direction_in) || |
738 if ((param_direction == function_param_iterator_c::direction_in) || |
619 (param_direction == function_param_iterator_c::direction_inout)) { |
739 (param_direction == function_param_iterator_c::direction_inout)) { |
620 print_variable_prefix(); |
740 if (!this->is_variable_prefix_null()) { |
|
741 s4o.print(SET_VAR); |
|
742 s4o.print("("); |
|
743 } |
|
744 print_variable_prefix(); |
621 symbol->fb_name->accept(*this); |
745 symbol->fb_name->accept(*this); |
622 s4o.print("."); |
746 s4o.print("."); |
623 param_name->accept(*this); |
747 param_name->accept(*this); |
624 s4o.print(" = "); |
748 if (this->is_variable_prefix_null()) |
625 if (search_base_type.type_is_subrange(param_type)) { |
749 s4o.print(" = "); |
626 s4o.print("__CHECK_"); |
750 else |
627 param_type->accept(*this); |
751 s4o.print(","); |
628 s4o.print("("); |
752 print_check_function(param_type, param_value); |
629 } |
753 if (!this->is_variable_prefix_null()) |
630 param_value->accept(*this); |
|
631 if (search_base_type.type_is_subrange(param_type)) |
|
632 s4o.print(")"); |
754 s4o.print(")"); |
633 s4o.print(";\n" + s4o.indent_spaces); |
755 s4o.print(";\n" + s4o.indent_spaces); |
634 } |
756 } |
635 } /* for(...) */ |
757 } /* for(...) */ |
636 |
758 |
660 /* now output the value assignment */ |
782 /* now output the value assignment */ |
661 if (param_value != NULL) |
783 if (param_value != NULL) |
662 if ((param_direction == function_param_iterator_c::direction_out) || |
784 if ((param_direction == function_param_iterator_c::direction_out) || |
663 (param_direction == function_param_iterator_c::direction_inout)) { |
785 (param_direction == function_param_iterator_c::direction_inout)) { |
664 symbol_c *param_type = search_varfb_instance_type->get_type(param_value, false); |
786 symbol_c *param_type = search_varfb_instance_type->get_type(param_value, false); |
665 |
787 |
666 s4o.print(";\n"+ s4o.indent_spaces); |
788 if (!this->is_variable_prefix_null()) { |
667 param_value->accept(*this); |
789 unsigned int vartype = search_varfb_instance_type->get_vartype(param_value); |
668 s4o.print(" = "); |
790 s4o.print(";\n"+ s4o.indent_spaces); |
669 if (search_base_type.type_is_subrange(param_type)) { |
791 if (vartype == search_var_instance_decl_c::external_vt) |
670 s4o.print("__CHECK_"); |
792 s4o.print(SET_EXTERNAL); |
671 param_type->accept(*this); |
793 else if (vartype == search_var_instance_decl_c::located_vt) |
|
794 s4o.print(SET_LOCATED); |
|
795 else |
|
796 s4o.print(SET_VAR); |
672 s4o.print("("); |
797 s4o.print("("); |
|
798 |
|
799 wanted_variablegeneration = assignment_vg; |
|
800 param_value->accept(*this); |
|
801 wanted_variablegeneration = expression_vg; |
|
802 s4o.print(","); |
673 } |
803 } |
674 print_variable_prefix(); |
804 else { |
675 symbol->fb_name->accept(*this); |
805 param_value->accept(*this); |
676 s4o.print("."); |
806 s4o.print(" = "); |
677 param_name->accept(*this); |
807 } |
678 if (search_base_type.type_is_subrange(param_type)) |
808 print_check_function(param_type, param_name, symbol->fb_name); |
|
809 if (!this->is_variable_prefix_null()) |
679 s4o.print(")"); |
810 s4o.print(")"); |
680 } |
811 } |
681 } /* for(...) */ |
812 } /* for(...) */ |
682 |
813 |
683 return NULL; |
814 return NULL; |