35 complextype_suffix_vg |
35 complextype_suffix_vg |
36 } variablegeneration_t; |
36 } variablegeneration_t; |
37 |
37 |
38 private: |
38 private: |
39 |
39 |
|
40 /* The initial value that should be given to the IL default variable |
|
41 * imediately after a parenthesis is opened. |
|
42 * This variable is only used to pass data from the |
|
43 * il_expression_c visitor to the simple_instr_list_c visitor. |
|
44 * |
|
45 * e.g.: |
|
46 * LD var1 |
|
47 * AND ( var2 |
|
48 * OR var3 |
|
49 * ) |
|
50 * |
|
51 * In the above code sample, the line 'AND ( var2' constitutes |
|
52 * an il_expression_c, where var2 should be loaded into the |
|
53 * il default variable before continuing with the expression |
|
54 * inside the parenthesis. |
|
55 * Unfortunately, only the simple_instr_list_c may do the |
|
56 * initial laoding of the var2 bariable following the parenthesis, |
|
57 * so the il_expression_c visitor will have to pass 'var2' as a |
|
58 * parameter to the simple_instr_list_c visitor. |
|
59 * Ergo, the existance of the following parameter...! |
|
60 */ |
|
61 symbol_c *il_default_variable_init_value; |
|
62 |
|
63 /* Operand to the IL operation currently being processed... */ |
|
64 /* These variables are used to pass data from the |
|
65 * il_simple_operation_c and il_expression_c visitors |
|
66 * to the il operator visitors (i.e. LD_operator_c, |
|
67 * LDN_operator_c, ST_operator_c, STN_operator_c, ...) |
|
68 */ |
|
69 symbol_c *current_operand; |
|
70 symbol_c *current_operand_type; |
|
71 |
|
72 /* The result of the comparison IL operations (GT, EQ, LT, ...) |
|
73 * is a boolean variable. |
|
74 * This class keeps track of the current data type stored in the |
|
75 * il default variable. This is usually done by keeping a reference |
|
76 * to the data type of the last operand. Nevertheless, in the case of |
|
77 * the comparison IL operators, the data type of the result (a boolean) |
|
78 * is not the data type of the operand. We therefore need an object |
|
79 * of the boolean data type to keep as a reference of the current |
|
80 * data type. |
|
81 * The following object is it... |
|
82 */ |
|
83 bool_type_name_c bool_type; |
|
84 lint_type_name_c lint_type; |
|
85 lword_type_name_c lword_type; |
|
86 lreal_type_name_c lreal_type; |
|
87 |
40 /* The name of the IL default variable... */ |
88 /* The name of the IL default variable... */ |
41 #define IL_DEFVAR VAR_LEADER "IL_DEFVAR" |
89 #define IL_DEFVAR VAR_LEADER "IL_DEFVAR" |
|
90 |
42 /* The name of the variable used to pass the result of a |
91 /* The name of the variable used to pass the result of a |
43 * parenthesised instruction list to the immediately preceding |
92 * parenthesised instruction list to the immediately preceding |
44 * scope ... |
93 * scope ... |
45 */ |
94 */ |
46 il_default_variable_c default_variable_name; |
95 #define IL_DEFVAR_BACK VAR_LEADER "IL_DEFVAR_BACK" |
|
96 il_default_variable_c default_variable_name; |
|
97 il_default_variable_c default_variable_back_name; |
47 |
98 |
48 symbol_c* current_array_type; |
99 symbol_c* current_array_type; |
49 |
100 |
50 int fcall_number; |
101 int fcall_number; |
51 symbol_c *fbname; |
102 symbol_c *fbname; |
201 s4o.indent_left(); |
253 s4o.indent_left(); |
202 s4o.print(s4o.indent_spaces + "}\n\n"); |
254 s4o.print(s4o.indent_spaces + "}\n\n"); |
203 } |
255 } |
204 |
256 |
205 private: |
257 private: |
|
258 |
|
259 /* A helper function... */ |
|
260 void CMP_operator_result_type() { |
|
261 /* the data type resulting from this operation... */ |
|
262 this->default_variable_name.current_type = &(this->bool_type); |
|
263 } |
|
264 |
|
265 /* A helper function... */ |
|
266 void BYTE_operator_result_type(void) { |
|
267 if (search_expression_type->is_literal_integer_type(this->default_variable_name.current_type)) { |
|
268 if (search_expression_type->is_literal_integer_type(this->current_operand_type)) |
|
269 this->default_variable_name.current_type = &(this->lword_type); |
|
270 else |
|
271 this->default_variable_name.current_type = this->current_operand_type; |
|
272 } |
|
273 else if (search_expression_type->is_literal_integer_type(this->current_operand_type)) |
|
274 this->current_operand_type = this->default_variable_name.current_type; |
|
275 } |
|
276 |
|
277 /* A helper function... */ |
|
278 void NUM_operator_result_type(void) { |
|
279 if (search_expression_type->is_literal_real_type(this->default_variable_name.current_type)) { |
|
280 if (search_expression_type->is_literal_integer_type(this->current_operand_type) || |
|
281 search_expression_type->is_literal_real_type(this->current_operand_type)) |
|
282 this->default_variable_name.current_type = &(this->lreal_type); |
|
283 else |
|
284 this->default_variable_name.current_type = this->current_operand_type; |
|
285 } |
|
286 else if (search_expression_type->is_literal_integer_type(this->default_variable_name.current_type)) { |
|
287 if (search_expression_type->is_literal_integer_type(this->current_operand_type)) |
|
288 this->default_variable_name.current_type = &(this->lint_type); |
|
289 else if (search_expression_type->is_literal_real_type(this->current_operand_type)) |
|
290 this->default_variable_name.current_type = &(this->lreal_type); |
|
291 else |
|
292 this->default_variable_name.current_type = this->current_operand_type; |
|
293 } |
|
294 else if (search_expression_type->is_literal_integer_type(this->current_operand_type) || |
|
295 search_expression_type->is_literal_real_type(this->current_operand_type)) |
|
296 this->current_operand_type = this->default_variable_name.current_type; |
|
297 } |
206 |
298 |
207 void *print_getter(symbol_c *symbol) { |
299 void *print_getter(symbol_c *symbol) { |
208 unsigned int vartype = search_varfb_instance_type->get_vartype(symbol); |
300 unsigned int vartype = search_varfb_instance_type->get_vartype(symbol); |
209 if (vartype == search_var_instance_decl_c::external_vt) |
301 if (vartype == search_var_instance_decl_c::external_vt) |
210 s4o.print(GET_EXTERNAL); |
302 s4o.print(GET_EXTERNAL); |
349 /****************************************/ |
441 /****************************************/ |
350 |
442 |
351 /***********************************/ |
443 /***********************************/ |
352 /* B 2.1 Instructions and Operands */ |
444 /* B 2.1 Instructions and Operands */ |
353 /***********************************/ |
445 /***********************************/ |
|
446 |
|
447 /* | label ':' [il_incomplete_instruction] eol_list */ |
|
448 // SYM_REF2(il_instruction_c, label, il_instruction) |
|
449 void *visit(il_instruction_c *symbol) { |
|
450 if (NULL != symbol->il_instruction) { |
|
451 symbol->il_instruction->accept(*this); |
|
452 } |
|
453 return NULL; |
|
454 } |
|
455 /* | il_simple_operator [il_operand] */ |
|
456 //SYM_REF2(il_simple_operation_c, il_simple_operator, il_operand) |
|
457 void *visit(il_simple_operation_c *symbol) { |
|
458 this->current_operand = symbol->il_operand; |
|
459 if (NULL == this->current_operand) { |
|
460 this->current_operand_type = NULL; |
|
461 } else { |
|
462 this->current_operand_type = search_expression_type->get_type(this->current_operand); |
|
463 if (NULL == this->current_operand_type) ERROR; |
|
464 } |
|
465 |
|
466 symbol->il_simple_operator->accept(*this); |
|
467 |
|
468 this->current_operand = NULL; |
|
469 this->current_operand_type = NULL; |
|
470 return NULL; |
|
471 } |
354 |
472 |
355 void *visit(il_function_call_c *symbol) { |
473 void *visit(il_function_call_c *symbol) { |
356 symbol_c* function_type_prefix = NULL; |
474 symbol_c* function_type_prefix = NULL; |
357 symbol_c* function_name = NULL; |
475 symbol_c* function_name = NULL; |
358 symbol_c* function_type_suffix = NULL; |
476 symbol_c* function_type_suffix = NULL; |
483 if (has_output_params) |
601 if (has_output_params) |
484 generate_inline(function_name, function_type_prefix, function_type_suffix, param_list, f_decl); |
602 generate_inline(function_name, function_type_prefix, function_type_suffix, param_list, f_decl); |
485 |
603 |
486 CLEAR_PARAM_LIST() |
604 CLEAR_PARAM_LIST() |
487 |
605 |
|
606 /* the data type resulting from this operation... */ |
|
607 default_variable_name.current_type = function_type_prefix; |
|
608 return NULL; |
|
609 } |
|
610 |
|
611 /* | il_expr_operator '(' [il_operand] eol_list [simple_instr_list] ')' */ |
|
612 //SYM_REF4(il_expression_c, il_expr_operator, il_operand, simple_instr_list, unused) |
|
613 void *visit(il_expression_c *symbol) { |
|
614 /* We will be recursevely interpreting an instruction list, |
|
615 * so we store a backup of the data type of the value currently stored |
|
616 * in the default variable, and set the current data type to NULL |
|
617 */ |
|
618 symbol_c *old_current_default_variable_data_type = this->default_variable_name.current_type; |
|
619 this->default_variable_name.current_type = NULL; |
|
620 |
|
621 /* Pass the symbol->il_operand to the simple_instr_list visitor |
|
622 * using the il_default_variable_init_value parameter... |
|
623 * Note that the simple_instr_list_c visitor will set this parameter |
|
624 * to NULL as soon as it does not require it any longer, |
|
625 * so we don't do it here again after the |
|
626 * symbol->simple_instr_list->accept(*this); |
|
627 * returns... |
|
628 */ |
|
629 this->il_default_variable_init_value = symbol->il_operand; |
|
630 |
|
631 /* Now do the parenthesised instructions... */ |
|
632 /* NOTE: the following code line will get the variable |
|
633 * this->default_variable_name.current_type updated! |
|
634 */ |
|
635 symbol->simple_instr_list->accept(*this); |
|
636 |
|
637 /* Now do the operation, using the previous result! */ |
|
638 /* NOTE: The result of the previous instruction list will be stored |
|
639 * in a variable named IL_DEFVAR_BACK. This is done in the visitor |
|
640 * to instruction_list_c objects... |
|
641 */ |
|
642 this->current_operand = &(this->default_variable_back_name); |
|
643 this->current_operand_type = this->default_variable_back_name.current_type; |
|
644 |
|
645 this->default_variable_name.current_type = old_current_default_variable_data_type; |
|
646 if (NULL == this->current_operand_type) ERROR; |
|
647 |
|
648 symbol->il_expr_operator->accept(*this); |
|
649 |
|
650 this->current_operand = NULL; |
|
651 this->current_operand_type = NULL; |
|
652 this->default_variable_back_name.current_type = NULL; |
488 return NULL; |
653 return NULL; |
489 } |
654 } |
490 |
655 |
491 /* | function_name '(' eol_list [il_param_list] ')' */ |
656 /* | function_name '(' eol_list [il_param_list] ')' */ |
492 // SYM_REF2(il_formal_funct_call_c, function_name, il_param_list) |
657 // SYM_REF2(il_formal_funct_call_c, function_name, il_param_list) |
617 if (has_output_params) |
782 if (has_output_params) |
618 generate_inline(function_name, function_type_prefix, function_type_suffix, param_list, f_decl); |
783 generate_inline(function_name, function_type_prefix, function_type_suffix, param_list, f_decl); |
619 |
784 |
620 CLEAR_PARAM_LIST() |
785 CLEAR_PARAM_LIST() |
621 |
786 |
|
787 /* the data type resulting from this operation... */ |
|
788 default_variable_name.current_type = function_type_prefix; |
|
789 return NULL; |
|
790 } |
|
791 |
|
792 /* | simple_instr_list il_simple_instruction */ |
|
793 // SYM_LIST(simple_instr_list_c) |
|
794 void *visit(simple_instr_list_c *symbol) { |
|
795 /* Check whether we should initiliase the il default variable... */ |
|
796 if (NULL != this->il_default_variable_init_value) { |
|
797 /* Yes, we must... */ |
|
798 /* We will do it by instatiating a LD operator, and having this |
|
799 * same generate_c_il_c class visiting it! |
|
800 */ |
|
801 LD_operator_c ld_oper; |
|
802 il_simple_operation_c il_simple_oper(&ld_oper, this->il_default_variable_init_value); |
|
803 |
|
804 il_simple_oper.accept(*this); |
|
805 } |
|
806 |
|
807 /* this parameter no longer required... */ |
|
808 this->il_default_variable_init_value = NULL; |
|
809 |
|
810 iterator_visitor_c::visit(symbol); |
|
811 |
|
812 /* copy the result in the default variable to the variable |
|
813 * used to pass the data out to the scope enclosing |
|
814 * the current scope! |
|
815 * |
|
816 * We also need to update the data type currently stored within |
|
817 * the variable used to pass the data to the outside scope... |
|
818 */ |
|
819 this->default_variable_back_name.current_type = this->default_variable_name.current_type; |
|
820 return NULL; |
|
821 } |
|
822 |
|
823 void *visit(LD_operator_c *symbol) { |
|
824 /* the data type resulting from this operation... */ |
|
825 this->default_variable_name.current_type = this->current_operand_type; |
|
826 return NULL; |
|
827 } |
|
828 |
|
829 void *visit(LDN_operator_c *symbol) { |
|
830 /* the data type resulting from this operation... */ |
|
831 this->default_variable_name.current_type = this->current_operand_type; |
|
832 return NULL; |
|
833 } |
|
834 |
|
835 void *visit(AND_operator_c *symbol) { |
|
836 if (search_expression_type->is_binary_type(this->default_variable_name.current_type) && |
|
837 search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) { |
|
838 BYTE_operator_result_type(); |
|
839 } |
|
840 else {ERROR;} |
|
841 return NULL; |
|
842 } |
|
843 |
|
844 void *visit(OR_operator_c *symbol) { |
|
845 if (search_expression_type->is_binary_type(this->default_variable_name.current_type) && |
|
846 search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) { |
|
847 BYTE_operator_result_type(); |
|
848 } |
|
849 else {ERROR;} |
|
850 return NULL; |
|
851 } |
|
852 |
|
853 void *visit(XOR_operator_c *symbol) { |
|
854 if (search_expression_type->is_binary_type(this->default_variable_name.current_type) && |
|
855 search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) { |
|
856 BYTE_operator_result_type(); |
|
857 } |
|
858 else {ERROR;} |
|
859 return NULL; |
|
860 } |
|
861 |
|
862 void *visit(ANDN_operator_c *symbol) { |
|
863 if (search_expression_type->is_binary_type(this->default_variable_name.current_type) && |
|
864 search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) { |
|
865 BYTE_operator_result_type(); |
|
866 } |
|
867 else {ERROR;} |
|
868 return NULL; |
|
869 } |
|
870 |
|
871 void *visit(ORN_operator_c *symbol) { |
|
872 if (search_expression_type->is_binary_type(this->default_variable_name.current_type) && |
|
873 search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) { |
|
874 BYTE_operator_result_type(); |
|
875 } |
|
876 else {ERROR;} |
|
877 return NULL; |
|
878 } |
|
879 |
|
880 void *visit(XORN_operator_c *symbol) { |
|
881 if (search_expression_type->is_binary_type(this->default_variable_name.current_type) && |
|
882 search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) { |
|
883 BYTE_operator_result_type(); |
|
884 } |
|
885 else {ERROR;} |
|
886 return NULL; |
|
887 } |
|
888 |
|
889 void *visit(ADD_operator_c *symbol) { |
|
890 if (search_expression_type->is_time_type(this->default_variable_name.current_type) && |
|
891 search_expression_type->is_time_type(this->current_operand_type)) { |
|
892 /* the data type resulting from this operation... */ |
|
893 this->default_variable_name.current_type = this->current_operand_type; |
|
894 } |
|
895 else if (search_expression_type->is_num_type(this->default_variable_name.current_type) && |
|
896 search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) { |
|
897 NUM_operator_result_type(); |
|
898 } |
|
899 else {ERROR;} |
|
900 return NULL; |
|
901 } |
|
902 |
|
903 void *visit(SUB_operator_c *symbol) { |
|
904 if (search_expression_type->is_time_type(this->default_variable_name.current_type) && |
|
905 search_expression_type->is_time_type(this->current_operand_type)) { |
|
906 /* the data type resulting from this operation... */ |
|
907 this->default_variable_name.current_type = this->current_operand_type; |
|
908 } |
|
909 else if (search_expression_type->is_num_type(this->default_variable_name.current_type) && |
|
910 search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) { |
|
911 NUM_operator_result_type(); |
|
912 } |
|
913 else {ERROR;} |
|
914 return NULL; |
|
915 } |
|
916 |
|
917 void *visit(MUL_operator_c *symbol) { |
|
918 if (search_expression_type->is_time_type(this->default_variable_name.current_type) && |
|
919 search_expression_type->is_integer_type(this->current_operand_type)) { |
|
920 /* the data type resulting from this operation is unchanged! */ |
|
921 } |
|
922 else if (search_expression_type->is_num_type(this->default_variable_name.current_type) && |
|
923 search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) { |
|
924 NUM_operator_result_type(); |
|
925 } |
|
926 else {ERROR;} |
|
927 return NULL; |
|
928 } |
|
929 |
|
930 void *visit(DIV_operator_c *symbol) { |
|
931 if (search_expression_type->is_time_type(this->default_variable_name.current_type) && |
|
932 search_expression_type->is_integer_type(this->current_operand_type)) { |
|
933 /* the data type resulting from this operation is unchanged! */ |
|
934 } |
|
935 else if (search_expression_type->is_num_type(this->default_variable_name.current_type) && |
|
936 search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) { |
|
937 NUM_operator_result_type(); |
|
938 } |
|
939 else {ERROR;} |
|
940 return NULL; |
|
941 } |
|
942 |
|
943 void *visit(MOD_operator_c *symbol) { |
|
944 if (search_expression_type->is_num_type(this->default_variable_name.current_type) && |
|
945 search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) { |
|
946 NUM_operator_result_type(); |
|
947 } |
|
948 else {ERROR;} |
|
949 return NULL; |
|
950 } |
|
951 |
|
952 void *visit(GT_operator_c *symbol) { |
|
953 if (!search_base_type.type_is_enumerated(this->default_variable_name.current_type) && |
|
954 search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) { |
|
955 CMP_operator_result_type(); |
|
956 } |
|
957 else {ERROR;} |
|
958 return NULL; |
|
959 } |
|
960 |
|
961 void *visit(GE_operator_c *symbol) { |
|
962 if (!search_base_type.type_is_enumerated(this->default_variable_name.current_type) && |
|
963 search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) { |
|
964 CMP_operator_result_type(); |
|
965 } |
|
966 else {ERROR;} |
|
967 return NULL; |
|
968 } |
|
969 |
|
970 void *visit(EQ_operator_c *symbol) { |
|
971 if (search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) { |
|
972 CMP_operator_result_type(); |
|
973 } |
|
974 else {ERROR;} |
|
975 return NULL; |
|
976 } |
|
977 |
|
978 void *visit(LT_operator_c *symbol) { |
|
979 if (!search_base_type.type_is_enumerated(this->default_variable_name.current_type) && |
|
980 search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) { |
|
981 CMP_operator_result_type(); |
|
982 } |
|
983 else {ERROR;} |
|
984 return NULL; |
|
985 } |
|
986 |
|
987 void *visit(LE_operator_c *symbol) { |
|
988 if (!search_base_type.type_is_enumerated(this->default_variable_name.current_type) && |
|
989 search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) { |
|
990 CMP_operator_result_type(); |
|
991 } |
|
992 else {ERROR;} |
|
993 return NULL; |
|
994 } |
|
995 |
|
996 void *visit(NE_operator_c *symbol) { |
|
997 if (search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) { |
|
998 CMP_operator_result_type(); |
|
999 } |
|
1000 else {ERROR;} |
622 return NULL; |
1001 return NULL; |
623 } |
1002 } |
624 |
1003 |
625 /***************************************/ |
1004 /***************************************/ |
626 /* B.3 - Language ST (Structured Text) */ |
1005 /* B.3 - Language ST (Structured Text) */ |
627 /***************************************/ |
1006 /***************************************/ |
628 /***********************/ |
1007 /***********************/ |
629 /* B 3.1 - Expressions */ |
1008 /* B 3.1 - Expressions */ |
630 /***********************/ |
1009 /***********************/ |
|
1010 |
|
1011 void *visit(statement_list_c *symbol) { |
|
1012 function_call_iterator_c fc_iterator(symbol); |
|
1013 symbol_c* function_call; |
|
1014 while ((function_call = fc_iterator.next()) != NULL) { |
|
1015 function_call->accept(*this); |
|
1016 } |
|
1017 return NULL; |
|
1018 } |
631 |
1019 |
632 void *visit(function_invocation_c *symbol) { |
1020 void *visit(function_invocation_c *symbol) { |
633 symbol_c* function_type_prefix = NULL; |
1021 symbol_c* function_type_prefix = NULL; |
634 symbol_c* function_name = NULL; |
1022 symbol_c* function_name = NULL; |
635 symbol_c* function_type_suffix = NULL; |
1023 symbol_c* function_type_suffix = NULL; |