796 /* B 1.3 - Data types */ |
796 /* B 1.3 - Data types */ |
797 /**********************/ |
797 /**********************/ |
798 /********************************/ |
798 /********************************/ |
799 /* B 1.3.3 - Derived data types */ |
799 /* B 1.3.3 - Derived data types */ |
800 /********************************/ |
800 /********************************/ |
|
801 |
|
802 void *fill_candidate_datatypes_c::fill_type_decl(symbol_c *symbol, symbol_c *type_name, symbol_c *spec_init) { |
|
803 /* NOTE: Unlike the rest of the 'fill' algorithm that works using a bottom->up approach, when handling |
|
804 * data type declarations (section B.1.3.3 - Derived data types) we use a top->bottom approach. |
|
805 * This is intentional, and not a bug! Explanation follows... |
|
806 * Here we are essentially determining the base type of each defined data type. In many cases (especially structs, |
|
807 * enumerations, arrays, etc...), the datatype is its own base type. However, the derived datatype is stored in |
|
808 * multiple symbol_c classes (e.g. an enumeration uses enumerated_type_declaration_c, enumerated_spec_init_c, |
|
809 * enumerated_value_list_c, enumerated_value_c, ...). Several of these could be chosen to work as the canonical base datatype |
|
810 * symbol. Which symbol is used is really up to the search_base_type_c, and not this fill_candidate_datatypes_c. |
|
811 * Here we must right the code to handle whatever the search_base_type_c chooses to use as the canonical symbol to represent |
|
812 * the base datatype. |
|
813 * Since the base datatype may be (and sometimes/often/always(?) actually is) the top level symbol_c (an enumerated_type_declaration_c |
|
814 * in the case of the enumerations), it only makes sense to ask search_base_type_c for a basetype when we pass it the |
|
815 * symbol in the highest level of the type declaration (the enumerated_type_declaration_c in the case of the enumerations). |
|
816 * For this reason, we determine the basetype at the top level, and send that info down to the bottom level of the data type |
|
817 * declaration. In summary, a top->down algorithm! |
|
818 */ |
|
819 add_datatype_to_candidate_list(symbol, base_type(symbol)); |
|
820 type_name->candidate_datatypes = symbol->candidate_datatypes; // use top->down algorithm!! |
|
821 spec_init->candidate_datatypes = symbol->candidate_datatypes; // use top->down algorithm!! |
|
822 spec_init->accept(*this); |
|
823 return NULL; |
|
824 } |
|
825 |
|
826 |
|
827 void *fill_candidate_datatypes_c::fill_spec_init(symbol_c *symbol, symbol_c *type_spec, symbol_c *init_value) { |
|
828 /* NOTE: The note in the fill_type_decl() function is also partially valid here, |
|
829 * i.e. here too we work using a top->down algorithm for the type_spec part, but a bottom->up algorithm |
|
830 * for the init_value part!! |
|
831 */ |
|
832 /* NOTE: When a variable is declared inside a POU as, for example |
|
833 * VAR |
|
834 * a : ARRAY[9] OF REAL; |
|
835 * e : ENUM (black, white, gray); |
|
836 * s : STRUCT x, y: REAL; END_STRUCT |
|
837 * END_VAR |
|
838 * the anonymous datatype will be defined directly by the ***_spec_init_c, and will not have an |
|
839 * ****_type_declaration_c. In these cases, the anonymous data type is its own basetype, and the |
|
840 * ***_spec_init_c class will act as the canonical symbol that represents the (anonymous) basetype. |
|
841 * |
|
842 * This method must handle the above case, as well as the case in which the ***_spec_init_c is called |
|
843 * from an ****_type_declaration_c. |
|
844 */ |
|
845 if (symbol->candidate_datatypes.size() == 0) // i.e., if this is an anonymous datatype! |
|
846 add_datatype_to_candidate_list(symbol, base_type(symbol)); |
|
847 |
|
848 // use top->down algorithm!! |
|
849 type_spec->candidate_datatypes = symbol->candidate_datatypes; |
|
850 type_spec->accept(*this); |
|
851 |
|
852 // use bottom->up algorithm!! |
|
853 if (NULL != init_value) init_value->accept(*this); |
|
854 /* NOTE: Even if the constant and the type are of incompatible data types, we let the |
|
855 * ***_spec_init_c object inherit the data type of the type declaration (simple_specification) |
|
856 * This will let us produce more informative error messages when checking data type compatibility |
|
857 * with located variables (AT %QW3.4 : WORD). |
|
858 */ |
|
859 // if (NULL != init_value) intersect_candidate_datatype_list(symbol /*origin, dest.*/, init_value /*with*/); |
|
860 return NULL; |
|
861 } |
|
862 |
|
863 |
801 /* TYPE type_declaration_list END_TYPE */ |
864 /* TYPE type_declaration_list END_TYPE */ |
802 // SYM_REF1(data_type_declaration_c, type_declaration_list) |
865 // SYM_REF1(data_type_declaration_c, type_declaration_list) |
803 /* NOTE: Not required. already handled by iterator_visitor_c base class */ |
866 /* NOTE: Not required. already handled by iterator_visitor_c base class */ |
804 |
867 |
805 /* helper symbol for data_type_declaration */ |
868 /* helper symbol for data_type_declaration */ |
806 // SYM_LIST(type_declaration_list_c) |
869 // SYM_LIST(type_declaration_list_c) |
807 /* NOTE: Not required. already handled by iterator_visitor_c base class */ |
870 /* NOTE: Not required. already handled by iterator_visitor_c base class */ |
808 |
871 |
809 /* simple_type_name ':' simple_spec_init */ |
872 /* simple_type_name ':' simple_spec_init */ |
810 // SYM_REF2(simple_type_declaration_c, simple_type_name, simple_spec_init) |
873 // SYM_REF2(simple_type_declaration_c, simple_type_name, simple_spec_init) |
811 /* NOTE: Not required. already handled by iterator_visitor_c base class */ |
874 void *fill_candidate_datatypes_c::visit(simple_type_declaration_c *symbol) {return fill_type_decl(symbol, symbol->simple_type_name, symbol->simple_spec_init);} |
|
875 |
812 |
876 |
813 /* simple_specification ASSIGN constant */ |
877 /* simple_specification ASSIGN constant */ |
814 // SYM_REF2(simple_spec_init_c, simple_specification, constant) |
878 // SYM_REF2(simple_spec_init_c, simple_specification, constant) |
815 void *fill_candidate_datatypes_c::visit(simple_spec_init_c *symbol) { |
879 void *fill_candidate_datatypes_c::visit(simple_spec_init_c *symbol) {return fill_spec_init(symbol, symbol->simple_specification, symbol->constant);} |
816 if (NULL != symbol->constant) symbol->constant->accept(*this); |
|
817 add_datatype_to_candidate_list(symbol->simple_specification, base_type(symbol->simple_specification)); |
|
818 symbol->candidate_datatypes = symbol->simple_specification->candidate_datatypes; |
|
819 /* NOTE: Even if the constant and the type are of incompatible data types, we let the |
|
820 * simple_spec_init_c object inherit the data type of the type declaration (simple_specification) |
|
821 * This will let us produce more informative error messages when checking data type compatibility |
|
822 * with located variables (AT %QW3.4 : WORD). |
|
823 */ |
|
824 // if (NULL != symbol->constant) intersect_candidate_datatype_list(symbol /*origin, dest.*/, symbol->constant /*with*/); |
|
825 return NULL; |
|
826 } |
|
827 |
880 |
828 |
881 |
829 /* subrange_type_name ':' subrange_spec_init */ |
882 /* subrange_type_name ':' subrange_spec_init */ |
830 // SYM_REF2(subrange_type_declaration_c, subrange_type_name, subrange_spec_init) |
883 // SYM_REF2(subrange_type_declaration_c, subrange_type_name, subrange_spec_init) |
|
884 void *fill_candidate_datatypes_c::visit(subrange_type_declaration_c *symbol) {return fill_type_decl(symbol, symbol->subrange_type_name, symbol->subrange_spec_init);} |
831 |
885 |
832 /* subrange_specification ASSIGN signed_integer */ |
886 /* subrange_specification ASSIGN signed_integer */ |
833 // SYM_REF2(subrange_spec_init_c, subrange_specification, signed_integer) |
887 // SYM_REF2(subrange_spec_init_c, subrange_specification, signed_integer) |
|
888 void *fill_candidate_datatypes_c::visit(subrange_spec_init_c *symbol) {return fill_spec_init(symbol, symbol->subrange_specification, symbol->signed_integer);} |
834 |
889 |
835 /* integer_type_name '(' subrange')' */ |
890 /* integer_type_name '(' subrange')' */ |
836 // SYM_REF2(subrange_specification_c, integer_type_name, subrange) |
891 // SYM_REF2(subrange_specification_c, integer_type_name, subrange) |
|
892 // NOTE: not needed! Iterator visitor already handles this! |
837 |
893 |
838 /* signed_integer DOTDOT signed_integer */ |
894 /* signed_integer DOTDOT signed_integer */ |
839 /* dimension will be filled in during stage 3 (array_range_check_c) with the number of elements in this subrange */ |
895 /* dimension will be filled in during stage 3 (array_range_check_c) with the number of elements in this subrange */ |
840 // SYM_REF2(subrange_c, lower_limit, upper_limit, unsigned long long int dimension;) |
896 // SYM_REF2(subrange_c, lower_limit, upper_limit, unsigned long long int dimension;) |
841 void *fill_candidate_datatypes_c::visit(subrange_c *symbol) { |
897 void *fill_candidate_datatypes_c::visit(subrange_c *symbol) { |
852 } |
908 } |
853 |
909 |
854 |
910 |
855 /* enumerated_type_name ':' enumerated_spec_init */ |
911 /* enumerated_type_name ':' enumerated_spec_init */ |
856 // SYM_REF2(enumerated_type_declaration_c, enumerated_type_name, enumerated_spec_init) |
912 // SYM_REF2(enumerated_type_declaration_c, enumerated_type_name, enumerated_spec_init) |
857 void *fill_candidate_datatypes_c::visit(enumerated_type_declaration_c *symbol) { |
913 void *fill_candidate_datatypes_c::visit(enumerated_type_declaration_c *symbol) {return fill_type_decl(symbol, symbol->enumerated_type_name, symbol->enumerated_spec_init);} |
858 current_enumerated_spec_type = base_type(symbol); |
|
859 add_datatype_to_candidate_list(symbol, current_enumerated_spec_type); |
|
860 add_datatype_to_candidate_list(symbol->enumerated_type_name, current_enumerated_spec_type); |
|
861 symbol->enumerated_spec_init->accept(*this); |
|
862 current_enumerated_spec_type = NULL; |
|
863 return NULL; |
|
864 } |
|
865 |
914 |
866 |
915 |
867 /* enumerated_specification ASSIGN enumerated_value */ |
916 /* enumerated_specification ASSIGN enumerated_value */ |
868 // SYM_REF2(enumerated_spec_init_c, enumerated_specification, enumerated_value) |
917 // SYM_REF2(enumerated_spec_init_c, enumerated_specification, enumerated_value) |
869 void *fill_candidate_datatypes_c::visit(enumerated_spec_init_c *symbol) { |
918 // NOTE: enumerated_specification is either an enumerated_value_list_c or identifier_c. |
870 /* If we are handling an anonymous datatype (i.e. a datatype implicitly declared inside a VAR ... END_VAR declaration) |
919 void *fill_candidate_datatypes_c::visit(enumerated_spec_init_c *symbol) {return fill_spec_init(symbol, symbol->enumerated_specification, symbol->enumerated_value);} |
871 * then the symbol->datatype has not yet been set by the previous visit(enumerated_spec_init_c) method! |
920 |
872 */ |
|
873 if (NULL == current_enumerated_spec_type) |
|
874 current_enumerated_spec_type = base_type(symbol); |
|
875 add_datatype_to_candidate_list(symbol, current_enumerated_spec_type); |
|
876 symbol->enumerated_specification->accept(*this); /* calls enumerated_value_list_c (or identifier_c, which we ignore!) visit method */ |
|
877 current_enumerated_spec_type = NULL; |
|
878 if (NULL != symbol->enumerated_value) symbol->enumerated_value->accept(*this); |
|
879 return NULL; |
|
880 } |
|
881 |
921 |
882 /* helper symbol for enumerated_specification->enumerated_spec_init */ |
922 /* helper symbol for enumerated_specification->enumerated_spec_init */ |
883 /* enumerated_value_list ',' enumerated_value */ |
923 /* enumerated_value_list ',' enumerated_value */ |
884 // SYM_LIST(enumerated_value_list_c) |
924 // SYM_LIST(enumerated_value_list_c) |
885 void *fill_candidate_datatypes_c::visit(enumerated_value_list_c *symbol) { |
925 void *fill_candidate_datatypes_c::visit(enumerated_value_list_c *symbol) { |
886 if (NULL == current_enumerated_spec_type) ERROR; |
926 if (symbol->candidate_datatypes.size() != 1) ERROR; |
887 add_datatype_to_candidate_list(symbol, current_enumerated_spec_type); |
927 symbol_c *current_enumerated_spec_type = symbol->candidate_datatypes[0]; |
888 |
928 |
889 /* We already know the datatype of the enumerated_value(s) in the list, so we set them directly instead of recursively calling the enumerated_value_c visit method! */ |
929 /* We already know the datatype of the enumerated_value(s) in the list, so we set them directly instead of recursively calling the enumerated_value_c visit method! */ |
890 for(int i = 0; i < symbol->n; i++) |
930 for(int i = 0; i < symbol->n; i++) |
891 add_datatype_to_candidate_list(symbol->elements[i], current_enumerated_spec_type); |
931 add_datatype_to_candidate_list(symbol->elements[i], current_enumerated_spec_type); // top->down algorithm!! |
892 |
932 |
893 return NULL; |
933 return NULL; |
894 } |
934 } |
895 |
935 |
896 |
936 |
990 /* array_initial_element may be NULL ! */ |
1032 /* array_initial_element may be NULL ! */ |
991 // SYM_REF2(array_initial_elements_c, integer, array_initial_element) |
1033 // SYM_REF2(array_initial_elements_c, integer, array_initial_element) |
992 |
1034 |
993 /* structure_type_name ':' structure_specification */ |
1035 /* structure_type_name ':' structure_specification */ |
994 // SYM_REF2(structure_type_declaration_c, structure_type_name, structure_specification) |
1036 // SYM_REF2(structure_type_declaration_c, structure_type_name, structure_specification) |
|
1037 void *fill_candidate_datatypes_c::visit(structure_type_declaration_c *symbol) {return fill_type_decl(symbol, symbol->structure_type_name, symbol->structure_specification);} |
995 |
1038 |
996 /* structure_type_name ASSIGN structure_initialization */ |
1039 /* structure_type_name ASSIGN structure_initialization */ |
997 /* structure_initialization may be NULL ! */ |
1040 /* structure_initialization may be NULL ! */ |
998 // SYM_REF2(initialized_structure_c, structure_type_name, structure_initialization) |
1041 // SYM_REF2(initialized_structure_c, structure_type_name, structure_initialization) |
|
1042 void *fill_candidate_datatypes_c::visit(initialized_structure_c *symbol) {return fill_spec_init(symbol, symbol->structure_type_name, symbol->structure_initialization);} |
999 |
1043 |
1000 /* helper symbol for structure_declaration */ |
1044 /* helper symbol for structure_declaration */ |
1001 /* structure_declaration: STRUCT structure_element_declaration_list END_STRUCT */ |
1045 /* structure_declaration: STRUCT structure_element_declaration_list END_STRUCT */ |
1002 /* structure_element_declaration_list structure_element_declaration ';' */ |
1046 /* structure_element_declaration_list structure_element_declaration ';' */ |
1003 // SYM_LIST(structure_element_declaration_list_c) |
1047 // SYM_LIST(structure_element_declaration_list_c) |