59 * parameter to the simple_instr_list_c visitor. |
59 * parameter to the simple_instr_list_c visitor. |
60 * Ergo, the existance of the following parameter...! |
60 * Ergo, the existance of the following parameter...! |
61 */ |
61 */ |
62 symbol_c *il_default_variable_init_value; |
62 symbol_c *il_default_variable_init_value; |
63 |
63 |
64 /* Operand to the IL operation currently being processed... */ |
|
65 /* These variables are used to pass data from the |
|
66 * il_simple_operation_c and il_expression_c visitors |
|
67 * to the il operator visitors (i.e. LD_operator_c, |
|
68 * LDN_operator_c, ST_operator_c, STN_operator_c, ...) |
|
69 */ |
|
70 symbol_c *current_operand; |
|
71 symbol_c *current_operand_type; |
|
72 |
|
73 /* The result of the comparison IL operations (GT, EQ, LT, ...) |
64 /* The result of the comparison IL operations (GT, EQ, LT, ...) |
74 * is a boolean variable. |
65 * is a boolean variable. |
75 * This class keeps track of the current data type stored in the |
66 * This class keeps track of the current data type stored in the |
76 * il default variable. This is usually done by keeping a reference |
67 * il default variable. This is usually done by keeping a reference |
77 * to the data type of the last operand. Nevertheless, in the case of |
68 * to the data type of the last operand. Nevertheless, in the case of |
111 variablegeneration_t wanted_variablegeneration; |
101 variablegeneration_t wanted_variablegeneration; |
112 |
102 |
113 public: |
103 public: |
114 generate_c_inlinefcall_c(stage4out_c *s4o_ptr, symbol_c *name, symbol_c *scope, const char *variable_prefix = NULL) |
104 generate_c_inlinefcall_c(stage4out_c *s4o_ptr, symbol_c *name, symbol_c *scope, const char *variable_prefix = NULL) |
115 : generate_c_typedecl_c(s4o_ptr), |
105 : generate_c_typedecl_c(s4o_ptr), |
116 default_variable_name(IL_DEFVAR, NULL), |
106 implicit_variable_current(IL_DEFVAR, NULL) |
117 default_variable_back_name(IL_DEFVAR_BACK, NULL) |
|
118 { |
107 { |
119 search_varfb_instance_type = new search_varfb_instance_type_c(scope); |
108 search_varfb_instance_type = new search_varfb_instance_type_c(scope); |
120 search_var_instance_decl = new search_var_instance_decl_c (scope); |
109 search_var_instance_decl = new search_var_instance_decl_c (scope); |
121 |
110 |
122 this->set_variable_prefix(variable_prefix); |
111 this->set_variable_prefix(variable_prefix); |
123 current_operand = NULL; |
|
124 current_operand_type = NULL; |
|
125 il_default_variable_init_value = NULL; |
112 il_default_variable_init_value = NULL; |
126 fcall_number = 0; |
113 fcall_number = 0; |
127 fbname = name; |
114 fbname = name; |
128 wanted_variablegeneration = expression_vg; |
115 wanted_variablegeneration = expression_vg; |
129 generating_inlinefunction = false; |
116 generating_inlinefunction = false; |
276 return &search_constant_type_c::lreal_type_name; |
263 return &search_constant_type_c::lreal_type_name; |
277 } |
264 } |
278 return symbol; |
265 return symbol; |
279 } |
266 } |
280 |
267 |
281 /* A helper function... */ |
268 |
282 void CMP_operator_result_type() { |
|
283 /* the data type resulting from this operation... */ |
|
284 this->default_variable_name.current_type = &(this->bool_type); |
|
285 } |
|
286 |
|
287 /* A helper function... */ |
|
288 void BYTE_operator_result_type(void) { |
|
289 if (get_datatype_info_c::is_ANY_INT_literal(this->default_variable_name.current_type)) { |
|
290 if (get_datatype_info_c::is_ANY_INT_literal(this->current_operand_type)) |
|
291 this->default_variable_name.current_type = &(this->lword_type); |
|
292 else |
|
293 this->default_variable_name.current_type = this->current_operand_type; |
|
294 } |
|
295 else if (get_datatype_info_c::is_ANY_INT_literal(this->current_operand_type)) |
|
296 this->current_operand_type = this->default_variable_name.current_type; |
|
297 } |
|
298 |
|
299 /* A helper function... */ |
|
300 void NUM_operator_result_type(void) { |
|
301 if (get_datatype_info_c::is_ANY_REAL_literal(this->default_variable_name.current_type)) { |
|
302 if (get_datatype_info_c::is_ANY_INT_literal(this->current_operand_type) || |
|
303 get_datatype_info_c::is_ANY_REAL_literal(this->current_operand_type)) |
|
304 this->default_variable_name.current_type = &(this->lreal_type); |
|
305 else |
|
306 this->default_variable_name.current_type = this->current_operand_type; |
|
307 } |
|
308 else if (get_datatype_info_c::is_ANY_INT_literal(this->default_variable_name.current_type)) { |
|
309 if (get_datatype_info_c::is_ANY_INT_literal(this->current_operand_type)) |
|
310 this->default_variable_name.current_type = &(this->lint_type); |
|
311 else if (get_datatype_info_c::is_ANY_REAL_literal(this->current_operand_type)) |
|
312 this->default_variable_name.current_type = &(this->lreal_type); |
|
313 else |
|
314 this->default_variable_name.current_type = this->current_operand_type; |
|
315 } |
|
316 else if (get_datatype_info_c::is_ANY_INT_literal(this->current_operand_type) || |
|
317 get_datatype_info_c::is_ANY_REAL_literal(this->current_operand_type)) |
|
318 this->current_operand_type = this->default_variable_name.current_type; |
|
319 } |
|
320 |
269 |
321 void *print_getter(symbol_c *symbol) { |
270 void *print_getter(symbol_c *symbol) { |
322 unsigned int vartype = search_var_instance_decl->get_vartype(symbol); |
271 unsigned int vartype = search_var_instance_decl->get_vartype(symbol); |
323 if (vartype == search_var_instance_decl_c::external_vt) |
272 if (vartype == search_var_instance_decl_c::external_vt) |
324 s4o.print(GET_EXTERNAL); |
273 s4o.print(GET_EXTERNAL); |
325 else if (vartype == search_var_instance_decl_c::located_vt) |
274 else if (vartype == search_var_instance_decl_c::located_vt) |
326 s4o.print(GET_LOCATED); |
275 s4o.print(GET_LOCATED); |
327 else |
276 else |
328 s4o.print(GET_VAR); |
277 s4o.print(GET_VAR); |
329 s4o.print("("); |
278 s4o.print("("); |
330 |
279 |
331 wanted_variablegeneration = complextype_base_vg; |
280 wanted_variablegeneration = complextype_base_vg; |
332 symbol->accept(*this); |
281 symbol->accept(*this); |
333 if (search_var_instance_decl->type_is_complex(symbol)) |
282 if (search_var_instance_decl->type_is_complex(symbol)) |
334 s4o.print(","); |
283 s4o.print(","); |
335 wanted_variablegeneration = complextype_suffix_vg; |
284 wanted_variablegeneration = complextype_suffix_vg; |
336 symbol->accept(*this); |
285 symbol->accept(*this); |
337 s4o.print(")"); |
286 s4o.print(")"); |
338 wanted_variablegeneration = expression_vg; |
287 wanted_variablegeneration = expression_vg; |
339 return NULL; |
288 return NULL; |
468 /***********************************/ |
417 /***********************************/ |
469 |
418 |
470 /* | label ':' [il_incomplete_instruction] eol_list */ |
419 /* | label ':' [il_incomplete_instruction] eol_list */ |
471 // SYM_REF2(il_instruction_c, label, il_instruction) |
420 // SYM_REF2(il_instruction_c, label, il_instruction) |
472 void *visit(il_instruction_c *symbol) { |
421 void *visit(il_instruction_c *symbol) { |
473 if (NULL != symbol->il_instruction) { |
422 /* all previous IL instructions should have the same datatype (checked in stage3), so we get the datatype from the first previous IL instruction we find */ |
474 symbol->il_instruction->accept(*this); |
423 implicit_variable_current.datatype = (symbol->prev_il_instruction.empty())? NULL : symbol->prev_il_instruction[0]->datatype; |
475 } |
424 if (NULL != symbol->il_instruction) symbol->il_instruction->accept(*this); |
476 return NULL; |
425 implicit_variable_current.datatype = NULL; |
477 } |
426 return NULL; |
|
427 } |
|
428 |
478 |
429 |
479 /* | il_simple_operator [il_operand] */ |
430 /* | il_simple_operator [il_operand] */ |
480 //SYM_REF2(il_simple_operation_c, il_simple_operator, il_operand) |
431 //SYM_REF2(il_simple_operation_c, il_simple_operator, il_operand) |
481 void *visit(il_simple_operation_c *symbol) { |
432 void *visit(il_simple_operation_c *symbol) { |
482 this->current_operand = symbol->il_operand; |
|
483 if (NULL == this->current_operand) { |
|
484 this->current_operand_type = NULL; |
|
485 } else { |
|
486 this->current_operand_type = this->current_operand->datatype; |
|
487 if (NULL == this->current_operand_type) ERROR; |
|
488 } |
|
489 |
|
490 symbol->il_simple_operator->accept(*this); |
433 symbol->il_simple_operator->accept(*this); |
491 |
434 return NULL; |
492 this->current_operand = NULL; |
435 } |
493 this->current_operand_type = NULL; |
436 |
494 return NULL; |
|
495 } |
|
496 |
437 |
497 void *visit(il_function_call_c *symbol) { |
438 void *visit(il_function_call_c *symbol) { |
498 symbol_c* function_type_prefix = NULL; |
439 symbol_c* function_type_prefix = NULL; |
499 symbol_c* function_name = NULL; |
440 symbol_c* function_name = NULL; |
500 symbol_c* function_type_suffix = NULL; |
441 symbol_c* function_type_suffix = NULL; |
501 DECLARE_PARAM_LIST() |
442 DECLARE_PARAM_LIST() |
502 |
|
503 symbol_c *param_data_type = default_variable_name.current_type; |
|
504 |
443 |
505 function_call_param_iterator_c function_call_param_iterator(symbol); |
444 function_call_param_iterator_c function_call_param_iterator(symbol); |
506 |
445 |
507 function_declaration_c *f_decl = (function_declaration_c *)symbol->called_function_declaration; |
446 function_declaration_c *f_decl = (function_declaration_c *)symbol->called_function_declaration; |
508 if (f_decl == NULL) ERROR; |
447 if (f_decl == NULL) ERROR; |
624 |
564 |
625 if (has_output_params) |
565 if (has_output_params) |
626 generate_inline(function_name, function_type_prefix, function_type_suffix, param_list, f_decl); |
566 generate_inline(function_name, function_type_prefix, function_type_suffix, param_list, f_decl); |
627 |
567 |
628 CLEAR_PARAM_LIST() |
568 CLEAR_PARAM_LIST() |
629 |
569 return NULL; |
630 /* the data type resulting from this operation... */ |
570 } |
631 default_variable_name.current_type = function_type_prefix; |
571 |
632 return NULL; |
572 |
633 } |
|
634 |
573 |
635 /* | il_expr_operator '(' [il_operand] eol_list [simple_instr_list] ')' */ |
574 /* | il_expr_operator '(' [il_operand] eol_list [simple_instr_list] ')' */ |
636 //SYM_REF4(il_expression_c, il_expr_operator, il_operand, simple_instr_list, unused) |
575 //SYM_REF4(il_expression_c, il_expr_operator, il_operand, simple_instr_list, unused) |
637 void *visit(il_expression_c *symbol) { |
576 void *visit(il_expression_c *symbol) { |
638 /* We will be recursevely interpreting an instruction list, |
577 /* We will be recursevely interpreting an instruction list, so we store a backup of the implicit_variable_result/current. |
639 * so we store a backup of the data type of the value currently stored |
578 * Notice that they will be overwriten while processing the parenthsized instruction list. |
640 * in the default variable, and set the current data type to NULL |
|
641 */ |
579 */ |
642 symbol_c *old_current_default_variable_data_type = this->default_variable_name.current_type; |
580 // il_default_variable_c old_implicit_variable_current = this->implicit_variable_current; // no longer needed! |
643 this->default_variable_name.current_type = NULL; |
581 |
644 |
582 |
645 /* Pass the symbol->il_operand to the simple_instr_list visitor |
583 /* Pass the symbol->il_operand to the simple_instr_list visitor |
646 * using the il_default_variable_init_value parameter... |
584 * using the il_default_variable_init_value parameter... |
647 * Note that the simple_instr_list_c visitor will set this parameter |
585 * Note that the simple_instr_list_c visitor will set this parameter |
648 * to NULL as soon as it does not require it any longer, |
586 * to NULL as soon as it does not require it any longer, |
651 * returns... |
589 * returns... |
652 */ |
590 */ |
653 this->il_default_variable_init_value = symbol->il_operand; |
591 this->il_default_variable_init_value = symbol->il_operand; |
654 |
592 |
655 /* Now do the parenthesised instructions... */ |
593 /* Now do the parenthesised instructions... */ |
656 /* NOTE: the following code line will get the variable |
594 /* NOTE: the following code line will get the variable this->implicit_variable_current.datatype updated! */ |
657 * this->default_variable_name.current_type updated! |
|
658 */ |
|
659 symbol->simple_instr_list->accept(*this); |
595 symbol->simple_instr_list->accept(*this); |
660 |
596 |
661 /* Now do the operation, using the previous result! */ |
597 /* Now do the operation, using the previous result! */ |
662 /* NOTE: The result of the previous instruction list will be stored |
598 /* NOTE: Actually, we do not need to call this, as it can never be a function call, which is what we are handling here... */ |
663 * in a variable named IL_DEFVAR_BACK. This is done in the visitor |
599 // this->implicit_variable_current.datatype = old_current_default_variable_data_type; |
664 * to instruction_list_c objects... |
600 // symbol->il_expr_operator->accept(*this); |
665 */ |
601 return NULL; |
666 this->current_operand = &(this->default_variable_back_name); |
602 } |
667 this->current_operand_type = this->default_variable_back_name.current_type; |
603 |
668 |
|
669 this->default_variable_name.current_type = old_current_default_variable_data_type; |
|
670 if (NULL == this->current_operand_type) ERROR; |
|
671 |
|
672 symbol->il_expr_operator->accept(*this); |
|
673 |
|
674 this->current_operand = NULL; |
|
675 this->current_operand_type = NULL; |
|
676 this->default_variable_back_name.current_type = NULL; |
|
677 return NULL; |
|
678 } |
|
679 |
604 |
680 /* | function_name '(' eol_list [il_param_list] ')' */ |
605 /* | function_name '(' eol_list [il_param_list] ')' */ |
681 // SYM_REF2(il_formal_funct_call_c, function_name, il_param_list) |
606 // SYM_REF2(il_formal_funct_call_c, function_name, il_param_list) |
682 void *visit(il_formal_funct_call_c *symbol) { |
607 void *visit(il_formal_funct_call_c *symbol) { |
683 symbol_c* function_type_prefix = NULL; |
608 symbol_c* function_type_prefix = NULL; |
805 |
730 |
806 if (has_output_params) |
731 if (has_output_params) |
807 generate_inline(function_name, function_type_prefix, function_type_suffix, param_list, f_decl); |
732 generate_inline(function_name, function_type_prefix, function_type_suffix, param_list, f_decl); |
808 |
733 |
809 CLEAR_PARAM_LIST() |
734 CLEAR_PARAM_LIST() |
810 |
735 return NULL; |
811 /* the data type resulting from this operation... */ |
736 } |
812 default_variable_name.current_type = function_type_prefix; |
737 |
813 return NULL; |
738 |
814 } |
|
815 |
739 |
816 /* | simple_instr_list il_simple_instruction */ |
740 /* | simple_instr_list il_simple_instruction */ |
817 // SYM_LIST(simple_instr_list_c) |
741 // SYM_LIST(simple_instr_list_c) |
818 void *visit(simple_instr_list_c *symbol) { |
742 void *visit(simple_instr_list_c *symbol) { |
819 /* Check whether we should initiliase the il default variable... */ |
743 /* Check whether we should initiliase the il default variable... */ |
820 if (NULL != this->il_default_variable_init_value) { |
744 // TODO: fix the way we handle this... It is currently not working!! |
821 /* Yes, we must... */ |
745 // if (NULL != this->il_default_variable_init_value) implicit_variable_current = il_default_variable_init_value; |
822 /* We will do it by instatiating a LD operator, and having this |
746 this->il_default_variable_init_value = NULL; // this parameter no longer required... |
823 * same generate_c_il_c class visiting it! |
|
824 */ |
|
825 LD_operator_c ld_oper; |
|
826 il_simple_operation_c il_simple_oper(&ld_oper, this->il_default_variable_init_value); |
|
827 |
|
828 il_simple_oper.accept(*this); |
|
829 } |
|
830 |
|
831 /* this parameter no longer required... */ |
|
832 this->il_default_variable_init_value = NULL; |
|
833 |
747 |
834 iterator_visitor_c::visit(symbol); |
748 iterator_visitor_c::visit(symbol); |
835 |
749 return NULL; |
836 /* copy the result in the default variable to the variable |
750 } |
837 * used to pass the data out to the scope enclosing |
751 |
838 * the current scope! |
752 |
839 * |
|
840 * We also need to update the data type currently stored within |
|
841 * the variable used to pass the data to the outside scope... |
|
842 */ |
|
843 this->default_variable_back_name.current_type = this->default_variable_name.current_type; |
|
844 return NULL; |
|
845 } |
|
846 |
|
847 // SYM_REF1(il_simple_instruction_c, il_simple_instruction, symbol_c *prev_il_instruction;) |
753 // SYM_REF1(il_simple_instruction_c, il_simple_instruction, symbol_c *prev_il_instruction;) |
848 void *visit(il_simple_instruction_c *symbol) { |
754 void *visit(il_simple_instruction_c *symbol) { |
849 return symbol->il_simple_instruction->accept(*this); |
755 return symbol->il_simple_instruction->accept(*this); |
850 } |
756 } |
851 |
757 |
852 void *visit(LD_operator_c *symbol) { |
758 |
853 /* the data type resulting from this operation... */ |
|
854 this->default_variable_name.current_type = this->current_operand_type; |
|
855 return NULL; |
|
856 } |
|
857 |
|
858 void *visit(LDN_operator_c *symbol) { |
|
859 /* the data type resulting from this operation... */ |
|
860 this->default_variable_name.current_type = this->current_operand_type; |
|
861 return NULL; |
|
862 } |
|
863 |
|
864 void *visit(AND_operator_c *symbol) { |
|
865 if (get_datatype_info_c::is_ANY_BIT_compatible(this->default_variable_name.current_type)) { |
|
866 BYTE_operator_result_type(); |
|
867 } |
|
868 else {ERROR;} |
|
869 return NULL; |
|
870 } |
|
871 |
|
872 void *visit(OR_operator_c *symbol) { |
|
873 if (get_datatype_info_c::is_ANY_BIT_compatible(this->default_variable_name.current_type)) { |
|
874 BYTE_operator_result_type(); |
|
875 } |
|
876 else {ERROR;} |
|
877 return NULL; |
|
878 } |
|
879 |
|
880 void *visit(XOR_operator_c *symbol) { |
|
881 if (get_datatype_info_c::is_ANY_BIT_compatible(this->default_variable_name.current_type)) { |
|
882 BYTE_operator_result_type(); |
|
883 } |
|
884 else {ERROR;} |
|
885 return NULL; |
|
886 } |
|
887 |
|
888 void *visit(ANDN_operator_c *symbol) { |
|
889 if (get_datatype_info_c::is_ANY_BIT_compatible(this->default_variable_name.current_type)) { |
|
890 BYTE_operator_result_type(); |
|
891 } |
|
892 else {ERROR;} |
|
893 return NULL; |
|
894 } |
|
895 |
|
896 void *visit(ORN_operator_c *symbol) { |
|
897 if (get_datatype_info_c::is_ANY_BIT_compatible(this->default_variable_name.current_type)) { |
|
898 BYTE_operator_result_type(); |
|
899 } |
|
900 else {ERROR;} |
|
901 return NULL; |
|
902 } |
|
903 |
|
904 void *visit(XORN_operator_c *symbol) { |
|
905 if (get_datatype_info_c::is_ANY_BIT_compatible(this->default_variable_name.current_type)) { |
|
906 BYTE_operator_result_type(); |
|
907 } |
|
908 else {ERROR;} |
|
909 return NULL; |
|
910 } |
|
911 |
|
912 void *visit(ADD_operator_c *symbol) { |
|
913 if (get_datatype_info_c::is_TIME_compatible (symbol->datatype) || |
|
914 get_datatype_info_c::is_ANY_DATE_compatible (symbol->datatype)) { |
|
915 /* the data type resulting from this operation... */ |
|
916 this->default_variable_name.current_type = this->current_operand_type; |
|
917 } else { |
|
918 NUM_operator_result_type(); |
|
919 } |
|
920 return NULL; |
|
921 } |
|
922 |
|
923 void *visit(SUB_operator_c *symbol) { |
|
924 if (get_datatype_info_c::is_TIME_compatible (symbol->datatype) || |
|
925 get_datatype_info_c::is_ANY_DATE_compatible (symbol->datatype)) { |
|
926 /* the data type resulting from this operation... */ |
|
927 this->default_variable_name.current_type = this->current_operand_type; |
|
928 } else { |
|
929 NUM_operator_result_type(); |
|
930 } |
|
931 return NULL; |
|
932 } |
|
933 |
|
934 void *visit(MUL_operator_c *symbol) { |
|
935 if (get_datatype_info_c::is_TIME_compatible (symbol->datatype)) { |
|
936 /* the data type resulting from this operation is unchanged! */ |
|
937 } else { |
|
938 NUM_operator_result_type(); |
|
939 } |
|
940 return NULL; |
|
941 } |
|
942 |
|
943 void *visit(DIV_operator_c *symbol) { |
|
944 if (get_datatype_info_c::is_TIME_compatible (symbol->datatype)) { |
|
945 /* the data type resulting from this operation is unchanged! */ |
|
946 } else { |
|
947 NUM_operator_result_type(); |
|
948 } |
|
949 return NULL; |
|
950 } |
|
951 |
|
952 void *visit(MOD_operator_c *symbol) { |
|
953 NUM_operator_result_type(); |
|
954 return NULL; |
|
955 } |
|
956 |
|
957 void *visit(GT_operator_c *symbol) {CMP_operator_result_type(); return NULL;} |
|
958 void *visit(GE_operator_c *symbol) {CMP_operator_result_type(); return NULL;} |
|
959 void *visit(EQ_operator_c *symbol) {CMP_operator_result_type(); return NULL;} |
|
960 void *visit(LT_operator_c *symbol) {CMP_operator_result_type(); return NULL;} |
|
961 void *visit(LE_operator_c *symbol) {CMP_operator_result_type(); return NULL;} |
|
962 void *visit(NE_operator_c *symbol) {CMP_operator_result_type(); return NULL;} |
|
963 |
759 |
964 /***************************************/ |
760 /***************************************/ |
965 /* B.3 - Language ST (Structured Text) */ |
761 /* B.3 - Language ST (Structured Text) */ |
966 /***************************************/ |
762 /***************************************/ |
967 /***********************/ |
763 /***********************/ |