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; |
189 s4o.indent_left(); |
241 s4o.indent_left(); |
190 s4o.print(s4o.indent_spaces + "}\n\n"); |
242 s4o.print(s4o.indent_spaces + "}\n\n"); |
191 } |
243 } |
192 |
244 |
193 private: |
245 private: |
|
246 |
|
247 /* A helper function... */ |
|
248 void *CMP_operator_result_type() { |
|
249 /* the data type resulting from this operation... */ |
|
250 this->default_variable_name.current_type = &(this->bool_type); |
|
251 return NULL; |
|
252 } |
|
253 |
|
254 /* A helper function... */ |
|
255 void *BYTE_operator_result_type(void) { |
|
256 if (search_expression_type->is_literal_integer_type(this->default_variable_name.current_type)) { |
|
257 if (search_expression_type->is_literal_integer_type(this->current_operand_type)) |
|
258 this->default_variable_name.current_type = &(this->lword_type); |
|
259 else |
|
260 this->default_variable_name.current_type = this->current_operand_type; |
|
261 } |
|
262 else if (search_expression_type->is_literal_integer_type(this->current_operand_type)) |
|
263 this->current_operand_type = this->default_variable_name.current_type; |
|
264 return NULL; |
|
265 } |
|
266 |
|
267 /* A helper function... */ |
|
268 void *NUM_operator_result_type(void) { |
|
269 if (search_expression_type->is_literal_real_type(this->default_variable_name.current_type)) { |
|
270 if (search_expression_type->is_literal_integer_type(this->current_operand_type) || |
|
271 search_expression_type->is_literal_real_type(this->current_operand_type)) |
|
272 this->default_variable_name.current_type = &(this->lreal_type); |
|
273 else |
|
274 this->default_variable_name.current_type = this->current_operand_type; |
|
275 } |
|
276 else if (search_expression_type->is_literal_integer_type(this->default_variable_name.current_type)) { |
|
277 if (search_expression_type->is_literal_integer_type(this->current_operand_type)) |
|
278 this->default_variable_name.current_type = &(this->lint_type); |
|
279 else if (search_expression_type->is_literal_real_type(this->current_operand_type)) |
|
280 this->default_variable_name.current_type = &(this->lreal_type); |
|
281 else |
|
282 this->default_variable_name.current_type = this->current_operand_type; |
|
283 } |
|
284 else if (search_expression_type->is_literal_integer_type(this->current_operand_type) || |
|
285 search_expression_type->is_literal_real_type(this->current_operand_type)) |
|
286 this->current_operand_type = this->default_variable_name.current_type; |
|
287 return NULL; |
|
288 } |
194 |
289 |
195 void *print_getter(symbol_c *symbol) { |
290 void *print_getter(symbol_c *symbol) { |
196 unsigned int vartype = search_varfb_instance_type->get_vartype(symbol); |
291 unsigned int vartype = search_varfb_instance_type->get_vartype(symbol); |
197 if (vartype == search_var_instance_decl_c::external_vt) |
292 if (vartype == search_var_instance_decl_c::external_vt) |
198 s4o.print(GET_EXTERNAL); |
293 s4o.print(GET_EXTERNAL); |
338 |
433 |
339 /***********************************/ |
434 /***********************************/ |
340 /* B 2.1 Instructions and Operands */ |
435 /* B 2.1 Instructions and Operands */ |
341 /***********************************/ |
436 /***********************************/ |
342 |
437 |
|
438 /* | label ':' [il_incomplete_instruction] eol_list */ |
|
439 // SYM_REF2(il_instruction_c, label, il_instruction) |
|
440 void *visit(il_instruction_c *symbol) { |
|
441 if (NULL != symbol->il_instruction) { |
|
442 symbol->il_instruction->accept(*this); |
|
443 } |
|
444 return NULL; |
|
445 } |
|
446 /* | il_simple_operator [il_operand] */ |
|
447 //SYM_REF2(il_simple_operation_c, il_simple_operator, il_operand) |
|
448 void *visit(il_simple_operation_c *symbol) { |
|
449 this->current_operand = symbol->il_operand; |
|
450 if (NULL == this->current_operand) { |
|
451 this->current_operand_type = NULL; |
|
452 } else { |
|
453 this->current_operand_type = search_expression_type->get_type(this->current_operand); |
|
454 if (NULL == this->current_operand_type) ERROR; |
|
455 } |
|
456 |
|
457 symbol->il_simple_operator->accept(*this); |
|
458 |
|
459 this->current_operand = NULL; |
|
460 this->current_operand_type = NULL; |
|
461 return NULL; |
|
462 } |
|
463 |
343 void *visit(il_function_call_c *symbol) { |
464 void *visit(il_function_call_c *symbol) { |
344 symbol_c* function_type_prefix = NULL; |
465 symbol_c* function_type_prefix = NULL; |
345 symbol_c* function_name = NULL; |
466 symbol_c* function_name = NULL; |
346 symbol_c* function_type_suffix = NULL; |
467 symbol_c* function_type_suffix = NULL; |
347 DECLARE_PARAM_LIST() |
468 DECLARE_PARAM_LIST() |
445 if (has_output_params) |
566 if (has_output_params) |
446 generate_inline(function_name, function_type_prefix, function_type_suffix, param_list); |
567 generate_inline(function_name, function_type_prefix, function_type_suffix, param_list); |
447 |
568 |
448 CLEAR_PARAM_LIST() |
569 CLEAR_PARAM_LIST() |
449 |
570 |
|
571 /* the data type resulting from this operation... */ |
|
572 default_variable_name.current_type = function_type_prefix; |
|
573 return NULL; |
|
574 } |
|
575 |
|
576 /* | il_expr_operator '(' [il_operand] eol_list [simple_instr_list] ')' */ |
|
577 //SYM_REF4(il_expression_c, il_expr_operator, il_operand, simple_instr_list, unused) |
|
578 void *visit(il_expression_c *symbol) { |
|
579 /* We will be recursevely interpreting an instruction list, |
|
580 * so we store a backup of the data type of the value currently stored |
|
581 * in the default variable, and set the current data type to NULL |
|
582 */ |
|
583 symbol_c *old_current_default_variable_data_type = this->default_variable_name.current_type; |
|
584 this->default_variable_name.current_type = NULL; |
|
585 |
|
586 /* Pass the symbol->il_operand to the simple_instr_list visitor |
|
587 * using the il_default_variable_init_value parameter... |
|
588 * Note that the simple_instr_list_c visitor will set this parameter |
|
589 * to NULL as soon as it does not require it any longer, |
|
590 * so we don't do it here again after the |
|
591 * symbol->simple_instr_list->accept(*this); |
|
592 * returns... |
|
593 */ |
|
594 this->il_default_variable_init_value = symbol->il_operand; |
|
595 |
|
596 /* Now do the parenthesised instructions... */ |
|
597 /* NOTE: the following code line will get the variable |
|
598 * this->default_variable_name.current_type updated! |
|
599 */ |
|
600 symbol->simple_instr_list->accept(*this); |
|
601 |
|
602 /* Now do the operation, using the previous result! */ |
|
603 /* NOTE: The result of the previous instruction list will be stored |
|
604 * in a variable named IL_DEFVAR_BACK. This is done in the visitor |
|
605 * to instruction_list_c objects... |
|
606 */ |
|
607 this->current_operand = &(this->default_variable_back_name); |
|
608 this->current_operand_type = this->default_variable_back_name.current_type; |
|
609 |
|
610 this->default_variable_name.current_type = old_current_default_variable_data_type; |
|
611 if (NULL == this->current_operand_type) ERROR; |
|
612 |
|
613 symbol->il_expr_operator->accept(*this); |
|
614 |
|
615 this->current_operand = NULL; |
|
616 this->current_operand_type = NULL; |
|
617 this->default_variable_back_name.current_type = NULL; |
450 return NULL; |
618 return NULL; |
451 } |
619 } |
452 |
620 |
453 /* | function_name '(' eol_list [il_param_list] ')' */ |
621 /* | function_name '(' eol_list [il_param_list] ')' */ |
454 // SYM_REF2(il_formal_funct_call_c, function_name, il_param_list) |
622 // SYM_REF2(il_formal_funct_call_c, function_name, il_param_list) |
555 if (has_output_params) |
723 if (has_output_params) |
556 generate_inline(function_name, function_type_prefix, function_type_suffix, param_list); |
724 generate_inline(function_name, function_type_prefix, function_type_suffix, param_list); |
557 |
725 |
558 CLEAR_PARAM_LIST() |
726 CLEAR_PARAM_LIST() |
559 |
727 |
|
728 /* the data type resulting from this operation... */ |
|
729 default_variable_name.current_type = function_type_prefix; |
|
730 return NULL; |
|
731 } |
|
732 |
|
733 /* | simple_instr_list il_simple_instruction */ |
|
734 // SYM_LIST(simple_instr_list_c) |
|
735 void *visit(simple_instr_list_c *symbol) { |
|
736 /* Check whether we should initiliase the il default variable... */ |
|
737 if (NULL != this->il_default_variable_init_value) { |
|
738 /* Yes, we must... */ |
|
739 /* We will do it by instatiating a LD operator, and having this |
|
740 * same generate_c_il_c class visiting it! |
|
741 */ |
|
742 LD_operator_c ld_oper; |
|
743 il_simple_operation_c il_simple_oper(&ld_oper, this->il_default_variable_init_value); |
|
744 |
|
745 il_simple_oper.accept(*this); |
|
746 } |
|
747 |
|
748 /* this parameter no longer required... */ |
|
749 this->il_default_variable_init_value = NULL; |
|
750 |
|
751 iterator_visitor_c::visit(symbol); |
|
752 |
|
753 /* copy the result in the default variable to the variable |
|
754 * used to pass the data out to the scope enclosing |
|
755 * the current scope! |
|
756 * |
|
757 * We also need to update the data type currently stored within |
|
758 * the variable used to pass the data to the outside scope... |
|
759 */ |
|
760 this->default_variable_back_name.current_type = this->default_variable_name.current_type; |
|
761 return NULL; |
|
762 } |
|
763 |
|
764 void *visit(LD_operator_c *symbol) { |
|
765 /* the data type resulting from this operation... */ |
|
766 this->default_variable_name.current_type = this->current_operand_type; |
|
767 return NULL; |
|
768 } |
|
769 |
|
770 void *visit(LDN_operator_c *symbol) { |
|
771 /* the data type resulting from this operation... */ |
|
772 this->default_variable_name.current_type = this->current_operand_type; |
|
773 return NULL; |
|
774 } |
|
775 |
|
776 void *visit(ADD_operator_c *symbol) { |
|
777 if (search_expression_type->is_time_type(this->default_variable_name.current_type) && |
|
778 search_expression_type->is_time_type(this->current_operand_type)) { |
|
779 /* the data type resulting from this operation... */ |
|
780 this->default_variable_name.current_type = this->current_operand_type; |
|
781 return NULL; |
|
782 } |
|
783 if (search_expression_type->is_num_type(this->default_variable_name.current_type) && |
|
784 search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) { |
|
785 return NUM_operator_result_type(); |
|
786 } |
|
787 ERROR; |
|
788 return NULL; |
|
789 } |
|
790 |
|
791 void *visit(SUB_operator_c *symbol) { |
|
792 if (search_expression_type->is_time_type(this->default_variable_name.current_type) && |
|
793 search_expression_type->is_time_type(this->current_operand_type)) { |
|
794 /* the data type resulting from this operation... */ |
|
795 this->default_variable_name.current_type = this->current_operand_type; |
|
796 return NULL; |
|
797 } |
|
798 if (search_expression_type->is_num_type(this->default_variable_name.current_type) && |
|
799 search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) { |
|
800 return NUM_operator_result_type(); |
|
801 } |
|
802 ERROR; |
|
803 return NULL; |
|
804 } |
|
805 |
|
806 void *visit(MUL_operator_c *symbol) { |
|
807 if (search_expression_type->is_time_type(this->default_variable_name.current_type) && |
|
808 search_expression_type->is_integer_type(this->current_operand_type)) { |
|
809 return NULL; |
|
810 } |
|
811 if (search_expression_type->is_num_type(this->default_variable_name.current_type) && |
|
812 search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) { |
|
813 return NUM_operator_result_type(); |
|
814 } |
|
815 ERROR; |
|
816 return NULL; |
|
817 } |
|
818 |
|
819 void *visit(DIV_operator_c *symbol) { |
|
820 if (search_expression_type->is_time_type(this->default_variable_name.current_type) && |
|
821 search_expression_type->is_integer_type(this->current_operand_type)) { |
|
822 return NULL; |
|
823 } |
|
824 if (search_expression_type->is_num_type(this->default_variable_name.current_type) && |
|
825 search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) { |
|
826 return NUM_operator_result_type(); |
|
827 } |
|
828 ERROR; |
|
829 return NULL; |
|
830 } |
|
831 |
|
832 void *visit(MOD_operator_c *symbol) { |
|
833 if (search_expression_type->is_num_type(this->default_variable_name.current_type) && |
|
834 search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) { |
|
835 return NUM_operator_result_type(); |
|
836 } |
|
837 ERROR; |
|
838 return NULL; |
|
839 } |
|
840 |
|
841 void *visit(GT_operator_c *symbol) { |
|
842 if (!search_base_type.type_is_enumerated(this->default_variable_name.current_type) && |
|
843 search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) |
|
844 return CMP_operator_result_type(); |
|
845 ERROR; |
|
846 return NULL; |
|
847 } |
|
848 |
|
849 void *visit(GE_operator_c *symbol) { |
|
850 if (!search_base_type.type_is_enumerated(this->default_variable_name.current_type) && |
|
851 search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) |
|
852 return CMP_operator_result_type(); |
|
853 ERROR; |
|
854 return NULL; |
|
855 } |
|
856 |
|
857 void *visit(EQ_operator_c *symbol) { |
|
858 if (search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) |
|
859 return CMP_operator_result_type(); |
|
860 ERROR; |
|
861 return NULL; |
|
862 } |
|
863 |
|
864 void *visit(LT_operator_c *symbol) { |
|
865 if (!search_base_type.type_is_enumerated(this->default_variable_name.current_type) && |
|
866 search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) |
|
867 return CMP_operator_result_type(); |
|
868 return NULL; |
|
869 } |
|
870 |
|
871 void *visit(LE_operator_c *symbol) { |
|
872 if (!search_base_type.type_is_enumerated(this->default_variable_name.current_type) && |
|
873 search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) |
|
874 return CMP_operator_result_type(); |
|
875 ERROR; |
|
876 return NULL; |
|
877 } |
|
878 |
|
879 void *visit(NE_operator_c *symbol) { |
|
880 if (search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) |
|
881 return CMP_operator_result_type(); |
|
882 ERROR; |
560 return NULL; |
883 return NULL; |
561 } |
884 } |
562 |
885 |
563 /***************************************/ |
886 /***************************************/ |
564 /* B.3 - Language ST (Structured Text) */ |
887 /* B.3 - Language ST (Structured Text) */ |
565 /***************************************/ |
888 /***************************************/ |
566 /***********************/ |
889 /***********************/ |
567 /* B 3.1 - Expressions */ |
890 /* B 3.1 - Expressions */ |
568 /***********************/ |
891 /***********************/ |
|
892 |
|
893 void *visit(statement_list_c *symbol) { |
|
894 function_call_iterator_c fc_iterator(symbol); |
|
895 symbol_c* function_call; |
|
896 while ((function_call = fc_iterator.next()) != NULL) { |
|
897 function_call->accept(*this); |
|
898 } |
|
899 return NULL; |
|
900 } |
569 |
901 |
570 void *visit(function_invocation_c *symbol) { |
902 void *visit(function_invocation_c *symbol) { |
571 symbol_c* function_type_prefix = NULL; |
903 symbol_c* function_type_prefix = NULL; |
572 symbol_c* function_name = NULL; |
904 symbol_c* function_name = NULL; |
573 symbol_c* function_type_suffix = NULL; |
905 symbol_c* function_type_suffix = NULL; |