absyntax_utils/search_expression_type.cc
changeset 671 d28c7ebaca21
parent 670 400bf52a2691
child 672 dee28c5bdc73
equal deleted inserted replaced
670:400bf52a2691 671:d28c7ebaca21
     1 /*
       
     2  *  matiec - a compiler for the programming languages defined in IEC 61131-3
       
     3  *
       
     4  *  Copyright (C) 2003-2011  Mario de Sousa (msousa@fe.up.pt)
       
     5  *  Copyright (C) 2007-2011  Laurent Bessard and Edouard Tisserant
       
     6  *
       
     7  *  This program is free software: you can redistribute it and/or modify
       
     8  *  it under the terms of the GNU General Public License as published by
       
     9  *  the Free Software Foundation, either version 3 of the License, or
       
    10  *  (at your option) any later version.
       
    11  *
       
    12  *  This program is distributed in the hope that it will be useful,
       
    13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
    15  *  GNU General Public License for more details.
       
    16  *
       
    17  *  You should have received a copy of the GNU General Public License
       
    18  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
       
    19  *
       
    20  *
       
    21  * This code is made available on the understanding that it will not be
       
    22  * used in safety-critical situations without a full and competent review.
       
    23  */
       
    24 
       
    25 /*
       
    26  * An IEC 61131-3 compiler.
       
    27  *
       
    28  * Based on the
       
    29  * FINAL DRAFT - IEC 61131-3, 2nd Ed. (2001-12-10)
       
    30  *
       
    31  */
       
    32 
       
    33 
       
    34 /* Determine the data type of an ST expression.
       
    35  * A reference to the relevant type definition is returned.
       
    36  *
       
    37  * For example:
       
    38  *       2 + 3       -> returns reference to a int_type_name_c object.
       
    39  *       22.2 - 5    -> returns reference to a real_type_name_c object.
       
    40  *       etc...
       
    41  */
       
    42 
       
    43 
       
    44 
       
    45 #include "absyntax_utils.hh"
       
    46 #include <typeinfo>
       
    47 
       
    48 search_expression_type_c::search_expression_type_c(symbol_c *search_scope) {
       
    49   search_varfb_instance_type = new search_varfb_instance_type_c(search_scope);
       
    50 }
       
    51 
       
    52 search_expression_type_c::~search_expression_type_c(void) {
       
    53   delete search_varfb_instance_type;
       
    54 }
       
    55 
       
    56 /* A helper function... */
       
    57 bool search_expression_type_c::is_bool_type(symbol_c *type_symbol) {
       
    58   bool_type_name_c tt;
       
    59   if (type_symbol == NULL) {return true;}
       
    60   if (typeid(*type_symbol) == typeid(safebool_type_name_c)) {return true;}
       
    61   if (typeid(*type_symbol) == typeid(bool_type_name_c))     {return true;}
       
    62   if (typeid(*type_symbol) == typeid(boolean_true_c))       {return true;}
       
    63   if (typeid(*type_symbol) == typeid(boolean_false_c))      {return true;}
       
    64   return false;
       
    65 }
       
    66 
       
    67 /* A helper function... */
       
    68 bool search_expression_type_c::is_time_type(symbol_c *type_symbol) {
       
    69   if (type_symbol == NULL) {return true;}
       
    70   if (typeid(*type_symbol) == typeid(time_type_name_c))     {return true;}
       
    71   if (typeid(*type_symbol) == typeid(date_type_name_c))     {return true;}
       
    72   if (typeid(*type_symbol) == typeid(tod_type_name_c))      {return true;}
       
    73   if (typeid(*type_symbol) == typeid(dt_type_name_c))       {return true;}
       
    74   if (typeid(*type_symbol) == typeid(safetime_type_name_c)) {return true;}
       
    75   if (typeid(*type_symbol) == typeid(safedate_type_name_c)) {return true;}
       
    76   if (typeid(*type_symbol) == typeid(safetod_type_name_c))  {return true;}
       
    77   if (typeid(*type_symbol) == typeid(safedt_type_name_c))   {return true;}
       
    78   return false;
       
    79 }
       
    80 
       
    81 /* A helper function... */
       
    82 bool search_expression_type_c::is_string_type(symbol_c *type_symbol) {
       
    83   if (type_symbol == NULL) {return true;}
       
    84   if (typeid(*type_symbol) == typeid(string_type_name_c))      {return true;}
       
    85   if (typeid(*type_symbol) == typeid(wstring_type_name_c))     {return true;}
       
    86   if (typeid(*type_symbol) == typeid(safestring_type_name_c))  {return true;}
       
    87   if (typeid(*type_symbol) == typeid(safewstring_type_name_c)) {return true;}
       
    88   return false;
       
    89 }
       
    90 
       
    91 /* A helper function... */
       
    92 bool search_expression_type_c::is_literal_integer_type(symbol_c *type_symbol) {
       
    93   if (type_symbol == NULL) {return true;}
       
    94   if (typeid(*type_symbol) == typeid(integer_c))        {return true;}
       
    95   if (typeid(*type_symbol) == typeid(neg_integer_c))    {return true;}
       
    96   if (typeid(*type_symbol) == typeid(binary_integer_c)) {return true;}
       
    97   if (typeid(*type_symbol) == typeid(octal_integer_c))  {return true;}
       
    98   if (typeid(*type_symbol) == typeid(hex_integer_c))    {return true;}
       
    99   return false;
       
   100 }
       
   101 
       
   102 /* A helper function... */
       
   103 bool search_expression_type_c::is_integer_type(symbol_c *type_symbol) {
       
   104   if (type_symbol == NULL) {return true;}
       
   105   if (typeid(*type_symbol) == typeid(sint_type_name_c))      {return true;}
       
   106   if (typeid(*type_symbol) == typeid(int_type_name_c))       {return true;}
       
   107   if (typeid(*type_symbol) == typeid(dint_type_name_c))      {return true;}
       
   108   if (typeid(*type_symbol) == typeid(lint_type_name_c))      {return true;}
       
   109   if (typeid(*type_symbol) == typeid(usint_type_name_c))     {return true;}
       
   110   if (typeid(*type_symbol) == typeid(uint_type_name_c))      {return true;}
       
   111   if (typeid(*type_symbol) == typeid(udint_type_name_c))     {return true;}
       
   112   if (typeid(*type_symbol) == typeid(ulint_type_name_c))     {return true;}
       
   113   if (typeid(*type_symbol) == typeid(safesint_type_name_c))  {return true;}
       
   114   if (typeid(*type_symbol) == typeid(safeint_type_name_c))   {return true;}
       
   115   if (typeid(*type_symbol) == typeid(safedint_type_name_c))  {return true;}
       
   116   if (typeid(*type_symbol) == typeid(safelint_type_name_c))  {return true;}
       
   117   if (typeid(*type_symbol) == typeid(safeusint_type_name_c)) {return true;}
       
   118   if (typeid(*type_symbol) == typeid(safeuint_type_name_c))  {return true;}
       
   119   if (typeid(*type_symbol) == typeid(safeudint_type_name_c)) {return true;}
       
   120   if (typeid(*type_symbol) == typeid(safeulint_type_name_c)) {return true;}
       
   121   return is_literal_integer_type(type_symbol);
       
   122 }
       
   123 
       
   124 /* A helper function... */
       
   125 bool search_expression_type_c::is_literal_real_type(symbol_c *type_symbol) {
       
   126   if (type_symbol == NULL) {return true;}
       
   127   if (typeid(*type_symbol) == typeid(real_c))     {return true;}
       
   128   if (typeid(*type_symbol) == typeid(neg_real_c)) {return true;}
       
   129   return false;
       
   130 }
       
   131 
       
   132 /* A helper function... */
       
   133 bool search_expression_type_c::is_real_type(symbol_c *type_symbol) {
       
   134   if (type_symbol == NULL) {return true;}
       
   135   if (typeid(*type_symbol) == typeid(real_type_name_c))      {return true;}
       
   136   if (typeid(*type_symbol) == typeid(lreal_type_name_c))     {return true;}
       
   137   if (typeid(*type_symbol) == typeid(safereal_type_name_c))  {return true;} 
       
   138   if (typeid(*type_symbol) == typeid(safelreal_type_name_c)) {return true;}  
       
   139   return is_literal_real_type(type_symbol);
       
   140 }
       
   141 
       
   142 bool search_expression_type_c::is_num_type(symbol_c *type_symbol) {
       
   143   if (type_symbol == NULL) {return true;}
       
   144   return is_real_type(type_symbol) || is_integer_type(type_symbol);
       
   145 }
       
   146 
       
   147 bool search_expression_type_c::is_nbinary_type(symbol_c *type_symbol) {
       
   148   if (type_symbol == NULL) {return true;}
       
   149   if (typeid(*type_symbol) == typeid(byte_type_name_c))      {return true;}
       
   150   if (typeid(*type_symbol) == typeid(word_type_name_c))      {return true;}
       
   151   if (typeid(*type_symbol) == typeid(dword_type_name_c))     {return true;}
       
   152   if (typeid(*type_symbol) == typeid(lword_type_name_c))     {return true;}
       
   153   if (typeid(*type_symbol) == typeid(safebyte_type_name_c))  {return true;}
       
   154   if (typeid(*type_symbol) == typeid(safeword_type_name_c))  {return true;}
       
   155   if (typeid(*type_symbol) == typeid(safedword_type_name_c)) {return true;}
       
   156   if (typeid(*type_symbol) == typeid(safelword_type_name_c)) {return true;}
       
   157   return is_literal_integer_type(type_symbol);
       
   158 }
       
   159 
       
   160 bool search_expression_type_c::is_binary_type(symbol_c *type_symbol) {
       
   161   if (type_symbol == NULL) {return true;}
       
   162 //   if (typeid(*type_symbol) == typeid(bool_type_name_c))     {return true;}
       
   163 //   if (typeid(*type_symbol) == typeid(safebool_type_name_c)) {return true;}
       
   164   return (is_nbinary_type(type_symbol) || is_bool_type(type_symbol));
       
   165 }
       
   166 
       
   167 bool search_expression_type_c::is_same_type(symbol_c *first_type, symbol_c *second_type) {
       
   168   if (first_type == NULL || second_type == NULL) {return true;}
       
   169   if (typeid(*first_type) == typeid(*second_type)) {return true;}
       
   170   if (is_bool_type(first_type)            && is_bool_type(second_type))            {return true;}
       
   171   if (is_integer_type(first_type)         && is_literal_integer_type(second_type)) {return true;}
       
   172   if (is_literal_integer_type(first_type) && is_integer_type(second_type))         {return true;}
       
   173   if (is_binary_type(first_type)          && is_literal_integer_type(second_type)) {return true;}
       
   174   if (is_literal_integer_type(first_type) && is_binary_type(second_type))          {return true;}
       
   175   if (is_real_type(first_type)            && is_literal_real_type(second_type))    {return true;}
       
   176   if (is_literal_real_type(first_type)    && is_real_type(second_type))            {return true;}
       
   177   return false;
       
   178 }
       
   179 
       
   180 symbol_c* search_expression_type_c::common_type(symbol_c *first_type, symbol_c *second_type) {
       
   181   if (first_type == NULL && second_type == NULL) {return NULL;}
       
   182   if (first_type == NULL) {return second_type;}
       
   183   if (second_type == NULL) {return first_type;}
       
   184   if (typeid(*first_type) == typeid(*second_type)) {return first_type;}
       
   185   if (is_integer_type(first_type)         && is_literal_integer_type(second_type)) {return first_type;}
       
   186   if (is_literal_integer_type(first_type) && is_integer_type(second_type))         {return second_type;}
       
   187   if (is_binary_type(first_type)          && is_literal_integer_type(second_type)) {return first_type;}
       
   188   if (is_literal_integer_type(first_type) && is_binary_type(second_type))          {return second_type;}
       
   189   if (is_real_type(first_type)            && is_literal_real_type(second_type))    {return first_type;}
       
   190   if (is_literal_real_type(first_type)    && is_real_type(second_type))            {return second_type;}
       
   191   return NULL;
       
   192 }
       
   193 
       
   194 symbol_c *search_expression_type_c::default_literal_type(symbol_c* symbol) {
       
   195   if (is_literal_integer_type(symbol)) {
       
   196     return (symbol_c *)&search_constant_type_c::lint_type_name;
       
   197   }
       
   198   else if (is_literal_real_type(symbol)) {
       
   199     return (symbol_c *)&search_constant_type_c::lreal_type_name;
       
   200   }
       
   201   return symbol;
       
   202 }
       
   203 
       
   204 
       
   205 /* A helper function... */
       
   206 void *search_expression_type_c::compute_boolean_expression(symbol_c *left_type, symbol_c *right_type) {
       
   207   if (!is_same_type(left_type, right_type))
       
   208     ERROR;
       
   209   if (!is_bool_type(left_type) && !is_binary_type(left_type))
       
   210     ERROR;
       
   211   if (is_literal_integer_type(left_type)) {return (void *)right_type;}
       
   212   else {return (void *)left_type;}
       
   213 }
       
   214 
       
   215 /* A helper function... */
       
   216 void *search_expression_type_c::compute_numeric_expression(symbol_c *left_type, symbol_c *right_type) {
       
   217   if (!is_same_type(left_type, right_type))
       
   218     ERROR;
       
   219   if (!is_integer_type(left_type) && !is_real_type(left_type))
       
   220     ERROR;
       
   221   if (is_literal_integer_type(left_type) || is_literal_real_type(left_type)) {return (void *)right_type;}
       
   222   else {return (void *)left_type;}
       
   223   return NULL;
       
   224 }
       
   225 
       
   226 /* a helper function... */
       
   227 symbol_c *search_expression_type_c::base_type(symbol_c *symbol) {
       
   228   return (symbol_c *)symbol->accept(search_base_type);
       
   229 }
       
   230 
       
   231 /*********************/
       
   232 /* B 1.4 - Variables */
       
   233 /*********************/
       
   234 
       
   235 void *search_expression_type_c::visit(symbolic_variable_c *symbol) {
       
   236   symbol_c *res;
       
   237   
       
   238   /* Nope, now we assume it is a variable, and determine its type... */
       
   239   res = search_varfb_instance_type->get_basetype_decl(symbol);
       
   240   if (NULL != res) return res;
       
   241   
       
   242   return NULL;
       
   243 }
       
   244 
       
   245 /********************************************/
       
   246 /* B 1.4.1 - Directly Represented Variables */
       
   247 /********************************************/
       
   248 void *search_expression_type_c::visit(direct_variable_c *symbol) {
       
   249   symbol_c *res;
       
   250   
       
   251   /* Nope, now we assume it is a variable, and determine its type... */
       
   252   res = search_varfb_instance_type->get_basetype_decl(symbol);
       
   253   if (NULL != res) return res;
       
   254   
       
   255   return NULL;
       
   256 }
       
   257 
       
   258 /*************************************/
       
   259 /* B 1.4.2 - Multi-element variables */
       
   260 /*************************************/
       
   261 
       
   262 void *search_expression_type_c::visit(array_variable_c *symbol) {
       
   263   symbol_c *res;
       
   264   
       
   265   /* Nope, now we assume it is a variable, and determine its type... */
       
   266   res = search_varfb_instance_type->get_basetype_decl(symbol);
       
   267   if (NULL != res) return res;
       
   268   
       
   269   return NULL;
       
   270 }
       
   271 
       
   272 void *search_expression_type_c::visit(structured_variable_c *symbol) {
       
   273   symbol_c *res;
       
   274   
       
   275   /* Nope, now we assume it is a variable, and determine its type... */
       
   276   res = search_varfb_instance_type->get_basetype_decl(symbol);
       
   277   if (NULL != res) return res;
       
   278   
       
   279   return NULL;
       
   280 }
       
   281 
       
   282 /***************************************/
       
   283 /* B.3 - Language ST (Structured Text) */
       
   284 /***************************************/
       
   285 /***********************/
       
   286 /* B 3.1 - Expressions */
       
   287 /***********************/
       
   288 void *search_expression_type_c::visit(or_expression_c *symbol) {
       
   289   symbol_c *left_type = base_type((symbol_c *)symbol->l_exp->accept(*this));
       
   290   symbol_c *right_type = base_type((symbol_c *)symbol->r_exp->accept(*this));
       
   291   return compute_boolean_expression(left_type, right_type);
       
   292 }
       
   293 
       
   294 void *search_expression_type_c::visit(xor_expression_c *symbol) {
       
   295   symbol_c *left_type = base_type((symbol_c *)symbol->l_exp->accept(*this));
       
   296   symbol_c *right_type = base_type((symbol_c *)symbol->r_exp->accept(*this));
       
   297   return compute_boolean_expression(left_type, right_type);
       
   298 }
       
   299 
       
   300 void *search_expression_type_c::visit(and_expression_c *symbol) {
       
   301   symbol_c *left_type = base_type((symbol_c *)symbol->l_exp->accept(*this));
       
   302   symbol_c *right_type = base_type((symbol_c *)symbol->r_exp->accept(*this));
       
   303   return compute_boolean_expression(left_type, right_type); 
       
   304 }
       
   305 
       
   306 void *search_expression_type_c::visit(equ_expression_c *symbol) {return (void *)&bool_type_name;}
       
   307 void *search_expression_type_c::visit(notequ_expression_c *symbol) {return (void *)&bool_type_name;}
       
   308 void *search_expression_type_c::visit(lt_expression_c *symbol) {return (void *)&bool_type_name;}
       
   309 void *search_expression_type_c::visit(gt_expression_c *symbol) {return (void *)&bool_type_name;}
       
   310 void *search_expression_type_c::visit(le_expression_c *symbol) {return (void *)&bool_type_name;}
       
   311 void *search_expression_type_c::visit(ge_expression_c *symbol) {return (void *)&bool_type_name;}
       
   312 
       
   313 void *search_expression_type_c::visit(add_expression_c *symbol) {
       
   314   symbol_c *left_type = base_type((symbol_c *)symbol->l_exp->accept(*this));
       
   315   symbol_c *right_type = base_type((symbol_c *)symbol->r_exp->accept(*this));
       
   316   if (typeid(*left_type) == typeid(time_type_name_c) && typeid(*right_type) == typeid(time_type_name_c)) {return (void *)&time_type_name;}
       
   317   if (typeid(*left_type) == typeid(tod_type_name_c) && typeid(*right_type) == typeid(time_type_name_c)) {return (void *)&tod_type_name;}
       
   318   if (typeid(*left_type) == typeid(dt_type_name_c) && typeid(*right_type) == typeid(time_type_name_c)) {return (void *)&dt_type_name;}
       
   319   return compute_numeric_expression(left_type, right_type);
       
   320 }
       
   321 
       
   322 void *search_expression_type_c::visit(sub_expression_c *symbol) {
       
   323   symbol_c *left_type = base_type((symbol_c *)symbol->l_exp->accept(*this));
       
   324   symbol_c *right_type = base_type((symbol_c *)symbol->r_exp->accept(*this));
       
   325   if (typeid(*left_type) == typeid(time_type_name_c) && typeid(*right_type) == typeid(time_type_name_c)) {return (void *)&time_type_name;}
       
   326   if (typeid(*left_type) == typeid(date_type_name_c) && typeid(*right_type) == typeid(date_type_name_c)) {return (void *)&time_type_name;}
       
   327   if (typeid(*left_type) == typeid(tod_type_name_c) && typeid(*right_type) == typeid(time_type_name_c)) {return (void *)&tod_type_name;}
       
   328   if (typeid(*left_type) == typeid(tod_type_name_c) && typeid(*right_type) == typeid(tod_type_name_c)) {return (void *)&time_type_name;}
       
   329   if (typeid(*left_type) == typeid(dt_type_name_c) && typeid(*right_type) == typeid(time_type_name_c)) {return (void *)&dt_type_name;}
       
   330   if (typeid(*left_type) == typeid(dt_type_name_c) && typeid(*right_type) == typeid(dt_type_name_c)) {return (void *)&time_type_name;}
       
   331   return compute_numeric_expression(left_type, right_type);
       
   332 }
       
   333 
       
   334 void *search_expression_type_c::visit(mul_expression_c *symbol) {
       
   335   symbol_c *left_type = base_type((symbol_c *)symbol->l_exp->accept(*this));
       
   336   symbol_c *right_type = base_type((symbol_c *)symbol->r_exp->accept(*this));
       
   337   if (typeid(*left_type) == typeid(time_type_name_c) && is_num_type(right_type)) {
       
   338       return (void *)&time_type_name;
       
   339   }
       
   340   return compute_numeric_expression(left_type, right_type);
       
   341 }
       
   342 
       
   343 void *search_expression_type_c::visit(div_expression_c *symbol) {
       
   344   symbol_c *left_type = base_type((symbol_c *)symbol->l_exp->accept(*this));
       
   345   symbol_c *right_type = base_type((symbol_c *)symbol->r_exp->accept(*this));
       
   346   if (typeid(*left_type) == typeid(time_type_name_c) && is_num_type(right_type)){
       
   347       return (void *)&time_type_name;
       
   348   }
       
   349   return compute_numeric_expression(left_type, right_type);
       
   350 }
       
   351 
       
   352 void *search_expression_type_c::visit(mod_expression_c *symbol) {
       
   353   symbol_c *left_type = base_type((symbol_c *)symbol->l_exp->accept(*this));
       
   354   symbol_c *right_type = base_type((symbol_c *)symbol->r_exp->accept(*this));
       
   355   return compute_numeric_expression(left_type, right_type);
       
   356 }
       
   357 
       
   358 void *search_expression_type_c::visit(power_expression_c *symbol) {
       
   359   symbol_c *left_type = base_type((symbol_c *)symbol->l_exp->accept(*this));
       
   360   symbol_c *right_type = base_type((symbol_c *)symbol->r_exp->accept(*this));
       
   361   if (is_real_type(left_type) && is_num_type(right_type)) {
       
   362       return (void *)left_type;
       
   363   }
       
   364   ERROR;
       
   365   return NULL;
       
   366 }
       
   367 
       
   368 void *search_expression_type_c::visit(neg_expression_c *symbol) {
       
   369   symbol_c *exp_type = base_type((symbol_c *)symbol->exp->accept(*this));
       
   370   if (is_num_type(exp_type) || typeid(*exp_type) == typeid(time_type_name_c)){
       
   371       return (void *)exp_type;
       
   372   }
       
   373   ERROR;
       
   374   return NULL;
       
   375 }
       
   376 
       
   377 void *search_expression_type_c::visit(not_expression_c *symbol) {
       
   378   symbol_c *exp_type = base_type((symbol_c *)symbol->exp->accept(*this));
       
   379   return compute_boolean_expression(exp_type, exp_type);
       
   380 }
       
   381 
       
   382 void *search_expression_type_c::visit(function_invocation_c *symbol) {
       
   383   function_declaration_c *f_decl = (function_declaration_c *)symbol->called_function_declaration;
       
   384   if (f_decl == NULL) ERROR;
       
   385   return base_type(f_decl->type_name);
       
   386 }
       
   387 
       
   388 /*bool_type_name_c     search_expression_type_c::bool_type_name;*/
       
   389