51 * |
51 * |
52 * The class constructor must be given the search scope |
52 * The class constructor must be given the search scope |
53 * (function, function block or program within which |
53 * (function, function block or program within which |
54 * the possible il_operand variable instance was declared). |
54 * the possible il_operand variable instance was declared). |
55 */ |
55 */ |
56 |
|
57 #include "../../absyntax_utils/search_il_operand_type.hh" |
|
58 |
|
59 |
|
60 |
56 |
61 /***********************************************************************/ |
57 /***********************************************************************/ |
62 /***********************************************************************/ |
58 /***********************************************************************/ |
63 /***********************************************************************/ |
59 /***********************************************************************/ |
64 /***********************************************************************/ |
60 /***********************************************************************/ |
150 * or function currently being processed. |
146 * or function currently being processed. |
151 * The following object does just that... |
147 * The following object does just that... |
152 * This object instance will then later be called while the |
148 * This object instance will then later be called while the |
153 * remaining il code is being handled. |
149 * remaining il code is being handled. |
154 */ |
150 */ |
155 //search_il_operand_type_c *search_il_operand_type; |
|
156 search_expression_type_c *search_expression_type; |
151 search_expression_type_c *search_expression_type; |
157 |
152 |
158 /* The initial value that should be given to the IL default variable |
153 /* The initial value that should be given to the IL default variable |
159 * imediately after a parenthesis is opened. |
154 * imediately after a parenthesis is opened. |
160 * This variable is only used to pass data from the |
155 * This variable is only used to pass data from the |
218 */ |
213 */ |
219 #define IL_DEFVAR_BACK VAR_LEADER "IL_DEFVAR_BACK" |
214 #define IL_DEFVAR_BACK VAR_LEADER "IL_DEFVAR_BACK" |
220 il_default_variable_c default_variable_name; |
215 il_default_variable_c default_variable_name; |
221 il_default_variable_c default_variable_back_name; |
216 il_default_variable_c default_variable_back_name; |
222 |
217 |
223 /* Some function calls in the body of functions or function blocks |
|
224 * may leave some parameters to their default values, and |
|
225 * ignore some output parameters of the function being called. |
|
226 * Our conversion of ST functions to C++ does not contemplate that, |
|
227 * i.e. each called function must get all it's input and output |
|
228 * parameters set correctly. |
|
229 * For input parameters we merely need to call the function with |
|
230 * the apropriate default value, but for output parameters |
|
231 * we must create temporary variables to hold the output value. |
|
232 * |
|
233 * We declare all the temporary output variables at the begining of |
|
234 * the body of each function or function block, and use them as |
|
235 * in function calls later on as they become necessary... |
|
236 * Note that we cannot create these variables just before a function |
|
237 * call, as the function call itself may be integrated within an |
|
238 * expression, or another function call! |
|
239 * |
|
240 * The variables are declared in the exact same order in which they |
|
241 * will be used later on during the function calls, which allows us |
|
242 * to simply re-create the name that was used for the temporary variable |
|
243 * instead of keeping it in some list. |
|
244 * The names are recreated by the temp_var_name_factory, after reset() |
|
245 * has been called! |
|
246 * |
|
247 * This function will genertae code similar to... |
|
248 * |
|
249 * INT __TMP_0 = 23; |
|
250 * REAL __TMP_1 = 45.5; |
|
251 * ... |
|
252 */ |
|
253 temp_var_name_c temp_var_name_factory; |
|
254 |
|
255 /* When calling a function block, we must first find it's type, |
218 /* When calling a function block, we must first find it's type, |
256 * by searching through the declarations of the variables currently |
219 * by searching through the declarations of the variables currently |
257 * in scope. |
220 * in scope. |
258 * This class does just that... |
221 * This class does just that... |
259 * A new class is instantiated whenever we begin generating the code |
222 * A new class is instantiated whenever we begin generating the code |
277 generate_c_il_c(stage4out_c *s4o_ptr, symbol_c *scope, const char *variable_prefix = NULL) |
240 generate_c_il_c(stage4out_c *s4o_ptr, symbol_c *scope, const char *variable_prefix = NULL) |
278 : generate_c_typedecl_c(s4o_ptr), |
241 : generate_c_typedecl_c(s4o_ptr), |
279 default_variable_name(IL_DEFVAR, NULL), |
242 default_variable_name(IL_DEFVAR, NULL), |
280 default_variable_back_name(IL_DEFVAR_BACK, NULL) |
243 default_variable_back_name(IL_DEFVAR_BACK, NULL) |
281 { |
244 { |
282 //search_il_operand_type = new search_il_operand_type_c(scope); |
|
283 search_expression_type = new search_expression_type_c(scope); |
245 search_expression_type = new search_expression_type_c(scope); |
284 search_fb_instance_decl = new search_fb_instance_decl_c(scope); |
246 search_fb_instance_decl = new search_fb_instance_decl_c(scope); |
285 search_varfb_instance_type = new search_varfb_instance_type_c(scope); |
247 search_varfb_instance_type = new search_varfb_instance_type_c(scope); |
286 current_operand = NULL; |
248 current_operand = NULL; |
287 current_operand_type = NULL; |
249 current_operand_type = NULL; |
290 this->set_variable_prefix(variable_prefix); |
252 this->set_variable_prefix(variable_prefix); |
291 } |
253 } |
292 |
254 |
293 virtual ~generate_c_il_c(void) { |
255 virtual ~generate_c_il_c(void) { |
294 delete search_fb_instance_decl; |
256 delete search_fb_instance_decl; |
295 //delete search_il_operand_type; |
|
296 delete search_expression_type; |
257 delete search_expression_type; |
297 delete search_varfb_instance_type; |
258 delete search_varfb_instance_type; |
298 } |
259 } |
299 |
260 |
300 void generate(instruction_list_c *il) { |
261 void generate(instruction_list_c *il) { |
301 generate_c_tempvardecl_c generate_c_tempvardecl(&s4o); |
|
302 generate_c_tempvardecl.generate(il, &temp_var_name_factory); |
|
303 il->accept(*this); |
262 il->accept(*this); |
304 } |
263 } |
305 |
264 |
306 /* Declare the backup to the default variable, that will store the result |
265 /* Declare the backup to the default variable, that will store the result |
307 * of the IL operations executed inside a parenthesis... |
266 * of the IL operations executed inside a parenthesis... |
358 if (NULL == fb_name) ERROR; |
317 if (NULL == fb_name) ERROR; |
359 symbolic_variable_c *sv = dynamic_cast<symbolic_variable_c *>(fb_name); |
318 symbolic_variable_c *sv = dynamic_cast<symbolic_variable_c *>(fb_name); |
360 if (NULL == sv) ERROR; |
319 if (NULL == sv) ERROR; |
361 identifier_c *id = dynamic_cast<identifier_c *>(sv->var_name); |
320 identifier_c *id = dynamic_cast<identifier_c *>(sv->var_name); |
362 if (NULL == id) ERROR; |
321 if (NULL == id) ERROR; |
363 |
322 |
364 identifier_c param(param_name); |
323 identifier_c param(param_name); |
365 |
324 |
366 //SYM_REF3(il_param_assignment_c, il_assign_operator, il_operand, simple_instr_list) |
325 //SYM_REF3(il_param_assignment_c, il_assign_operator, il_operand, simple_instr_list) |
367 il_param_assignment_c il_param_assignment(¶m, &this->default_variable_name, NULL); |
326 il_assign_operator_c il_assign_operator(¶m); |
|
327 il_param_assignment_c il_param_assignment(&il_assign_operator, &this->default_variable_name, NULL); |
368 // SYM_LIST(il_param_list_c) |
328 // SYM_LIST(il_param_list_c) |
369 il_param_list_c il_param_list; |
329 il_param_list_c il_param_list; |
370 il_param_list.add_element(&il_param_assignment); |
330 il_param_list.add_element(&il_param_assignment); |
371 CAL_operator_c CAL_operator; |
331 CAL_operator_c CAL_operator; |
372 // SYM_REF4(il_fb_call_c, il_call_operator, fb_name, il_operand_list, il_param_list) |
332 // SYM_REF4(il_fb_call_c, il_call_operator, fb_name, il_operand_list, il_param_list) |
373 il_fb_call_c il_fb_call(&CAL_operator, id, NULL, &il_param_list); |
333 il_fb_call_c il_fb_call(&CAL_operator, id, NULL, &il_param_list); |
374 |
334 |
435 } |
395 } |
436 |
396 |
437 |
397 |
438 private: |
398 private: |
439 |
399 |
|
400 #if 0 |
|
401 I NEED TO FIX THIS!!! |
|
402 TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO |
440 void *visit(eno_param_c *symbol) { |
403 void *visit(eno_param_c *symbol) { |
441 if (this->is_variable_prefix_null()) { |
404 if (this->is_variable_prefix_null()) { |
442 s4o.print("*"); |
405 s4o.print("*"); |
443 } |
406 } |
444 else { |
407 else { |
445 this->print_variable_prefix(); |
408 this->print_variable_prefix(); |
446 } |
409 } |
447 s4o.print("ENO"); |
410 s4o.print("ENO"); |
448 return NULL; |
411 return NULL; |
449 } |
412 } |
|
413 TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO |
|
414 #endif |
|
415 |
450 |
416 |
451 /*********************/ |
417 /*********************/ |
452 /* B 1.4 - Variables */ |
418 /* B 1.4 - Variables */ |
453 /*********************/ |
419 /*********************/ |
454 void *visit(symbolic_variable_c *symbol) { |
420 void *visit(symbolic_variable_c *symbol) { |
606 |
572 |
607 int nb_param = 1; |
573 int nb_param = 1; |
608 if (symbol->il_operand_list != NULL) |
574 if (symbol->il_operand_list != NULL) |
609 nb_param += ((list_c *)symbol->il_operand_list)->n; |
575 nb_param += ((list_c *)symbol->il_operand_list)->n; |
610 |
576 |
|
577 #define search(x) search_f(x) |
|
578 #define next() next_nf() |
|
579 // #define search_constant_type_c::constant_int_type_name search_expression_type_c::integer |
|
580 #define constant_int_type_name integer |
611 #include "il_code_gen.c" |
581 #include "il_code_gen.c" |
|
582 #undef constant_int_type_name |
|
583 // #undef search_constant_type_c::constant_int_type_name |
|
584 #undef next |
|
585 #undef search |
612 |
586 |
613 } |
587 } |
614 else { |
588 else { |
615 /* determine the base data type returned by the function being called... */ |
589 /* determine the base data type returned by the function being called... */ |
616 search_base_type_c search_base_type; |
590 search_base_type_c search_base_type; |
647 * We leave it in in case we later decide to merge this part of the code together |
621 * We leave it in in case we later decide to merge this part of the code together |
648 * with the function calling code in generate_c_st_c, which does require |
622 * with the function calling code in generate_c_st_c, which does require |
649 * the following line... |
623 * the following line... |
650 */ |
624 */ |
651 if (param_value == NULL) |
625 if (param_value == NULL) |
652 param_value = function_call_param_iterator.search(param_name); |
626 param_value = function_call_param_iterator.search_f(param_name); |
653 |
627 |
654 /* Get the value from a foo(<param_value>) style call */ |
628 /* Get the value from a foo(<param_value>) style call */ |
655 if (param_value == NULL) |
629 if (param_value == NULL) |
656 param_value = function_call_param_iterator.next(); |
630 param_value = function_call_param_iterator.next_nf(); |
657 |
631 |
658 if (param_value == NULL && param_direction == function_param_iterator_c::direction_in) { |
632 if (param_value == NULL && param_direction == function_param_iterator_c::direction_in) { |
659 /* No value given for parameter, so we must use the default... */ |
633 /* No value given for parameter, so we must use the default... */ |
660 /* First check whether default value specified in function declaration...*/ |
634 /* First check whether default value specified in function declaration...*/ |
661 param_value = fp_iterator.default_value(); |
635 param_value = fp_iterator.default_value(); |
818 function_call_param_iterator_c function_call_param_iterator(symbol); |
792 function_call_param_iterator_c function_call_param_iterator(symbol); |
819 for(int i = 1; (param_name = fp_iterator.next()) != NULL; i++) { |
793 for(int i = 1; (param_name = fp_iterator.next()) != NULL; i++) { |
820 function_param_iterator_c::param_direction_t param_direction = fp_iterator.param_direction(); |
794 function_param_iterator_c::param_direction_t param_direction = fp_iterator.param_direction(); |
821 |
795 |
822 /* Get the value from a foo(<param_name> = <param_value>) style call */ |
796 /* Get the value from a foo(<param_name> = <param_value>) style call */ |
823 symbol_c *param_value = function_call_param_iterator.search(param_name); |
797 symbol_c *param_value = function_call_param_iterator.search_f(param_name); |
824 |
798 |
825 /* Get the value from a foo(<param_value>) style call */ |
799 /* Get the value from a foo(<param_value>) style call */ |
826 if (param_value == NULL) |
800 if (param_value == NULL) |
827 param_value = function_call_param_iterator.next(); |
801 param_value = function_call_param_iterator.next_nf(); |
828 |
802 |
829 symbol_c *param_type = fp_iterator.param_type(); |
803 symbol_c *param_type = fp_iterator.param_type(); |
830 if (param_type == NULL) ERROR; |
804 if (param_type == NULL) ERROR; |
831 |
805 |
832 /* now output the value assignment */ |
806 /* now output the value assignment */ |
863 function_call_param_iterator.reset(); |
837 function_call_param_iterator.reset(); |
864 for(int i = 1; (param_name = fp_iterator.next()) != NULL; i++) { |
838 for(int i = 1; (param_name = fp_iterator.next()) != NULL; i++) { |
865 function_param_iterator_c::param_direction_t param_direction = fp_iterator.param_direction(); |
839 function_param_iterator_c::param_direction_t param_direction = fp_iterator.param_direction(); |
866 |
840 |
867 /* Get the value from a foo(<param_name> = <param_value>) style call */ |
841 /* Get the value from a foo(<param_name> = <param_value>) style call */ |
868 symbol_c *param_value = function_call_param_iterator.search(param_name); |
842 symbol_c *param_value = function_call_param_iterator.search_f(param_name); |
869 |
843 |
870 /* Get the value from a foo(<param_value>) style call */ |
844 /* Get the value from a foo(<param_value>) style call */ |
871 if (param_value == NULL) |
845 if (param_value == NULL) |
872 param_value = function_call_param_iterator.next(); |
846 param_value = function_call_param_iterator.next_nf(); |
873 |
847 |
874 /* now output the value assignment */ |
848 /* now output the value assignment */ |
875 if (param_value != NULL) |
849 if (param_value != NULL) |
876 if ((param_direction == function_param_iterator_c::direction_out) || |
850 if ((param_direction == function_param_iterator_c::direction_out) || |
877 (param_direction == function_param_iterator_c::direction_inout)) { |
851 (param_direction == function_param_iterator_c::direction_inout)) { |
878 symbol_c *param_type = search_varfb_instance_type->get_type(param_value, false); |
852 symbol_c *param_type = search_varfb_instance_type->get_type(param_value, false); |
879 |
853 |
880 s4o.print(";\n"+ s4o.indent_spaces); |
854 s4o.print(";\n"+ s4o.indent_spaces); |
881 param_value->accept(*this); |
855 param_value->accept(*this); |
882 s4o.print(" = "); |
856 s4o.print(" = "); |
883 if (search_base_type.type_is_subrange(param_type)) { |
857 if (search_base_type.type_is_subrange(param_type)) { |
884 s4o.print("__CHECK_"); |
858 s4o.print("__CHECK_"); |
929 if (symbol->il_param_list != NULL) |
903 if (symbol->il_param_list != NULL) |
930 nb_param += ((list_c *)symbol->il_param_list)->n; |
904 nb_param += ((list_c *)symbol->il_param_list)->n; |
931 |
905 |
932 identifier_c en_param_name("EN"); |
906 identifier_c en_param_name("EN"); |
933 /* Get the value from EN param */ |
907 /* Get the value from EN param */ |
934 symbol_c *EN_param_value = function_call_param_iterator.search(&en_param_name); |
908 symbol_c *EN_param_value = function_call_param_iterator.search_f(&en_param_name); |
935 if (EN_param_value == NULL) |
909 if (EN_param_value == NULL) |
936 EN_param_value = (symbol_c*)(new boolean_literal_c((symbol_c*)(new bool_type_name_c()), new boolean_true_c())); |
910 EN_param_value = (symbol_c*)(new boolean_literal_c((symbol_c*)(new bool_type_name_c()), new boolean_true_c())); |
937 else |
911 else |
938 nb_param --; |
912 nb_param --; |
939 ADD_PARAM_LIST(EN_param_value, (symbol_c*)(new bool_type_name_c()), function_param_iterator_c::direction_in) |
913 ADD_PARAM_LIST(EN_param_value, (symbol_c*)(new bool_type_name_c()), function_param_iterator_c::direction_in) |
940 |
914 |
941 identifier_c eno_param_name("EN0"); |
915 identifier_c eno_param_name("EN0"); |
942 /* Get the value from ENO param */ |
916 /* Get the value from ENO param */ |
943 symbol_c *ENO_param_value = function_call_param_iterator.search(&eno_param_name); |
917 symbol_c *ENO_param_value = function_call_param_iterator.search_f(&eno_param_name); |
944 if (ENO_param_value != NULL) |
918 if (ENO_param_value != NULL) |
945 nb_param --; |
919 nb_param --; |
946 ADD_PARAM_LIST(ENO_param_value, (symbol_c*)(new bool_type_name_c()), function_param_iterator_c::direction_out) |
920 ADD_PARAM_LIST(ENO_param_value, (symbol_c*)(new bool_type_name_c()), function_param_iterator_c::direction_out) |
947 |
921 |
|
922 #define search(x) search_f(x) |
|
923 #define next() next_nf() |
|
924 // #define search_constant_type_c::constant_int_type_name search_expression_type_c::integer |
|
925 #define constant_int_type_name integer |
948 #include "st_code_gen.c" |
926 #include "st_code_gen.c" |
|
927 #undef constant_int_type_name |
|
928 // #undef search_constant_type_c::constant_int_type_name |
|
929 #undef next |
|
930 #undef search |
949 |
931 |
950 } |
932 } |
951 else { |
933 else { |
952 /* determine the base data type returned by the function being called... */ |
934 /* determine the base data type returned by the function being called... */ |
953 search_base_type_c search_base_type; |
935 search_base_type_c search_base_type; |
972 |
954 |
973 symbol_c *param_value = NULL; |
955 symbol_c *param_value = NULL; |
974 |
956 |
975 /* Get the value from a foo(<param_name> = <param_value>) style call */ |
957 /* Get the value from a foo(<param_name> = <param_value>) style call */ |
976 if (param_value == NULL) |
958 if (param_value == NULL) |
977 param_value = function_call_param_iterator.search(param_name); |
959 param_value = function_call_param_iterator.search_f(param_name); |
978 |
960 |
979 /* Get the value from a foo(<param_value>) style call */ |
961 /* Get the value from a foo(<param_value>) style call */ |
980 /* NOTE: the following line of code is not required in this case, but it doesn't |
962 /* NOTE: the following line of code is not required in this case, but it doesn't |
981 * harm to leave it in, as in the case of a formal syntax function call, |
963 * harm to leave it in, as in the case of a formal syntax function call, |
982 * it will always return NULL. |
964 * it will always return NULL. |
983 * We leave it in in case we later decide to merge this part of the code together |
965 * We leave it in in case we later decide to merge this part of the code together |
984 * with the function calling code in generate_c_st_c, which does require |
966 * with the function calling code in generate_c_st_c, which does require |
985 * the following line... |
967 * the following line... |
986 */ |
968 */ |
987 if (param_value == NULL) |
969 if (param_value == NULL) |
988 param_value = function_call_param_iterator.next(); |
970 param_value = function_call_param_iterator.next_nf(); |
989 |
971 |
990 if (param_value == NULL) { |
972 if (param_value == NULL) { |
991 /* No value given for parameter, so we must use the default... */ |
973 /* No value given for parameter, so we must use the default... */ |
992 /* First check whether default value specified in function declaration...*/ |
974 /* First check whether default value specified in function declaration...*/ |
993 param_value = fp_iterator.default_value(); |
975 param_value = fp_iterator.default_value(); |