diff -r 50fca2d3abd9 -r 8ba9ec4bae50 absyntax_utils/get_datatype_info.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/absyntax_utils/get_datatype_info.cc Thu Oct 04 14:30:51 2012 +0100 @@ -0,0 +1,583 @@ +/* + * matiec - a compiler for the programming languages defined in IEC 61131-3 + * + * Copyright (C) 2003-2012 Mario de Sousa (msousa@fe.up.pt) + * Copyright (C) 2007-2011 Laurent Bessard and Edouard Tisserant + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * + * This code is made available on the understanding that it will not be + * used in safety-critical situations without a full and competent review. + */ + +/* + * An IEC 61131-3 compiler. + * + * Based on the + * FINAL DRAFT - IEC 61131-3, 2nd Ed. (2001-12-10) + * + */ + +/* Determine the characteristics of a specific data type + * e.g., is it an enumeration, is it an array, is it ANY_INT, etc... + * + * The methods of this class may be passed either: + * - a data type declaration symbol_c, + * OR + * - the name of a data type (identifier_c) + * In this case, we shall first serach for the basetype declaration using search_base_type_c, and then + * run the normal process. + */ +#include "absyntax_utils.hh" + +#include "../main.hh" // required for ERROR() and ERROR_MSG() macros. + + + +#include // required for typeid + + + + + + +static search_base_type_c search_base_type; + + + + +bool get_datatype_info_c::is_sfc_initstep(symbol_c *type_symbol) { + symbol_c *type_decl = search_base_type.get_basetype_decl(type_symbol); + if (typeid(*type_decl) == typeid(initial_step_c)) {return true;} /* INITIAL_STEP step_name ':' action_association_list END_STEP */ /* A pseudo data type! */ + return false; +} + + + + + +bool get_datatype_info_c::is_sfc_step(symbol_c *type_symbol) { + symbol_c *type_decl = search_base_type.get_basetype_decl(type_symbol); + if (typeid(*type_decl) == typeid(initial_step_c)) {return true;} /* INITIAL_STEP step_name ':' action_association_list END_STEP */ /* A pseudo data type! */ + if (typeid(*type_decl) == typeid( step_c)) {return true;} /* STEP step_name ':' action_association_list END_STEP */ /* A pseudo data type! */ + return false; +} + + + + +bool get_datatype_info_c::is_function_block(symbol_c *type_symbol) { + symbol_c *type_decl = search_base_type.get_basetype_decl(type_symbol); + 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 */ + return false; +} + + + + + +bool get_datatype_info_c::is_subrange(symbol_c *type_symbol) { + symbol_c *type_decl = search_base_type.get_basetype_decl(type_symbol); /* NOTE: will work correctly once we update the way search_base_type_c works, by adding a new search_effective_type:c */ + + if (typeid(*type_decl) == typeid(subrange_type_declaration_c)) {return true;} /* subrange_type_name ':' subrange_spec_init */ + if (typeid(*type_decl) == typeid(subrange_spec_init_c)) {return true;} /* subrange_specification ASSIGN signed_integer */ + if (typeid(*type_decl) == typeid(subrange_specification_c)) {return true;} /* integer_type_name '(' subrange')' */ + + if (typeid(*type_decl) == typeid(subrange_c)) {ERROR;} /* signed_integer DOTDOT signed_integer */ + return false; +} + + + + + +bool get_datatype_info_c::is_enumerated(symbol_c *type_symbol) { + symbol_c *type_decl = search_base_type.get_basetype_decl(type_symbol); + + if (typeid(*type_decl) == typeid(enumerated_type_declaration_c)) {return true;} /* enumerated_type_name ':' enumerated_spec_init */ + if (typeid(*type_decl) == typeid(enumerated_spec_init_c)) {return true;} /* enumerated_specification ASSIGN enumerated_value */ + 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! */ + + if (typeid(*type_decl) == typeid(enumerated_value_c)) {ERROR;} /* enumerated_type_name '#' identifier */ + return false; +} + + + + + +bool get_datatype_info_c::is_array(symbol_c *type_symbol) { + symbol_c *type_decl = search_base_type.get_basetype_decl(type_symbol); + + if (typeid(*type_decl) == typeid(array_type_declaration_c)) {return true;} /* identifier ':' array_spec_init */ + if (typeid(*type_decl) == typeid(array_spec_init_c)) {return true;} /* array_specification [ASSIGN array_initialization} */ + if (typeid(*type_decl) == typeid(array_specification_c)) {return true;} /* ARRAY '[' array_subrange_list ']' OF non_generic_type_name */ + + if (typeid(*type_decl) == typeid(array_subrange_list_c)) {ERROR;} /* array_subrange_list ',' subrange */ + if (typeid(*type_decl) == typeid(array_initial_elements_list_c)) {ERROR;} /* array_initialization: '[' array_initial_elements_list ']' */ /* array_initial_elements_list ',' array_initial_elements */ + if (typeid(*type_decl) == typeid(array_initial_elements_c)) {ERROR;} /* integer '(' [array_initial_element] ')' */ + return false; +} + + + + + +bool get_datatype_info_c::is_structure(symbol_c *type_symbol) { + symbol_c *type_decl = search_base_type.get_basetype_decl(type_symbol); + + if (typeid(*type_decl) == typeid(structure_type_declaration_c)) {return true;} /* structure_type_name ':' structure_specification */ + if (typeid(*type_decl) == typeid(initialized_structure_c)) {return true;} /* structure_type_name ASSIGN structure_initialization */ + 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 ';' */ + + if (typeid(*type_decl) == typeid(structure_element_declaration_c)) {ERROR;} /* structure_element_name ':' *_spec_init */ + if (typeid(*type_decl) == typeid(structure_element_initialization_list_c)) {ERROR;} /* structure_initialization: '(' structure_element_initialization_list ')' */ /* structure_element_initialization_list ',' structure_element_initialization */ + if (typeid(*type_decl) == typeid(structure_element_initialization_c)) {ERROR;} /* structure_element_name ASSIGN value */ + return false; +} + + + + + + + + + + +bool get_datatype_info_c::is_ANY_ELEMENTARY(symbol_c *type_symbol) { + if (type_symbol == NULL) {return false;} + if (is_ANY_MAGNITUDE(type_symbol)) {return true;} + if (is_ANY_BIT (type_symbol)) {return true;} + if (is_ANY_STRING (type_symbol)) {return true;} + if (is_ANY_DATE (type_symbol)) {return true;} + return false; +} + + +bool get_datatype_info_c::is_ANY_SAFEELEMENTARY(symbol_c *type_symbol) { + if (type_symbol == NULL) {return false;} + if (is_ANY_SAFEMAGNITUDE(type_symbol)) {return true;} + if (is_ANY_SAFEBIT (type_symbol)) {return true;} + if (is_ANY_SAFESTRING (type_symbol)) {return true;} + if (is_ANY_SAFEDATE (type_symbol)) {return true;} + return false; +} + + +bool get_datatype_info_c::is_ANY_ELEMENTARY_compatible(symbol_c *type_symbol) { + if (type_symbol == NULL) {return false;} + if (is_ANY_ELEMENTARY (type_symbol)) {return true;} + if (is_ANY_SAFEELEMENTARY(type_symbol)) {return true;} + return false; +} + + + + + + + +bool get_datatype_info_c::is_ANY_MAGNITUDE(symbol_c *type_symbol) { + if (type_symbol == NULL) {return false;} + if (typeid(*type_symbol) == typeid(time_type_name_c)) {return true;} + if (is_ANY_NUM(type_symbol)) {return true;} + return false; +} + + +bool get_datatype_info_c::is_ANY_SAFEMAGNITUDE(symbol_c *type_symbol) { + if (type_symbol == NULL) {return false;} + if (typeid(*type_symbol) == typeid(safetime_type_name_c)) {return true;} + if (is_ANY_SAFENUM(type_symbol)) {return true;} + return false; +} + + +bool get_datatype_info_c::is_ANY_MAGNITUDE_compatible(symbol_c *type_symbol) { + if (type_symbol == NULL) {return false;} + if (is_ANY_MAGNITUDE (type_symbol)) {return true;} + if (is_ANY_SAFEMAGNITUDE(type_symbol)) {return true;} + return false; +} + + + + + + + +bool get_datatype_info_c::is_ANY_signed_MAGNITUDE(symbol_c *type_symbol) { + if (type_symbol == NULL) {return false;} + if (typeid(*type_symbol) == typeid(time_type_name_c)) {return true;} + if (is_ANY_signed_NUM(type_symbol)) {return true;} + return false; +} + + +bool get_datatype_info_c::is_ANY_signed_SAFEMAGNITUDE(symbol_c *type_symbol) { + if (type_symbol == NULL) {return false;} + if (typeid(*type_symbol) == typeid(safetime_type_name_c)) {return true;} + return is_ANY_signed_SAFENUM(type_symbol); +} + + +bool get_datatype_info_c::is_ANY_signed_MAGNITUDE_compatible(symbol_c *type_symbol) { + if (type_symbol == NULL) {return false;} + if (is_ANY_signed_MAGNITUDE (type_symbol)) {return true;} + if (is_ANY_signed_SAFEMAGNITUDE(type_symbol)) {return true;} + return false; +} + + + + + + + +bool get_datatype_info_c::is_ANY_NUM(symbol_c *type_symbol) { + if (type_symbol == NULL) {return false;} + if (is_ANY_REAL(type_symbol)) {return true;} + if (is_ANY_INT (type_symbol)) {return true;} + return false; +} + + +bool get_datatype_info_c::is_ANY_SAFENUM(symbol_c *type_symbol) { + if (type_symbol == NULL) {return false;} + if (is_ANY_SAFEREAL(type_symbol)) {return true;} + if (is_ANY_SAFEINT (type_symbol)) {return true;} +} + + +bool get_datatype_info_c::is_ANY_NUM_compatible(symbol_c *type_symbol) { + if (type_symbol == NULL) {return false;} + if (is_ANY_NUM (type_symbol)) {return true;} + if (is_ANY_SAFENUM(type_symbol)) {return true;} + return false; +} + + + + + + + +bool get_datatype_info_c::is_ANY_signed_NUM(symbol_c *type_symbol) { + if (type_symbol == NULL) {return false;} + if (is_ANY_REAL (type_symbol)) {return true;} + if (is_ANY_signed_INT(type_symbol)) {return true;} + return false; +} + + +bool get_datatype_info_c::is_ANY_signed_SAFENUM(symbol_c *type_symbol) { + if (type_symbol == NULL) {return false;} + if (is_ANY_SAFEREAL (type_symbol)) {return true;} + if (is_ANY_signed_SAFEINT(type_symbol)) {return true;} +} + + +bool get_datatype_info_c::is_ANY_signed_NUM_compatible(symbol_c *type_symbol) { + if (type_symbol == NULL) {return false;} + if (is_ANY_signed_NUM (type_symbol)) {return true;} + if (is_ANY_signed_SAFENUM(type_symbol)) {return true;} + return false; +} + + + + + + + +bool get_datatype_info_c::is_ANY_DATE(symbol_c *type_symbol) { + if (type_symbol == NULL) {return false;} + if (typeid(*type_symbol) == typeid(date_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(tod_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(dt_type_name_c)) {return true;} + return false; +} + + +bool get_datatype_info_c::is_ANY_SAFEDATE(symbol_c *type_symbol) { + if (type_symbol == NULL) {return false;} + if (typeid(*type_symbol) == typeid(safedate_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(safetod_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(safedt_type_name_c)) {return true;} + return false; +} + + +bool get_datatype_info_c::is_ANY_DATE_compatible(symbol_c *type_symbol) { + if (type_symbol == NULL) {return false;} + if (is_ANY_DATE (type_symbol)) {return true;} + if (is_ANY_SAFEDATE(type_symbol)) {return true;} + return false; +} + + + + + + + +bool get_datatype_info_c::is_ANY_STRING(symbol_c *type_symbol) { + if (type_symbol == NULL) {return false;} + if (typeid(*type_symbol) == typeid(string_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(wstring_type_name_c)) {return true;} + return false; +} + + +bool get_datatype_info_c::is_ANY_SAFESTRING(symbol_c *type_symbol) { + if (type_symbol == NULL) {return false;} + if (typeid(*type_symbol) == typeid(safestring_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(safewstring_type_name_c)) {return true;} + return false; +} + + +bool get_datatype_info_c::is_ANY_STRING_compatible(symbol_c *type_symbol) { + if (type_symbol == NULL) {return false;} + if (is_ANY_STRING (type_symbol)) {return true;} + if (is_ANY_SAFESTRING(type_symbol)) {return true;} + return false; +} + + + + + + + +bool get_datatype_info_c::is_ANY_INT(symbol_c *type_symbol) { + if (type_symbol == NULL) {return false;} + if (is_ANY_signed_INT (type_symbol)) {return true;} + if (is_ANY_unsigned_INT(type_symbol)) {return true;} + return false; +} + + +bool get_datatype_info_c::is_ANY_SAFEINT(symbol_c *type_symbol) { + if (type_symbol == NULL) {return false;} + if (is_ANY_signed_SAFEINT (type_symbol)) {return true;} + if (is_ANY_unsigned_SAFEINT(type_symbol)) {return true;} + return false; +} + + +bool get_datatype_info_c::is_ANY_INT_compatible(symbol_c *type_symbol) { + if (type_symbol == NULL) {return false;} + if (is_ANY_INT (type_symbol)) {return true;} + if (is_ANY_SAFEINT(type_symbol)) {return true;} + return false; +} + + + + + + +bool get_datatype_info_c::is_ANY_signed_INT(symbol_c *type_symbol) { + if (type_symbol == NULL) {return false;} + if (typeid(*type_symbol) == typeid(sint_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(int_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(dint_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(lint_type_name_c)) {return true;} + return false; +} + + +bool get_datatype_info_c::is_ANY_signed_SAFEINT(symbol_c *type_symbol) { + if (type_symbol == NULL) {return false;} + if (typeid(*type_symbol) == typeid(safesint_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(safeint_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(safedint_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(safelint_type_name_c)) {return true;} + return false; +} + + +bool get_datatype_info_c::is_ANY_signed_INT_compatible(symbol_c *type_symbol) { + if (type_symbol == NULL) {return false;} + if (is_ANY_signed_INT (type_symbol)) {return true;} + if (is_ANY_signed_SAFEINT(type_symbol)) {return true;} + return false; +} + + + + + + + + + +bool get_datatype_info_c::is_ANY_unsigned_INT(symbol_c *type_symbol) { + if (type_symbol == NULL) {return false;} + if (typeid(*type_symbol) == typeid(usint_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(uint_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(udint_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(ulint_type_name_c)) {return true;} + return false; +} + + +bool get_datatype_info_c::is_ANY_unsigned_SAFEINT(symbol_c *type_symbol) { + if (type_symbol == NULL) {return false;} + if (typeid(*type_symbol) == typeid(safeusint_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(safeuint_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(safeudint_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(safeulint_type_name_c)) {return true;} + return false; +} + + +bool get_datatype_info_c::is_ANY_unsigned_INT_compatible(symbol_c *type_symbol) { + if (type_symbol == NULL) {return false;} + if (is_ANY_unsigned_INT (type_symbol)) {return true;} + if (is_ANY_unsigned_SAFEINT(type_symbol)) {return true;} + return false; +} + + + + + + + + + +bool get_datatype_info_c::is_ANY_REAL(symbol_c *type_symbol) { + if (type_symbol == NULL) {return false;} + if (typeid(*type_symbol) == typeid(real_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(lreal_type_name_c)) {return true;} + return false; +} + + +bool get_datatype_info_c::is_ANY_SAFEREAL(symbol_c *type_symbol) { + if (type_symbol == NULL) {return false;} + if (typeid(*type_symbol) == typeid(safereal_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(safelreal_type_name_c)) {return true;} + return false; +} + + +bool get_datatype_info_c::is_ANY_REAL_compatible(symbol_c *type_symbol) { + if (type_symbol == NULL) {return false;} + if (is_ANY_REAL (type_symbol)) {return true;} + if (is_ANY_SAFEREAL(type_symbol)) {return true;} + return false; +} + + + + + + + + +bool get_datatype_info_c::is_ANY_nBIT(symbol_c *type_symbol) { + if (type_symbol == NULL) {return false;} + if (typeid(*type_symbol) == typeid(byte_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(word_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(dword_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(lword_type_name_c)) {return true;} + return false; +} + + +bool get_datatype_info_c::is_ANY_SAFEnBIT(symbol_c *type_symbol) { + if (type_symbol == NULL) {return false;} + if (typeid(*type_symbol) == typeid(safebyte_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(safeword_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(safedword_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(safelword_type_name_c)) {return true;} + return false; +} + + +bool get_datatype_info_c::is_ANY_nBIT_compatible(symbol_c *type_symbol) { + if (type_symbol == NULL) {return false;} + if (is_ANY_nBIT (type_symbol)) {return true;} + if (is_ANY_SAFEnBIT(type_symbol)) {return true;} + return false; +} + + + + + + + + + + +bool get_datatype_info_c::is_BOOL(symbol_c *type_symbol) { + if (type_symbol == NULL) {return false;} + if (typeid(*type_symbol) == typeid(bool_type_name_c)) {return true;} + return false; +} + + +bool get_datatype_info_c::is_SAFEBOOL(symbol_c *type_symbol) { + if (type_symbol == NULL) {return false;} + if (typeid(*type_symbol) == typeid(safebool_type_name_c)) {return true;} + return false; +} + + +bool get_datatype_info_c::is_BOOL_compatible(symbol_c *type_symbol) { + if (type_symbol == NULL) {return false;} + if (is_BOOL (type_symbol)) {return true;} + if (is_SAFEBOOL(type_symbol)) {return true;} + return false; +} + + + + + + + + + +bool get_datatype_info_c::is_ANY_BIT(symbol_c *type_symbol) { + if (type_symbol == NULL) {return false;} + if (is_BOOL (type_symbol)) {return true;} + if (is_ANY_nBIT(type_symbol)) {return true;} + return false; +} + + +bool get_datatype_info_c::is_ANY_SAFEBIT(symbol_c *type_symbol) { + if (type_symbol == NULL) {return false;} + if (is_SAFEBOOL (type_symbol)) {return true;} + if (is_ANY_SAFEnBIT(type_symbol)) {return true;} + return false; +} + + +bool get_datatype_info_c::is_ANY_BIT_compatible(symbol_c *type_symbol) { + if (type_symbol == NULL) {return false;} + if (is_ANY_BIT (type_symbol)) {return true;} + if (is_ANY_SAFEBIT(type_symbol)) {return true;} + return false; +} + + +