msousa@666: /* msousa@666: * matiec - a compiler for the programming languages defined in IEC 61131-3 msousa@666: * msousa@666: * Copyright (C) 2003-2012 Mario de Sousa (msousa@fe.up.pt) msousa@666: * Copyright (C) 2007-2011 Laurent Bessard and Edouard Tisserant msousa@676: * Copyright (C) 2012 Manuele Conti (conti.ma@alice.it) msousa@666: * msousa@666: * This program is free software: you can redistribute it and/or modify msousa@666: * it under the terms of the GNU General Public License as published by msousa@666: * the Free Software Foundation, either version 3 of the License, or msousa@666: * (at your option) any later version. msousa@666: * msousa@666: * This program is distributed in the hope that it will be useful, msousa@666: * but WITHOUT ANY WARRANTY; without even the implied warranty of msousa@666: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the msousa@666: * GNU General Public License for more details. msousa@666: * msousa@666: * You should have received a copy of the GNU General Public License msousa@666: * along with this program. If not, see . msousa@666: * msousa@666: * msousa@666: * This code is made available on the understanding that it will not be msousa@666: * used in safety-critical situations without a full and competent review. msousa@666: */ msousa@666: msousa@666: /* msousa@666: * An IEC 61131-3 compiler. msousa@666: * msousa@666: * Based on the msousa@666: * FINAL DRAFT - IEC 61131-3, 2nd Ed. (2001-12-10) msousa@666: * msousa@666: */ msousa@666: msousa@666: /* Determine the characteristics of a specific data type msousa@666: * e.g., is it an enumeration, is it an array, is it ANY_INT, etc... msousa@666: * msousa@666: * The methods of this class may be passed either: msousa@666: * - a data type declaration symbol_c, msousa@666: * OR msousa@666: * - the name of a data type (identifier_c) msousa@666: * In this case, we shall first serach for the basetype declaration using search_base_type_c, and then msousa@666: * run the normal process. msousa@666: */ msousa@666: #include "absyntax_utils.hh" msousa@666: msousa@666: #include "../main.hh" // required for ERROR() and ERROR_MSG() macros. msousa@666: msousa@666: msousa@666: msousa@666: #include // required for typeid msousa@666: msousa@666: msousa@727: /**********************************************************/ msousa@727: /**********************************************************/ msousa@727: /**********************************************************/ msousa@727: /***** *****/ msousa@727: /***** *****/ msousa@727: /***** Some helper classes *****/ msousa@727: /***** *****/ msousa@727: /***** *****/ msousa@727: /**********************************************************/ msousa@727: /**********************************************************/ msousa@727: /**********************************************************/ msousa@727: mjsousa@938: mjsousa@938: /****************************************************************************************************/ mjsousa@938: /****************************************************************************************************/ msousa@727: /* Return the identifier (name) of a datatype, typically declared in a TYPE .. END_TYPE declaration */ mjsousa@938: /****************************************************************************************************/ mjsousa@938: /****************************************************************************************************/ msousa@727: class get_datatype_id_c: null_visitor_c { msousa@727: private: msousa@727: static get_datatype_id_c *singleton; msousa@727: msousa@727: public: msousa@727: static symbol_c *get_id(symbol_c *symbol) { msousa@727: if (NULL == singleton) singleton = new get_datatype_id_c(); msousa@727: if (NULL == singleton) ERROR; msousa@727: return (symbol_c *)symbol->accept(*singleton); msousa@727: } msousa@727: msousa@727: protected: mjsousa@929: /***********************************/ mjsousa@929: /* B 1.3.1 - Elementary Data Types */ mjsousa@929: /***********************************/ mjsousa@929: void *visit(time_type_name_c *symbol) {return (void *)symbol;}; mjsousa@929: void *visit(bool_type_name_c *symbol) {return (void *)symbol;}; mjsousa@929: void *visit(sint_type_name_c *symbol) {return (void *)symbol;}; mjsousa@929: void *visit(int_type_name_c *symbol) {return (void *)symbol;}; mjsousa@929: void *visit(dint_type_name_c *symbol) {return (void *)symbol;}; mjsousa@929: void *visit(lint_type_name_c *symbol) {return (void *)symbol;}; mjsousa@929: void *visit(usint_type_name_c *symbol) {return (void *)symbol;}; mjsousa@929: void *visit(uint_type_name_c *symbol) {return (void *)symbol;}; mjsousa@929: void *visit(udint_type_name_c *symbol) {return (void *)symbol;}; mjsousa@929: void *visit(ulint_type_name_c *symbol) {return (void *)symbol;}; mjsousa@929: void *visit(real_type_name_c *symbol) {return (void *)symbol;}; mjsousa@929: void *visit(lreal_type_name_c *symbol) {return (void *)symbol;}; mjsousa@929: void *visit(date_type_name_c *symbol) {return (void *)symbol;}; mjsousa@929: void *visit(tod_type_name_c *symbol) {return (void *)symbol;}; mjsousa@929: void *visit(dt_type_name_c *symbol) {return (void *)symbol;}; mjsousa@929: void *visit(byte_type_name_c *symbol) {return (void *)symbol;}; mjsousa@929: void *visit(word_type_name_c *symbol) {return (void *)symbol;}; mjsousa@929: void *visit(lword_type_name_c *symbol) {return (void *)symbol;}; mjsousa@929: void *visit(dword_type_name_c *symbol) {return (void *)symbol;}; mjsousa@929: void *visit(string_type_name_c *symbol) {return (void *)symbol;}; mjsousa@929: void *visit(wstring_type_name_c *symbol) {return (void *)symbol;}; mjsousa@929: mjsousa@929: void *visit(safetime_type_name_c *symbol) {return (void *)symbol;}; mjsousa@929: void *visit(safebool_type_name_c *symbol) {return (void *)symbol;}; mjsousa@929: void *visit(safesint_type_name_c *symbol) {return (void *)symbol;}; mjsousa@929: void *visit(safeint_type_name_c *symbol) {return (void *)symbol;}; mjsousa@929: void *visit(safedint_type_name_c *symbol) {return (void *)symbol;}; mjsousa@929: void *visit(safelint_type_name_c *symbol) {return (void *)symbol;}; mjsousa@929: void *visit(safeusint_type_name_c *symbol) {return (void *)symbol;}; mjsousa@929: void *visit(safeuint_type_name_c *symbol) {return (void *)symbol;}; mjsousa@929: void *visit(safeudint_type_name_c *symbol) {return (void *)symbol;}; mjsousa@929: void *visit(safeulint_type_name_c *symbol) {return (void *)symbol;}; mjsousa@929: void *visit(safereal_type_name_c *symbol) {return (void *)symbol;}; mjsousa@929: void *visit(safelreal_type_name_c *symbol) {return (void *)symbol;}; mjsousa@929: void *visit(safedate_type_name_c *symbol) {return (void *)symbol;}; mjsousa@929: void *visit(safetod_type_name_c *symbol) {return (void *)symbol;}; mjsousa@929: void *visit(safedt_type_name_c *symbol) {return (void *)symbol;}; mjsousa@929: void *visit(safebyte_type_name_c *symbol) {return (void *)symbol;}; mjsousa@929: void *visit(safeword_type_name_c *symbol) {return (void *)symbol;}; mjsousa@929: void *visit(safelword_type_name_c *symbol) {return (void *)symbol;}; mjsousa@929: void *visit(safedword_type_name_c *symbol) {return (void *)symbol;}; mjsousa@929: void *visit(safestring_type_name_c *symbol) {return (void *)symbol;}; mjsousa@929: void *visit(safewstring_type_name_c *symbol) {return (void *)symbol;}; mjsousa@929: msousa@727: /********************************/ msousa@727: /* B 1.3.3 - Derived data types */ msousa@727: /********************************/ msousa@727: /* simple_type_name ':' simple_spec_init */ mjsousa@909: void *visit(simple_type_declaration_c *symbol) {return symbol->simple_type_name;} msousa@727: /* subrange_type_name ':' subrange_spec_init */ mjsousa@909: void *visit(subrange_type_declaration_c *symbol) {return symbol->subrange_type_name;} msousa@727: /* enumerated_type_name ':' enumerated_spec_init */ msousa@727: void *visit(enumerated_type_declaration_c *symbol) {return symbol->enumerated_type_name;} msousa@727: /* identifier ':' array_spec_init */ mjsousa@909: void *visit(array_type_declaration_c *symbol) {return symbol->identifier;} msousa@727: /* structure_type_name ':' structure_specification */ mjsousa@909: void *visit(structure_type_declaration_c *symbol) {return symbol->structure_type_name;} msousa@727: /* string_type_name ':' elementary_string_type_name string_type_declaration_size string_type_declaration_init */ mjsousa@909: void *visit(string_type_declaration_c *symbol) {return symbol->string_type_name;} mjsousa@909: /* ref_type_decl: identifier ':' ref_spec_init */ mjsousa@909: void *visit(ref_type_decl_c *symbol) {return symbol->ref_type_name;} mjsousa@929: /* NOTE: DO NOT place any code here that references symbol->anotations_map["generate_c_annotaton__implicit_type_id"] !! mjsousa@929: * All anotations in the symbol->anotations_map[] are considered a stage4 construct. In the above example, mjsousa@929: * That anotation is specific to the generate_c stage4 code, and must therefore NOT be referenced mjsousa@929: * in the absyntax_utils code, as this last code should be independent of the stage4 version! mjsousa@929: */ msousa@727: msousa@727: /*****************************/ msousa@727: /* B 1.5.2 - Function Blocks */ msousa@727: /*****************************/ msousa@727: /* FUNCTION_BLOCK derived_function_block_name io_OR_other_var_declarations function_block_body END_FUNCTION_BLOCK */ mjsousa@909: void *visit(function_block_declaration_c *symbol) {return symbol->fblock_name;} msousa@727: }; // get_datatype_id_c msousa@727: msousa@727: get_datatype_id_c *get_datatype_id_c::singleton = NULL; msousa@727: msousa@727: msousa@727: msousa@727: mjsousa@938: mjsousa@938: mjsousa@938: /**************************************************/ mjsousa@938: /**************************************************/ mjsousa@938: /* transform elementary data type class to string */ mjsousa@938: /**************************************************/ mjsousa@938: /**************************************************/ msousa@778: msousa@778: /* A small helper class, to transform elementary data type to string. msousa@778: * this allows us to generate more relevant error messages... msousa@778: */ msousa@778: msousa@778: class get_datatype_id_str_c: public null_visitor_c { msousa@778: protected: msousa@778: get_datatype_id_str_c(void) {}; msousa@778: ~get_datatype_id_str_c(void) {}; msousa@778: msousa@778: private: msousa@778: /* singleton class! */ msousa@778: static get_datatype_id_str_c *singleton; msousa@778: msousa@778: public: msousa@778: static const char *get_id_str(symbol_c *symbol) { msousa@778: if (NULL == singleton) singleton = new get_datatype_id_str_c; msousa@778: if (NULL == singleton) ERROR; msousa@778: const char *res = (const char *)symbol->accept(*singleton); msousa@778: if (NULL == res) ERROR; msousa@778: return res; msousa@778: } msousa@778: msousa@778: msousa@778: /*************************/ msousa@778: /* B.1 - Common elements */ msousa@778: /*************************/ msousa@778: /*******************************************/ msousa@778: /* B 1.1 - Letters, digits and identifiers */ msousa@778: /*******************************************/ msousa@778: void *visit(identifier_c *symbol) {return (void *)symbol->value;}; msousa@778: msousa@778: /***********************************/ msousa@778: /* B 1.3.1 - Elementary Data Types */ msousa@778: /***********************************/ msousa@778: void *visit(time_type_name_c *symbol) {return (void *)"TIME"; }; msousa@778: void *visit(bool_type_name_c *symbol) {return (void *)"BOOL"; }; msousa@778: void *visit(sint_type_name_c *symbol) {return (void *)"SINT"; }; msousa@778: void *visit(int_type_name_c *symbol) {return (void *)"INT"; }; msousa@778: void *visit(dint_type_name_c *symbol) {return (void *)"DINT"; }; msousa@778: void *visit(lint_type_name_c *symbol) {return (void *)"LINT"; }; msousa@778: void *visit(usint_type_name_c *symbol) {return (void *)"USINT"; }; msousa@778: void *visit(uint_type_name_c *symbol) {return (void *)"UINT"; }; msousa@778: void *visit(udint_type_name_c *symbol) {return (void *)"UDINT"; }; msousa@778: void *visit(ulint_type_name_c *symbol) {return (void *)"ULINT"; }; msousa@778: void *visit(real_type_name_c *symbol) {return (void *)"REAL"; }; msousa@778: void *visit(lreal_type_name_c *symbol) {return (void *)"LREAL"; }; msousa@778: void *visit(date_type_name_c *symbol) {return (void *)"DATE"; }; msousa@778: void *visit(tod_type_name_c *symbol) {return (void *)"TOD"; }; msousa@778: void *visit(dt_type_name_c *symbol) {return (void *)"DT"; }; msousa@778: void *visit(byte_type_name_c *symbol) {return (void *)"BYTE"; }; msousa@778: void *visit(word_type_name_c *symbol) {return (void *)"WORD"; }; msousa@778: void *visit(lword_type_name_c *symbol) {return (void *)"LWORD"; }; msousa@778: void *visit(dword_type_name_c *symbol) {return (void *)"DWORD"; }; msousa@778: void *visit(string_type_name_c *symbol) {return (void *)"STRING"; }; msousa@778: void *visit(wstring_type_name_c *symbol) {return (void *)"WSTRING"; }; msousa@778: msousa@778: void *visit(safetime_type_name_c *symbol) {return (void *)"SAFETIME"; }; msousa@778: void *visit(safebool_type_name_c *symbol) {return (void *)"SAFEBOOL"; }; msousa@778: void *visit(safesint_type_name_c *symbol) {return (void *)"SAFESINT"; }; msousa@778: void *visit(safeint_type_name_c *symbol) {return (void *)"SAFEINT"; }; msousa@778: void *visit(safedint_type_name_c *symbol) {return (void *)"SAFEDINT"; }; msousa@778: void *visit(safelint_type_name_c *symbol) {return (void *)"SAFELINT"; }; msousa@778: void *visit(safeusint_type_name_c *symbol) {return (void *)"SAFEUSINT"; }; msousa@778: void *visit(safeuint_type_name_c *symbol) {return (void *)"SAFEUINT"; }; msousa@778: void *visit(safeudint_type_name_c *symbol) {return (void *)"SAFEUDINT"; }; msousa@778: void *visit(safeulint_type_name_c *symbol) {return (void *)"SAFEULINT"; }; msousa@778: void *visit(safereal_type_name_c *symbol) {return (void *)"SAFEREAL"; }; msousa@778: void *visit(safelreal_type_name_c *symbol) {return (void *)"SAFELREAL"; }; msousa@778: void *visit(safedate_type_name_c *symbol) {return (void *)"SAFEDATE"; }; msousa@778: void *visit(safetod_type_name_c *symbol) {return (void *)"SAFETOD"; }; msousa@778: void *visit(safedt_type_name_c *symbol) {return (void *)"SAFEDT"; }; msousa@778: void *visit(safebyte_type_name_c *symbol) {return (void *)"SAFEBYTE"; }; msousa@778: void *visit(safeword_type_name_c *symbol) {return (void *)"SAFEWORD"; }; msousa@778: void *visit(safelword_type_name_c *symbol) {return (void *)"SAFELWORD"; }; msousa@778: void *visit(safedword_type_name_c *symbol) {return (void *)"SAFEDWORD"; }; msousa@778: void *visit(safestring_type_name_c *symbol) {return (void *)"SAFESTRING"; }; msousa@778: void *visit(safewstring_type_name_c *symbol) {return (void *)"SAFEWSTRING"; }; msousa@778: msousa@778: /********************************/ msousa@778: /* B 1.3.3 - Derived data types */ msousa@778: /********************************/ msousa@778: /* simple_type_name ':' simple_spec_init */ mjsousa@909: void *visit(simple_type_declaration_c *symbol) {return symbol->simple_type_name->accept(*this);} msousa@778: /* subrange_type_name ':' subrange_spec_init */ mjsousa@909: void *visit(subrange_type_declaration_c *symbol) {return symbol->subrange_type_name->accept(*this);} msousa@778: /* enumerated_type_name ':' enumerated_spec_init */ msousa@778: void *visit(enumerated_type_declaration_c *symbol) {return symbol->enumerated_type_name->accept(*this);} msousa@778: /* identifier ':' array_spec_init */ mjsousa@909: void *visit(array_type_declaration_c *symbol) {return symbol->identifier->accept(*this);} msousa@778: /* structure_type_name ':' structure_specification */ mjsousa@909: void *visit(structure_type_declaration_c *symbol) {return symbol->structure_type_name->accept(*this);} msousa@778: /* string_type_name ':' elementary_string_type_name string_type_declaration_size string_type_declaration_init */ mjsousa@909: void *visit(string_type_declaration_c *symbol) {return symbol->string_type_name->accept(*this);} mjsousa@909: /* ref_type_decl: identifier ':' ref_spec_init */ mjsousa@909: void *visit(ref_type_decl_c *symbol) {return symbol->ref_type_name->accept(*this);} mjsousa@929: /* NOTE: DO NOT place any code here that references symbol->anotations_map["generate_c_annotaton__implicit_type_id"] !! mjsousa@929: * All anotations in the symbol->anotations_map[] are considered a stage4 construct. In the above example, mjsousa@929: * That anotation is specific to the generate_c stage4 code, and must therefore NOT be referenced mjsousa@929: * in the absyntax_utils code, as this last code should be independent of the stage4 version! mjsousa@929: */ msousa@778: msousa@778: /*****************************/ msousa@778: /* B 1.5.2 - Function Blocks */ msousa@778: /*****************************/ msousa@778: /* FUNCTION_BLOCK derived_function_block_name io_OR_other_var_declarations function_block_body END_FUNCTION_BLOCK */ mjsousa@909: void *visit(function_block_declaration_c *symbol) {return symbol->fblock_name->accept(*this);} msousa@778: }; msousa@778: msousa@778: get_datatype_id_str_c *get_datatype_id_str_c::singleton = NULL; msousa@778: msousa@727: msousa@727: mjsousa@938: /*********************************************************/ mjsousa@938: /*********************************************************/ mjsousa@938: /* get the datatype of a field inside a struct data type */ mjsousa@938: /*********************************************************/ mjsousa@938: /*********************************************************/ mjsousa@938: mjsousa@938: class get_struct_info_c : null_visitor_c { mjsousa@938: private: mjsousa@938: symbol_c *current_field; mjsousa@938: /* singleton class! */ mjsousa@938: static get_struct_info_c *singleton; mjsousa@938: mjsousa@938: public: mjsousa@938: get_struct_info_c(void) {current_field = NULL;} mjsousa@938: mjsousa@938: static symbol_c *get_field_type_id(symbol_c *struct_type, symbol_c *field_name) { mjsousa@938: if (NULL == singleton) singleton = new get_struct_info_c; mjsousa@938: if (NULL == singleton) ERROR; mjsousa@938: singleton->current_field = field_name; mjsousa@938: return (symbol_c *)struct_type->accept(*singleton); mjsousa@938: } mjsousa@938: mjsousa@938: mjsousa@938: private: mjsousa@938: /*************************/ mjsousa@938: /* B.1 - Common elements */ mjsousa@938: /*************************/ mjsousa@938: /********************************/ mjsousa@938: /* B 1.3.3 - Derived data types */ mjsousa@938: /********************************/ mjsousa@938: /* structure_type_name ':' structure_specification */ mjsousa@938: /* NOTE: this is only used inside a TYPE ... END_TYPE declaration. It is never used directly when declaring a new variable! */ mjsousa@938: /* NOTE: structure_specification will point to either initialized_structure_c OR structure_element_declaration_list_c */ mjsousa@938: void *visit(structure_type_declaration_c *symbol) {return symbol->structure_specification->accept(*this);} mjsousa@938: mjsousa@938: /* structure_type_name ASSIGN structure_initialization */ mjsousa@938: /* structure_initialization may be NULL ! */ mjsousa@938: // SYM_REF2(initialized_structure_c, structure_type_name, structure_initialization) mjsousa@938: /* NOTE: only the initialized structure is never used when declaring a new variable instance */ mjsousa@938: void *visit(initialized_structure_c *symbol) {return symbol->structure_type_name->accept(*this);} mjsousa@938: mjsousa@938: /* helper symbol for structure_declaration */ mjsousa@938: /* structure_declaration: STRUCT structure_element_declaration_list END_STRUCT */ mjsousa@938: /* structure_element_declaration_list structure_element_declaration ';' */ mjsousa@938: void *visit(structure_element_declaration_list_c *symbol) { mjsousa@938: /* now search the structure declaration */ mjsousa@938: for(int i = 0; i < symbol->n; i++) { mjsousa@938: void *tmp = symbol->elements[i]->accept(*this); mjsousa@938: if (NULL != tmp) return tmp; mjsousa@938: } mjsousa@938: return NULL; // not found!! mjsousa@938: } mjsousa@938: mjsousa@938: /* structure_element_name ':' spec_init */ mjsousa@938: void *visit(structure_element_declaration_c *symbol) { mjsousa@938: if (compare_identifiers(symbol->structure_element_name, current_field) == 0) mjsousa@938: return symbol->spec_init; /* found the type of the element we were looking for! */ mjsousa@938: return NULL; /* not the element we are looking for! */ mjsousa@938: } mjsousa@938: mjsousa@938: mjsousa@938: /* helper symbol for structure_initialization */ mjsousa@938: /* structure_initialization: '(' structure_element_initialization_list ')' */ mjsousa@938: /* structure_element_initialization_list ',' structure_element_initialization */ mjsousa@938: void *visit(structure_element_initialization_list_c *symbol) {ERROR; return NULL;} /* should never get called... */ mjsousa@938: /* structure_element_name ASSIGN value */ mjsousa@938: void *visit(structure_element_initialization_c *symbol) {ERROR; return NULL;} /* should never get called... */ mjsousa@938: mjsousa@938: mjsousa@938: /**************************************/ mjsousa@938: /* B.1.5 - Program organization units */ mjsousa@938: /**************************************/ mjsousa@938: /*****************************/ mjsousa@938: /* B 1.5.2 - Function Blocks */ mjsousa@938: /*****************************/ mjsousa@938: /* FUNCTION_BLOCK derived_function_block_name io_OR_other_var_declarations function_block_body END_FUNCTION_BLOCK */ mjsousa@938: // SYM_REF4(function_block_declaration_c, fblock_name, var_declarations, fblock_body, unused) mjsousa@938: void *visit(function_block_declaration_c *symbol) { mjsousa@938: /* now search the function block declaration for the variable... */ mjsousa@938: search_var_instance_decl_c search_decl(symbol); mjsousa@938: return search_decl.get_decl(current_field); mjsousa@938: } mjsousa@938: mjsousa@938: /*********************************************/ mjsousa@938: /* B.1.6 Sequential function chart elements */ mjsousa@938: /*********************************************/ mjsousa@938: /* INITIAL_STEP step_name ':' action_association_list END_STEP */ mjsousa@938: // SYM_REF2(initial_step_c, step_name, action_association_list) mjsousa@938: void *visit(initial_step_c *symbol) { mjsousa@938: identifier_c T("T"); identifier_c X("X"); mjsousa@938: /* Hard code the datatypes of the implicit variables Stepname.X and Stepname.T */ mjsousa@938: if (compare_identifiers(&T, current_field) == 0) return &get_datatype_info_c::time_type_name; mjsousa@938: if (compare_identifiers(&X, current_field) == 0) return &get_datatype_info_c::bool_type_name; mjsousa@938: return NULL; mjsousa@938: } mjsousa@938: mjsousa@938: /* STEP step_name ':' action_association_list END_STEP */ mjsousa@938: // SYM_REF2(step_c, step_name, action_association_list) mjsousa@938: /* The code here should be identicial to the code in the visit(initial_step_c *) visitor! So we simply call the other visitor! */ mjsousa@938: void *visit(step_c *symbol) {initial_step_c initial_step(NULL, NULL); return initial_step.accept(*this);} mjsousa@938: mjsousa@938: }; // get_struct_info_c mjsousa@938: mjsousa@938: get_struct_info_c *get_struct_info_c::singleton = NULL; mjsousa@938: mjsousa@938: mjsousa@938: mjsousa@938: mjsousa@938: msousa@727: /**********************************************************/ msousa@727: /**********************************************************/ msousa@727: /**********************************************************/ msousa@727: /***** *****/ msousa@727: /***** *****/ msousa@727: /***** GET_DATATYPE_INFO_C *****/ msousa@727: /***** *****/ msousa@727: /***** *****/ msousa@727: /**********************************************************/ msousa@727: /**********************************************************/ msousa@727: /**********************************************************/ msousa@727: msousa@778: const char *get_datatype_info_c::get_id_str(symbol_c *datatype) { msousa@778: return get_datatype_id_str_c::get_id_str(datatype); msousa@778: } msousa@778: msousa@778: msousa@778: symbol_c *get_datatype_info_c::get_id(symbol_c *datatype) { msousa@727: return get_datatype_id_c::get_id(datatype); msousa@727: } msousa@666: msousa@676: mjsousa@938: symbol_c *get_datatype_info_c::get_struct_field_type_id(symbol_c *struct_datatype, symbol_c *struct_fieldname) { mjsousa@938: return get_struct_info_c::get_field_type_id(struct_datatype, struct_fieldname); mjsousa@938: } mjsousa@938: mjsousa@939: symbol_c *get_datatype_info_c::get_array_storedtype_id(symbol_c *type_symbol) { mjsousa@939: // returns the datatype of the variables stored in the array mjsousa@939: symbol_c *basetype = search_base_type_c::get_basetype_decl(type_symbol); mjsousa@939: array_specification_c *symbol = dynamic_cast(basetype); mjsousa@939: mjsousa@939: if (NULL != symbol) mjsousa@939: return symbol->non_generic_type_name; mjsousa@939: return NULL; // this is not an array! mjsousa@939: } mjsousa@939: mjsousa@939: mjsousa@922: /* Returns true if both datatypes are equivalent (not necessarily equal!). mjsousa@922: * WARNING: May return true even though the datatypes are not the same/identicial!!! mjsousa@922: * This occurs when at least one of the datatypes is of a generic mjsousa@922: * datatype (or a REF_TO a generic datatype). mjsousa@922: * (Generic dataypes: ANY, ANY_INT, ANY_NUM, ...) mjsousa@922: * NOTE: Currently only the ANY generic datatype is implemented! mjsousa@922: * NOTE: Currently stage1_2 only allows the use of the ANY keyword when in conjuntion with mjsousa@922: * the REF_TO keyword (i.e. REF_TO ANY), so when handling non REF_TO datatypes, mjsousa@922: * this function will currently only return true if the dataypes are identicial. mjsousa@921: */ mjsousa@929: mjsousa@929: /* NOTE: Currently the datatype model used by matiec considers any implicitly defined datatype mjsousa@929: * (e.g. an array datatype defined in the variable declaration itself, instead of inside a TYPE ... END_TYPE mjsousa@929: * construct) to be different (i.e. not the same datatype, and therefore not compatible) to any other mjsousa@929: * datatype, including with datatypes declared identically to the implicit datatype. mjsousa@929: * e.g. mjsousa@929: * TYPE my_array_t: ARRAY [1..3] OF INT; END_TYPE; mjsousa@929: * FUNCTION_BLOCK FOO mjsousa@929: * VAR my_array: ARRAY [1..3] OF INT; END_VAR mjsousa@929: * ... mjsousa@929: * END_FUNCTION_BLOCK mjsousa@929: * mjsousa@929: * In the abive code, my_array is NOT considered to te compatible with my_Array_t !!! mjsousa@929: * mjsousa@929: * In essence, the currently supported datatype model considers all datatypes to be different to each other, mjsousa@929: * even though the stored data is the same (Let us call this rule (0))! mjsousa@929: * There are 2 exceptions to the above rule: mjsousa@929: * (1) Datatypes that are directly derived from other datatypes. mjsousa@929: * (this rule is specified in the standard, so we follow it!) mjsousa@929: * (2) REF_TO datatypes that reference the same datatype mjsousa@929: * (I dont think the standard says anything about this!) mjsousa@929: * mjsousa@929: * TYPE mjsousa@929: * my_array_1_t: ARRAY [1..3] OF INT; mjsousa@929: * my_array_2_t: ARRAY [1..3] OF INT; mjsousa@929: * my_array_3_t: my_array_1_t; mjsousa@929: * A_ref_t: REF_TO my_array_1_t; mjsousa@929: * B_ref_t: REF_TO my_array_1_t; mjsousa@929: * C_ref_t: A_ref_t; mjsousa@929: * END_TYPE; mjsousa@929: * mjsousa@929: * In the above code, my_array_1_t is a distinct datatype to my_array_2_t mjsousa@929: * (this is different to C and C++, where they would be considered the same datatype!) mjsousa@929: * (following rule (0)) mjsousa@929: * In the above code, my_array_3_t is the same datatype as my_array_1_t mjsousa@929: * (following rule (1)) mjsousa@929: * In the above code, A_ref_t is the same datatype as B_ref_t mjsousa@929: * (following rule (2)) mjsousa@929: * In the above code, A_ref_t is the same datatype as C_ref_t mjsousa@929: * (following rule (1)) mjsousa@929: * mjsousa@929: * Note that rule (0) means that a function/FB with a parameter whose datatype is implicitly defined mjsousa@929: * can never be passed a value! mjsousa@929: * FUNCTION_BLOCK FOO mjsousa@929: * VAR_INPUT my_array: ARRAY [1..3] OF INT; END_VAR mjsousa@929: * ... mjsousa@929: * END_FUNCTION_BLOCK mjsousa@929: * mjsousa@929: * Any call to FB foo can never pass a value to parameter my_array, as its datatype is distinct mjsousa@929: * to all other datatypes, and therefore passing any other variable to my_array will result in an mjsousa@929: * 'incompatible datatypes' error! mjsousa@929: * The above seems natural o me (Mario) in a programming language that is very strongly typed. mjsousa@929: * mjsousa@929: * However, if we did not have exception (2), the following would also be invalid: mjsousa@929: * TYPE my_array_t: ARRAY [1..3] OF INT; END_TYPE; mjsousa@929: * FUNCTION_BLOCK FOO_t mjsousa@929: * VAR_INPUT my_array: REF_TO my_array_t; END_VAR mjsousa@929: * ... mjsousa@929: * END_FUNCTION_BLOCK mjsousa@929: * mjsousa@929: * FUNCTION_BLOCK BAR mjsousa@929: * VAR mjsousa@929: * my_array: my_array_t; mjsousa@929: * foo: FOO_t; mjsousa@929: * END_VAR mjsousa@929: * foo(REF(my_array)); <----- invalid, without rule 2!! mjsousa@929: * ... mjsousa@929: * END_FUNCTION_BLOCK mjsousa@929: * mjsousa@929: * Rule/exception (2) goes against the datatype model used for all other datatypes. mjsousa@929: * This rule was adopted as without it, the datatype of the value returned by the REF() mjsousa@929: * operator would be considered distinct to all other datatypes, and therefore the mjsousa@929: * REF() operator would be essentially useless. mjsousa@929: */ msousa@676: bool get_datatype_info_c::is_type_equal(symbol_c *first_type, symbol_c *second_type) { mjsousa@921: if (!is_type_valid( first_type)) {return false;} mjsousa@921: if (!is_type_valid(second_type)) {return false;} mjsousa@921: mjsousa@921: /* GENERIC DATATYPES */ mjsousa@921: /* For the moment, we only support the ANY generic datatype! */ mjsousa@921: if ((is_ANY_generic_type( first_type)) || mjsousa@921: (is_ANY_generic_type(second_type))) {return true;} mjsousa@921: mjsousa@909: /* ANY_ELEMENTARY */ mjsousa@909: if ((is_ANY_ELEMENTARY(first_type)) && msousa@695: (typeid(*first_type) == typeid(*second_type))) {return true;} mjsousa@909: msousa@695: /* ANY_DERIVED */ mjsousa@919: if (is_ref_to(first_type) && is_ref_to(second_type)) { mjsousa@919: return is_type_equal(search_base_type_c::get_basetype_decl(get_ref_to(first_type )), mjsousa@919: search_base_type_c::get_basetype_decl(get_ref_to(second_type))); mjsousa@919: } msousa@695: return (first_type == second_type); msousa@676: } msousa@676: msousa@676: msousa@676: bool get_datatype_info_c::is_type_valid(symbol_c *type) { msousa@695: if (NULL == type) {return false;} msousa@695: if (typeid(*type) == typeid(invalid_type_name_c)) {return false;} msousa@676: return true; msousa@676: } msousa@676: msousa@676: msousa@676: msousa@676: msousa@676: msousa@676: mjsousa@909: mjsousa@909: /* returns the datatype the REF_TO datatype references/points to... */ mjsousa@909: symbol_c *get_datatype_info_c::get_ref_to(symbol_c *type_symbol) { mjsousa@909: ref_type_decl_c *type1 = dynamic_cast(type_symbol); mjsousa@909: if (NULL != type1) type_symbol = type1->ref_spec_init; mjsousa@909: mjsousa@909: ref_spec_init_c *type2 = dynamic_cast(type_symbol); mjsousa@909: if (NULL != type2) type_symbol = type2->ref_spec; mjsousa@909: mjsousa@909: ref_spec_c *type3 = dynamic_cast(type_symbol); mjsousa@909: if (NULL != type3) return type3->type_name; mjsousa@909: mjsousa@909: return NULL; /* this is not a ref datatype!! */ mjsousa@909: } mjsousa@909: mjsousa@909: mjsousa@909: mjsousa@909: mjsousa@909: mjsousa@909: mjsousa@909: bool get_datatype_info_c::is_ref_to(symbol_c *type_symbol) { mjsousa@909: symbol_c *type_decl = search_base_type_c::get_basetype_decl(type_symbol); mjsousa@909: if (NULL == type_decl) {return false;} mjsousa@909: mjsousa@909: if (typeid(*type_decl) == typeid(ref_type_decl_c)) {return true;} /* identifier ':' ref_spec_init */ mjsousa@909: if (typeid(*type_decl) == typeid(ref_spec_init_c)) {return true;} /* ref_spec [ ASSIGN ref_initialization ]; */ mjsousa@909: if (typeid(*type_decl) == typeid(ref_spec_c)) {return true;} /* REF_TO (non_generic_type_name | function_block_type_name) */ mjsousa@909: return false; mjsousa@909: } mjsousa@909: mjsousa@909: mjsousa@909: mjsousa@909: msousa@666: bool get_datatype_info_c::is_sfc_initstep(symbol_c *type_symbol) { msousa@718: symbol_c *type_decl = search_base_type_c::get_basetype_decl(type_symbol); mjsousa@832: if (NULL == type_decl) {return false;} msousa@666: if (typeid(*type_decl) == typeid(initial_step_c)) {return true;} /* INITIAL_STEP step_name ':' action_association_list END_STEP */ /* A pseudo data type! */ msousa@666: return false; msousa@666: } msousa@666: msousa@666: msousa@666: msousa@666: bool get_datatype_info_c::is_sfc_step(symbol_c *type_symbol) { msousa@718: symbol_c *type_decl = search_base_type_c::get_basetype_decl(type_symbol); mjsousa@832: if (NULL == type_decl) {return false;} msousa@666: if (typeid(*type_decl) == typeid(initial_step_c)) {return true;} /* INITIAL_STEP step_name ':' action_association_list END_STEP */ /* A pseudo data type! */ msousa@666: if (typeid(*type_decl) == typeid( step_c)) {return true;} /* STEP step_name ':' action_association_list END_STEP */ /* A pseudo data type! */ msousa@666: return false; msousa@666: } msousa@666: msousa@666: msousa@666: msousa@666: msousa@666: bool get_datatype_info_c::is_function_block(symbol_c *type_symbol) { msousa@718: symbol_c *type_decl = search_base_type_c::get_basetype_decl(type_symbol); mjsousa@832: if (NULL == type_decl) {return false;} msousa@666: if (typeid(*type_decl) == typeid(function_block_declaration_c)) {return true;} /* FUNCTION_BLOCK derived_function_block_name io_OR_other_var_declarations function_block_body END_FUNCTION_BLOCK */ msousa@666: return false; msousa@666: } msousa@666: msousa@666: msousa@666: msousa@666: msousa@666: msousa@666: bool get_datatype_info_c::is_subrange(symbol_c *type_symbol) { mjsousa@858: symbol_c *type_decl = search_base_type_c::get_equivtype_decl(type_symbol); /* NOTE: do NOT call search_base_type_c !! */ mjsousa@832: if (NULL == type_decl) {return false;} msousa@666: msousa@666: if (typeid(*type_decl) == typeid(subrange_type_declaration_c)) {return true;} /* subrange_type_name ':' subrange_spec_init */ msousa@666: if (typeid(*type_decl) == typeid(subrange_spec_init_c)) {return true;} /* subrange_specification ASSIGN signed_integer */ msousa@666: if (typeid(*type_decl) == typeid(subrange_specification_c)) {return true;} /* integer_type_name '(' subrange')' */ msousa@666: msousa@666: if (typeid(*type_decl) == typeid(subrange_c)) {ERROR;} /* signed_integer DOTDOT signed_integer */ msousa@666: return false; msousa@666: } msousa@666: msousa@666: msousa@666: msousa@666: msousa@666: msousa@666: bool get_datatype_info_c::is_enumerated(symbol_c *type_symbol) { msousa@718: symbol_c *type_decl = search_base_type_c::get_basetype_decl(type_symbol); mjsousa@832: if (NULL == type_decl) {return false;} msousa@666: msousa@666: if (typeid(*type_decl) == typeid(enumerated_type_declaration_c)) {return true;} /* enumerated_type_name ':' enumerated_spec_init */ msousa@666: if (typeid(*type_decl) == typeid(enumerated_spec_init_c)) {return true;} /* enumerated_specification ASSIGN enumerated_value */ msousa@666: if (typeid(*type_decl) == typeid(enumerated_value_list_c)) {return true;} /* enumerated_value_list ',' enumerated_value */ /* once we change the way we handle enums, this will probably become an ERROR! */ msousa@666: msousa@666: if (typeid(*type_decl) == typeid(enumerated_value_c)) {ERROR;} /* enumerated_type_name '#' identifier */ msousa@666: return false; msousa@666: } msousa@666: msousa@666: msousa@666: msousa@666: msousa@666: msousa@666: bool get_datatype_info_c::is_array(symbol_c *type_symbol) { msousa@718: symbol_c *type_decl = search_base_type_c::get_basetype_decl(type_symbol); mjsousa@832: if (NULL == type_decl) {return false;} msousa@666: msousa@666: if (typeid(*type_decl) == typeid(array_type_declaration_c)) {return true;} /* identifier ':' array_spec_init */ msousa@666: if (typeid(*type_decl) == typeid(array_spec_init_c)) {return true;} /* array_specification [ASSIGN array_initialization} */ msousa@666: if (typeid(*type_decl) == typeid(array_specification_c)) {return true;} /* ARRAY '[' array_subrange_list ']' OF non_generic_type_name */ msousa@666: msousa@666: if (typeid(*type_decl) == typeid(array_subrange_list_c)) {ERROR;} /* array_subrange_list ',' subrange */ msousa@666: if (typeid(*type_decl) == typeid(array_initial_elements_list_c)) {ERROR;} /* array_initialization: '[' array_initial_elements_list ']' */ /* array_initial_elements_list ',' array_initial_elements */ msousa@666: if (typeid(*type_decl) == typeid(array_initial_elements_c)) {ERROR;} /* integer '(' [array_initial_element] ')' */ msousa@666: return false; msousa@666: } msousa@666: msousa@666: msousa@666: msousa@666: msousa@666: msousa@666: bool get_datatype_info_c::is_structure(symbol_c *type_symbol) { msousa@718: symbol_c *type_decl = search_base_type_c::get_basetype_decl(type_symbol); mjsousa@832: if (NULL == type_decl) {return false;} msousa@666: msousa@666: if (typeid(*type_decl) == typeid(structure_type_declaration_c)) {return true;} /* structure_type_name ':' structure_specification */ msousa@666: if (typeid(*type_decl) == typeid(initialized_structure_c)) {return true;} /* structure_type_name ASSIGN structure_initialization */ msousa@666: if (typeid(*type_decl) == typeid(structure_element_declaration_list_c)) {return true;} /* structure_declaration: STRUCT structure_element_declaration_list END_STRUCT */ /* structure_element_declaration_list structure_element_declaration ';' */ msousa@666: msousa@666: if (typeid(*type_decl) == typeid(structure_element_declaration_c)) {ERROR;} /* structure_element_name ':' *_spec_init */ msousa@666: if (typeid(*type_decl) == typeid(structure_element_initialization_list_c)) {ERROR;} /* structure_initialization: '(' structure_element_initialization_list ')' */ /* structure_element_initialization_list ',' structure_element_initialization */ msousa@666: if (typeid(*type_decl) == typeid(structure_element_initialization_c)) {ERROR;} /* structure_element_name ASSIGN value */ msousa@666: return false; msousa@666: } msousa@666: msousa@666: msousa@666: msousa@666: mjsousa@921: bool get_datatype_info_c::is_ANY_generic_type(symbol_c *type_symbol) { mjsousa@921: symbol_c *type_decl = search_base_type_c::get_basetype_decl(type_symbol); mjsousa@921: if (NULL == type_decl) {return false;} mjsousa@921: if (typeid(*type_decl) == typeid(generic_type_any_c)) {return true;} /* The ANY keyword! */ mjsousa@921: return false; mjsousa@921: } msousa@666: msousa@666: msousa@666: bool get_datatype_info_c::is_ANY_ELEMENTARY(symbol_c *type_symbol) { msousa@666: if (type_symbol == NULL) {return false;} msousa@666: if (is_ANY_MAGNITUDE(type_symbol)) {return true;} msousa@666: if (is_ANY_BIT (type_symbol)) {return true;} msousa@666: if (is_ANY_STRING (type_symbol)) {return true;} msousa@666: if (is_ANY_DATE (type_symbol)) {return true;} msousa@666: return false; msousa@666: } msousa@666: msousa@666: msousa@666: bool get_datatype_info_c::is_ANY_SAFEELEMENTARY(symbol_c *type_symbol) { msousa@666: if (type_symbol == NULL) {return false;} msousa@666: if (is_ANY_SAFEMAGNITUDE(type_symbol)) {return true;} msousa@666: if (is_ANY_SAFEBIT (type_symbol)) {return true;} msousa@666: if (is_ANY_SAFESTRING (type_symbol)) {return true;} msousa@666: if (is_ANY_SAFEDATE (type_symbol)) {return true;} msousa@666: return false; msousa@666: } msousa@666: msousa@666: msousa@666: bool get_datatype_info_c::is_ANY_ELEMENTARY_compatible(symbol_c *type_symbol) { msousa@666: if (type_symbol == NULL) {return false;} msousa@666: if (is_ANY_ELEMENTARY (type_symbol)) {return true;} msousa@666: if (is_ANY_SAFEELEMENTARY(type_symbol)) {return true;} msousa@666: return false; msousa@666: } msousa@666: msousa@666: msousa@666: msousa@666: msousa@666: msousa@666: msousa@666: msousa@666: bool get_datatype_info_c::is_ANY_MAGNITUDE(symbol_c *type_symbol) { msousa@666: if (type_symbol == NULL) {return false;} msousa@668: if (is_TIME(type_symbol)) {return true;} msousa@666: if (is_ANY_NUM(type_symbol)) {return true;} msousa@666: return false; msousa@666: } msousa@666: msousa@666: msousa@666: bool get_datatype_info_c::is_ANY_SAFEMAGNITUDE(symbol_c *type_symbol) { msousa@666: if (type_symbol == NULL) {return false;} msousa@668: if (is_SAFETIME(type_symbol)) {return true;} msousa@666: if (is_ANY_SAFENUM(type_symbol)) {return true;} msousa@666: return false; msousa@666: } msousa@666: msousa@666: msousa@666: bool get_datatype_info_c::is_ANY_MAGNITUDE_compatible(symbol_c *type_symbol) { msousa@666: if (type_symbol == NULL) {return false;} msousa@666: if (is_ANY_MAGNITUDE (type_symbol)) {return true;} msousa@666: if (is_ANY_SAFEMAGNITUDE(type_symbol)) {return true;} msousa@666: return false; msousa@666: } msousa@666: msousa@666: msousa@666: msousa@666: msousa@666: msousa@666: msousa@666: msousa@666: bool get_datatype_info_c::is_ANY_signed_MAGNITUDE(symbol_c *type_symbol) { msousa@666: if (type_symbol == NULL) {return false;} msousa@666: if (typeid(*type_symbol) == typeid(time_type_name_c)) {return true;} msousa@666: if (is_ANY_signed_NUM(type_symbol)) {return true;} msousa@666: return false; msousa@666: } msousa@666: msousa@666: msousa@666: bool get_datatype_info_c::is_ANY_signed_SAFEMAGNITUDE(symbol_c *type_symbol) { msousa@666: if (type_symbol == NULL) {return false;} msousa@666: if (typeid(*type_symbol) == typeid(safetime_type_name_c)) {return true;} msousa@666: return is_ANY_signed_SAFENUM(type_symbol); msousa@666: } msousa@666: msousa@666: msousa@666: bool get_datatype_info_c::is_ANY_signed_MAGNITUDE_compatible(symbol_c *type_symbol) { msousa@666: if (type_symbol == NULL) {return false;} msousa@666: if (is_ANY_signed_MAGNITUDE (type_symbol)) {return true;} msousa@666: if (is_ANY_signed_SAFEMAGNITUDE(type_symbol)) {return true;} msousa@666: return false; msousa@666: } msousa@666: msousa@666: msousa@666: msousa@666: msousa@666: msousa@666: msousa@666: msousa@666: bool get_datatype_info_c::is_ANY_NUM(symbol_c *type_symbol) { msousa@666: if (type_symbol == NULL) {return false;} msousa@666: if (is_ANY_REAL(type_symbol)) {return true;} msousa@666: if (is_ANY_INT (type_symbol)) {return true;} msousa@666: return false; msousa@666: } msousa@666: msousa@666: msousa@666: bool get_datatype_info_c::is_ANY_SAFENUM(symbol_c *type_symbol) { msousa@666: if (type_symbol == NULL) {return false;} msousa@666: if (is_ANY_SAFEREAL(type_symbol)) {return true;} msousa@666: if (is_ANY_SAFEINT (type_symbol)) {return true;} msousa@676: return false; msousa@666: } msousa@666: msousa@666: msousa@666: bool get_datatype_info_c::is_ANY_NUM_compatible(symbol_c *type_symbol) { msousa@666: if (type_symbol == NULL) {return false;} msousa@666: if (is_ANY_NUM (type_symbol)) {return true;} msousa@666: if (is_ANY_SAFENUM(type_symbol)) {return true;} msousa@666: return false; msousa@666: } msousa@666: msousa@666: msousa@666: msousa@666: msousa@666: msousa@666: msousa@666: msousa@666: bool get_datatype_info_c::is_ANY_signed_NUM(symbol_c *type_symbol) { msousa@666: if (type_symbol == NULL) {return false;} msousa@666: if (is_ANY_REAL (type_symbol)) {return true;} msousa@666: if (is_ANY_signed_INT(type_symbol)) {return true;} msousa@666: return false; msousa@666: } msousa@666: msousa@666: msousa@666: bool get_datatype_info_c::is_ANY_signed_SAFENUM(symbol_c *type_symbol) { msousa@666: if (type_symbol == NULL) {return false;} msousa@666: if (is_ANY_SAFEREAL (type_symbol)) {return true;} msousa@666: if (is_ANY_signed_SAFEINT(type_symbol)) {return true;} msousa@676: return false; msousa@666: } msousa@666: msousa@666: msousa@666: bool get_datatype_info_c::is_ANY_signed_NUM_compatible(symbol_c *type_symbol) { msousa@666: if (type_symbol == NULL) {return false;} msousa@666: if (is_ANY_signed_NUM (type_symbol)) {return true;} msousa@666: if (is_ANY_signed_SAFENUM(type_symbol)) {return true;} msousa@666: return false; msousa@666: } msousa@666: msousa@666: msousa@666: msousa@666: msousa@666: msousa@666: msousa@666: msousa@666: bool get_datatype_info_c::is_ANY_INT(symbol_c *type_symbol) { msousa@666: if (type_symbol == NULL) {return false;} msousa@666: if (is_ANY_signed_INT (type_symbol)) {return true;} msousa@666: if (is_ANY_unsigned_INT(type_symbol)) {return true;} msousa@666: return false; msousa@666: } msousa@666: msousa@666: msousa@666: bool get_datatype_info_c::is_ANY_SAFEINT(symbol_c *type_symbol) { msousa@666: if (type_symbol == NULL) {return false;} msousa@666: if (is_ANY_signed_SAFEINT (type_symbol)) {return true;} msousa@666: if (is_ANY_unsigned_SAFEINT(type_symbol)) {return true;} msousa@666: return false; msousa@666: } msousa@666: msousa@666: msousa@666: bool get_datatype_info_c::is_ANY_INT_compatible(symbol_c *type_symbol) { msousa@666: if (type_symbol == NULL) {return false;} msousa@666: if (is_ANY_INT (type_symbol)) {return true;} msousa@666: if (is_ANY_SAFEINT(type_symbol)) {return true;} msousa@666: return false; msousa@666: } msousa@666: msousa@666: msousa@666: msousa@666: msousa@666: msousa@666: msousa@666: bool get_datatype_info_c::is_ANY_signed_INT(symbol_c *type_symbol) { msousa@666: if (type_symbol == NULL) {return false;} msousa@666: if (typeid(*type_symbol) == typeid(sint_type_name_c)) {return true;} msousa@666: if (typeid(*type_symbol) == typeid(int_type_name_c)) {return true;} msousa@666: if (typeid(*type_symbol) == typeid(dint_type_name_c)) {return true;} msousa@666: if (typeid(*type_symbol) == typeid(lint_type_name_c)) {return true;} msousa@666: return false; msousa@666: } msousa@666: msousa@666: msousa@666: bool get_datatype_info_c::is_ANY_signed_SAFEINT(symbol_c *type_symbol) { msousa@666: if (type_symbol == NULL) {return false;} msousa@666: if (typeid(*type_symbol) == typeid(safesint_type_name_c)) {return true;} msousa@666: if (typeid(*type_symbol) == typeid(safeint_type_name_c)) {return true;} msousa@666: if (typeid(*type_symbol) == typeid(safedint_type_name_c)) {return true;} msousa@666: if (typeid(*type_symbol) == typeid(safelint_type_name_c)) {return true;} msousa@666: return false; msousa@666: } msousa@666: msousa@666: msousa@666: bool get_datatype_info_c::is_ANY_signed_INT_compatible(symbol_c *type_symbol) { msousa@666: if (type_symbol == NULL) {return false;} msousa@666: if (is_ANY_signed_INT (type_symbol)) {return true;} msousa@666: if (is_ANY_signed_SAFEINT(type_symbol)) {return true;} msousa@666: return false; msousa@666: } msousa@666: msousa@666: msousa@666: msousa@666: msousa@666: msousa@666: msousa@666: msousa@666: msousa@666: msousa@666: bool get_datatype_info_c::is_ANY_unsigned_INT(symbol_c *type_symbol) { msousa@666: if (type_symbol == NULL) {return false;} msousa@666: if (typeid(*type_symbol) == typeid(usint_type_name_c)) {return true;} msousa@666: if (typeid(*type_symbol) == typeid(uint_type_name_c)) {return true;} msousa@666: if (typeid(*type_symbol) == typeid(udint_type_name_c)) {return true;} msousa@666: if (typeid(*type_symbol) == typeid(ulint_type_name_c)) {return true;} msousa@666: return false; msousa@666: } msousa@666: msousa@666: msousa@666: bool get_datatype_info_c::is_ANY_unsigned_SAFEINT(symbol_c *type_symbol) { msousa@666: if (type_symbol == NULL) {return false;} msousa@666: if (typeid(*type_symbol) == typeid(safeusint_type_name_c)) {return true;} msousa@666: if (typeid(*type_symbol) == typeid(safeuint_type_name_c)) {return true;} msousa@666: if (typeid(*type_symbol) == typeid(safeudint_type_name_c)) {return true;} msousa@666: if (typeid(*type_symbol) == typeid(safeulint_type_name_c)) {return true;} msousa@666: return false; msousa@666: } msousa@666: msousa@666: msousa@666: bool get_datatype_info_c::is_ANY_unsigned_INT_compatible(symbol_c *type_symbol) { msousa@666: if (type_symbol == NULL) {return false;} msousa@666: if (is_ANY_unsigned_INT (type_symbol)) {return true;} msousa@666: if (is_ANY_unsigned_SAFEINT(type_symbol)) {return true;} msousa@666: return false; msousa@666: } msousa@666: msousa@666: msousa@666: msousa@666: msousa@666: msousa@666: msousa@666: msousa@666: msousa@666: bool get_datatype_info_c::is_ANY_REAL(symbol_c *type_symbol) { msousa@666: if (type_symbol == NULL) {return false;} msousa@666: if (typeid(*type_symbol) == typeid(real_type_name_c)) {return true;} msousa@666: if (typeid(*type_symbol) == typeid(lreal_type_name_c)) {return true;} msousa@666: return false; msousa@666: } msousa@666: msousa@666: msousa@666: bool get_datatype_info_c::is_ANY_SAFEREAL(symbol_c *type_symbol) { msousa@666: if (type_symbol == NULL) {return false;} msousa@666: if (typeid(*type_symbol) == typeid(safereal_type_name_c)) {return true;} msousa@666: if (typeid(*type_symbol) == typeid(safelreal_type_name_c)) {return true;} msousa@666: return false; msousa@666: } msousa@666: msousa@666: msousa@666: bool get_datatype_info_c::is_ANY_REAL_compatible(symbol_c *type_symbol) { msousa@666: if (type_symbol == NULL) {return false;} msousa@666: if (is_ANY_REAL (type_symbol)) {return true;} msousa@666: if (is_ANY_SAFEREAL(type_symbol)) {return true;} msousa@666: return false; msousa@666: } msousa@666: msousa@666: msousa@666: msousa@666: msousa@666: msousa@666: msousa@666: msousa@666: msousa@666: bool get_datatype_info_c::is_ANY_nBIT(symbol_c *type_symbol) { msousa@666: if (type_symbol == NULL) {return false;} msousa@666: if (typeid(*type_symbol) == typeid(byte_type_name_c)) {return true;} msousa@666: if (typeid(*type_symbol) == typeid(word_type_name_c)) {return true;} msousa@666: if (typeid(*type_symbol) == typeid(dword_type_name_c)) {return true;} msousa@666: if (typeid(*type_symbol) == typeid(lword_type_name_c)) {return true;} msousa@666: return false; msousa@666: } msousa@666: msousa@666: msousa@666: bool get_datatype_info_c::is_ANY_SAFEnBIT(symbol_c *type_symbol) { msousa@666: if (type_symbol == NULL) {return false;} msousa@666: if (typeid(*type_symbol) == typeid(safebyte_type_name_c)) {return true;} msousa@666: if (typeid(*type_symbol) == typeid(safeword_type_name_c)) {return true;} msousa@666: if (typeid(*type_symbol) == typeid(safedword_type_name_c)) {return true;} msousa@666: if (typeid(*type_symbol) == typeid(safelword_type_name_c)) {return true;} msousa@666: return false; msousa@666: } msousa@666: msousa@666: msousa@666: bool get_datatype_info_c::is_ANY_nBIT_compatible(symbol_c *type_symbol) { msousa@666: if (type_symbol == NULL) {return false;} msousa@666: if (is_ANY_nBIT (type_symbol)) {return true;} msousa@666: if (is_ANY_SAFEnBIT(type_symbol)) {return true;} msousa@666: return false; msousa@666: } msousa@666: msousa@666: msousa@666: msousa@666: msousa@666: msousa@666: msousa@666: msousa@666: msousa@666: msousa@666: msousa@666: bool get_datatype_info_c::is_BOOL(symbol_c *type_symbol) { msousa@666: if (type_symbol == NULL) {return false;} msousa@666: if (typeid(*type_symbol) == typeid(bool_type_name_c)) {return true;} msousa@666: return false; msousa@666: } msousa@666: msousa@666: msousa@666: bool get_datatype_info_c::is_SAFEBOOL(symbol_c *type_symbol) { msousa@666: if (type_symbol == NULL) {return false;} msousa@666: if (typeid(*type_symbol) == typeid(safebool_type_name_c)) {return true;} msousa@666: return false; msousa@666: } msousa@666: msousa@666: msousa@666: bool get_datatype_info_c::is_BOOL_compatible(symbol_c *type_symbol) { msousa@666: if (type_symbol == NULL) {return false;} msousa@666: if (is_BOOL (type_symbol)) {return true;} msousa@666: if (is_SAFEBOOL(type_symbol)) {return true;} msousa@666: return false; msousa@666: } msousa@666: msousa@666: msousa@666: msousa@666: msousa@666: msousa@666: msousa@666: msousa@666: msousa@666: msousa@666: bool get_datatype_info_c::is_ANY_BIT(symbol_c *type_symbol) { msousa@666: if (type_symbol == NULL) {return false;} msousa@666: if (is_BOOL (type_symbol)) {return true;} msousa@666: if (is_ANY_nBIT(type_symbol)) {return true;} msousa@666: return false; msousa@666: } msousa@666: msousa@666: msousa@666: bool get_datatype_info_c::is_ANY_SAFEBIT(symbol_c *type_symbol) { msousa@666: if (type_symbol == NULL) {return false;} msousa@666: if (is_SAFEBOOL (type_symbol)) {return true;} msousa@666: if (is_ANY_SAFEnBIT(type_symbol)) {return true;} msousa@666: return false; msousa@666: } msousa@666: msousa@666: msousa@666: bool get_datatype_info_c::is_ANY_BIT_compatible(symbol_c *type_symbol) { msousa@666: if (type_symbol == NULL) {return false;} msousa@666: if (is_ANY_BIT (type_symbol)) {return true;} msousa@666: if (is_ANY_SAFEBIT(type_symbol)) {return true;} msousa@666: return false; msousa@666: } msousa@666: msousa@666: msousa@666: msousa@668: msousa@668: msousa@668: msousa@668: msousa@668: msousa@668: bool get_datatype_info_c::is_TIME(symbol_c *type_symbol) { msousa@668: if (type_symbol == NULL) {return false;} msousa@668: if (typeid(*type_symbol) == typeid(time_type_name_c)) {return true;} msousa@668: return false; msousa@668: } msousa@668: msousa@668: msousa@668: bool get_datatype_info_c::is_SAFETIME(symbol_c *type_symbol) { msousa@668: if (type_symbol == NULL) {return false;} msousa@668: if (typeid(*type_symbol) == typeid(safetime_type_name_c)) {return true;} msousa@668: return false; msousa@668: } msousa@668: msousa@668: msousa@668: bool get_datatype_info_c::is_TIME_compatible(symbol_c *type_symbol) { msousa@668: if (type_symbol == NULL) {return false;} msousa@668: if (is_TIME (type_symbol)) {return true;} msousa@668: if (is_SAFETIME(type_symbol)) {return true;} msousa@668: return false; msousa@668: } msousa@668: msousa@668: msousa@668: msousa@668: msousa@668: msousa@668: msousa@668: msousa@668: msousa@668: bool get_datatype_info_c::is_ANY_DATE(symbol_c *type_symbol) { msousa@668: if (type_symbol == NULL) {return false;} msousa@668: if (typeid(*type_symbol) == typeid(date_type_name_c)) {return true;} msousa@668: if (typeid(*type_symbol) == typeid(tod_type_name_c)) {return true;} msousa@668: if (typeid(*type_symbol) == typeid(dt_type_name_c)) {return true;} msousa@668: return false; msousa@668: } msousa@668: msousa@668: msousa@668: bool get_datatype_info_c::is_ANY_SAFEDATE(symbol_c *type_symbol) { msousa@668: if (type_symbol == NULL) {return false;} msousa@668: if (typeid(*type_symbol) == typeid(safedate_type_name_c)) {return true;} msousa@668: if (typeid(*type_symbol) == typeid(safetod_type_name_c)) {return true;} msousa@668: if (typeid(*type_symbol) == typeid(safedt_type_name_c)) {return true;} msousa@668: return false; msousa@668: } msousa@668: msousa@668: msousa@668: bool get_datatype_info_c::is_ANY_DATE_compatible(symbol_c *type_symbol) { msousa@668: if (type_symbol == NULL) {return false;} msousa@668: if (is_ANY_DATE (type_symbol)) {return true;} msousa@668: if (is_ANY_SAFEDATE(type_symbol)) {return true;} msousa@668: return false; msousa@668: } msousa@668: msousa@668: msousa@668: msousa@668: msousa@668: msousa@668: msousa@668: msousa@668: msousa@668: msousa@668: msousa@668: msousa@668: bool get_datatype_info_c::is_ANY_STRING(symbol_c *type_symbol) { msousa@668: if (type_symbol == NULL) {return false;} msousa@668: if (typeid(*type_symbol) == typeid(string_type_name_c)) {return true;} msousa@668: if (typeid(*type_symbol) == typeid(wstring_type_name_c)) {return true;} msousa@668: return false; msousa@668: } msousa@668: msousa@668: msousa@668: bool get_datatype_info_c::is_ANY_SAFESTRING(symbol_c *type_symbol) { msousa@668: if (type_symbol == NULL) {return false;} msousa@668: if (typeid(*type_symbol) == typeid(safestring_type_name_c)) {return true;} msousa@668: if (typeid(*type_symbol) == typeid(safewstring_type_name_c)) {return true;} msousa@668: return false; msousa@668: } msousa@668: msousa@668: msousa@668: bool get_datatype_info_c::is_ANY_STRING_compatible(symbol_c *type_symbol) { msousa@668: if (type_symbol == NULL) {return false;} msousa@668: if (is_ANY_STRING (type_symbol)) {return true;} msousa@668: if (is_ANY_SAFESTRING(type_symbol)) {return true;} msousa@668: return false; msousa@668: } msousa@668: msousa@668: msousa@668: msousa@668: msousa@668: msousa@668: msousa@668: msousa@668: /* Can't we do away with this?? */ msousa@668: bool get_datatype_info_c::is_ANY_REAL_literal(symbol_c *type_symbol) { msousa@668: if (type_symbol == NULL) {return true;} /* Please make sure things will work correctly before changing this to false!! */ msousa@668: if (typeid(*type_symbol) == typeid(real_c)) {return true;} msousa@668: if (typeid(*type_symbol) == typeid(neg_real_c)) {return true;} msousa@668: return false; msousa@668: } msousa@668: msousa@668: /* Can't we do away with this?? */ msousa@668: bool get_datatype_info_c::is_ANY_INT_literal(symbol_c *type_symbol) { msousa@668: if (type_symbol == NULL) {return true;} /* Please make sure things will work correctly before changing this to false!! */ msousa@668: if (typeid(*type_symbol) == typeid(integer_c)) {return true;} msousa@668: if (typeid(*type_symbol) == typeid(neg_integer_c)) {return true;} msousa@668: if (typeid(*type_symbol) == typeid(binary_integer_c)) {return true;} msousa@668: if (typeid(*type_symbol) == typeid(octal_integer_c)) {return true;} msousa@668: if (typeid(*type_symbol) == typeid(hex_integer_c)) {return true;} msousa@668: return false; msousa@668: } msousa@668: msousa@693: msousa@693: msousa@693: msousa@693: msousa@693: msousa@693: msousa@693: msousa@693: msousa@693: msousa@693: invalid_type_name_c get_datatype_info_c::invalid_type_name; msousa@693: msousa@693: /**********************/ msousa@693: /* B.1.3 - Data types */ msousa@693: /**********************/ msousa@693: /***********************************/ msousa@693: /* B 1.3.1 - Elementary Data Types */ msousa@693: /***********************************/ msousa@699: lreal_type_name_c get_datatype_info_c::lreal_type_name; msousa@693: real_type_name_c get_datatype_info_c::real_type_name; msousa@693: msousa@693: lint_type_name_c get_datatype_info_c::lint_type_name; msousa@693: dint_type_name_c get_datatype_info_c::dint_type_name; msousa@693: int_type_name_c get_datatype_info_c::int_type_name; msousa@693: sint_type_name_c get_datatype_info_c::sint_type_name; msousa@693: msousa@693: ulint_type_name_c get_datatype_info_c::ulint_type_name; msousa@693: udint_type_name_c get_datatype_info_c::udint_type_name; msousa@693: uint_type_name_c get_datatype_info_c::uint_type_name; msousa@693: usint_type_name_c get_datatype_info_c::usint_type_name; msousa@693: msousa@693: lword_type_name_c get_datatype_info_c::lword_type_name; msousa@693: dword_type_name_c get_datatype_info_c::dword_type_name; msousa@693: word_type_name_c get_datatype_info_c::word_type_name; msousa@693: byte_type_name_c get_datatype_info_c::byte_type_name; msousa@693: bool_type_name_c get_datatype_info_c::bool_type_name; msousa@693: msousa@693: wstring_type_name_c get_datatype_info_c::wstring_type_name; msousa@693: string_type_name_c get_datatype_info_c::string_type_name; msousa@693: msousa@693: dt_type_name_c get_datatype_info_c::dt_type_name; msousa@693: date_type_name_c get_datatype_info_c::date_type_name; msousa@693: tod_type_name_c get_datatype_info_c::tod_type_name; msousa@693: time_type_name_c get_datatype_info_c::time_type_name; msousa@693: msousa@693: msousa@693: /******************************************************/ msousa@693: /* Extensions to the base standard as defined in */ msousa@693: /* "Safety Software Technical Specification, */ msousa@693: /* Part 1: Concepts and Function Blocks, */ msousa@693: /* Version 1.0 – Official Release" */ msousa@693: /* by PLCopen - Technical Committee 5 - 2006-01-31 */ msousa@693: /******************************************************/ msousa@699: safelreal_type_name_c get_datatype_info_c::safelreal_type_name; msousa@693: safereal_type_name_c get_datatype_info_c::safereal_type_name; msousa@693: msousa@693: safelint_type_name_c get_datatype_info_c::safelint_type_name; msousa@693: safedint_type_name_c get_datatype_info_c::safedint_type_name; msousa@693: safeint_type_name_c get_datatype_info_c::safeint_type_name; msousa@693: safesint_type_name_c get_datatype_info_c::safesint_type_name; msousa@693: msousa@693: safeulint_type_name_c get_datatype_info_c::safeulint_type_name; msousa@693: safeudint_type_name_c get_datatype_info_c::safeudint_type_name; msousa@693: safeuint_type_name_c get_datatype_info_c::safeuint_type_name; msousa@693: safeusint_type_name_c get_datatype_info_c::safeusint_type_name; msousa@693: msousa@693: safelword_type_name_c get_datatype_info_c::safelword_type_name; msousa@693: safedword_type_name_c get_datatype_info_c::safedword_type_name; msousa@693: safeword_type_name_c get_datatype_info_c::safeword_type_name; msousa@693: safebyte_type_name_c get_datatype_info_c::safebyte_type_name; msousa@693: safebool_type_name_c get_datatype_info_c::safebool_type_name; msousa@693: msousa@693: safewstring_type_name_c get_datatype_info_c::safewstring_type_name; msousa@693: safestring_type_name_c get_datatype_info_c::safestring_type_name; msousa@693: msousa@693: safedt_type_name_c get_datatype_info_c::safedt_type_name; msousa@693: safedate_type_name_c get_datatype_info_c::safedate_type_name; msousa@693: safetod_type_name_c get_datatype_info_c::safetod_type_name; msousa@693: safetime_type_name_c get_datatype_info_c::safetime_type_name; msousa@693: msousa@693: msousa@693: msousa@693: msousa@693: