stage4/generate_c/search_expression_type.cc
changeset 70 e1f0ebd2d9ec
child 123 a9b4af71cfa4
equal deleted inserted replaced
69:41cb5b80416e 70:e1f0ebd2d9ec
       
     1 /*
       
     2  * (c) 2003 Mario de Sousa
       
     3  *
       
     4  * Offered to the public under the terms of the GNU General Public License
       
     5  * as published by the Free Software Foundation; either version 2 of the
       
     6  * License, or (at your option) any later version.
       
     7  *
       
     8  * This program is distributed in the hope that it will be useful, but
       
     9  * WITHOUT ANY WARRANTY; without even the implied warranty of
       
    10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
       
    11  * Public License for more details.
       
    12  *
       
    13  * This code is made available on the understanding that it will not be
       
    14  * used in safety-critical situations without a full and competent review.
       
    15  */
       
    16 
       
    17 /*
       
    18  * An IEC 61131-3 IL and ST compiler.
       
    19  *
       
    20  * Based on the
       
    21  * FINAL DRAFT - IEC 61131-3, 2nd Ed. (2001-12-10)
       
    22  *
       
    23  */
       
    24 
       
    25 
       
    26 /* Determine the data type of an ST expression.
       
    27  * A reference to the relevant type definition is returned.
       
    28  *
       
    29  * For example:
       
    30  *       2 + 3       -> returns reference to a int_type_name_c object.
       
    31  *       22.2 - 5    -> returns reference to a real_type_name_c object.
       
    32  *       etc...
       
    33  */
       
    34 
       
    35 #include "function_type_decl.h"
       
    36 #include "get_function_type_decl.c"
       
    37 
       
    38 #if 0
       
    39 typedef enum {function_add,
       
    40               function_sub,
       
    41               function_and,
       
    42               function_or,
       
    43               function_sqrt,
       
    44               function_none} function_type_t;
       
    45 
       
    46 
       
    47 function_type_t get_function_type(identifier_c *function_name) {
       
    48   if (!strcasecmp(function_name->value, "ADD"))
       
    49     return function_add;
       
    50   else if (!strcasecmp(function_name->value, "SUB"))
       
    51     return function_sub;
       
    52   else if (!strcasecmp(function_name->value, "AND"))
       
    53     return function_and;
       
    54   else if (!strcasecmp(function_name->value, "OR"))
       
    55     return function_or;
       
    56   else if (!strcasecmp(function_name->value, "SQRT"))
       
    57     return function_sqrt;
       
    58   else return function_none;
       
    59 }
       
    60 #endif
       
    61 
       
    62 
       
    63 symbol_c *generate_param_name(const char *name) {
       
    64   symbol_c *param_name = new identifier_c(name);
       
    65   return param_name;
       
    66 }
       
    67 
       
    68 
       
    69 symbol_c *generate_param_name(const char *format, int number) {
       
    70   char name[10];
       
    71   sprintf(name, format, number);
       
    72   symbol_c *param_name = new identifier_c(name);
       
    73   return param_name;
       
    74 }
       
    75 
       
    76 
       
    77 class search_expression_type_c: public search_constant_type_c {
       
    78   private:
       
    79     search_varfb_instance_type_c *search_varfb_instance_type;
       
    80     search_base_type_c search_base_type;
       
    81 
       
    82   public:
       
    83     search_expression_type_c(symbol_c *search_scope) {
       
    84       search_varfb_instance_type = new search_varfb_instance_type_c(search_scope);
       
    85     }
       
    86 
       
    87     virtual ~search_expression_type_c(void) {
       
    88       delete search_varfb_instance_type;
       
    89     }
       
    90 
       
    91     /* A helper function... */
       
    92     bool is_bool_type(symbol_c *type_symbol) {
       
    93       return (typeid(*type_symbol) == typeid(bool_type_name_c));
       
    94     }
       
    95 
       
    96     /* A helper function... */
       
    97     bool is_time_type(symbol_c *type_symbol) {
       
    98       if (typeid(*type_symbol) == typeid(time_type_name_c)) {return true;}
       
    99       if (typeid(*type_symbol) == typeid(date_type_name_c)) {return true;}
       
   100       if (typeid(*type_symbol) == typeid(tod_type_name_c)) {return true;}
       
   101       if (typeid(*type_symbol) == typeid(dt_type_name_c)) {return true;}
       
   102       return false;
       
   103     }
       
   104 
       
   105     /* A helper function... */
       
   106     bool is_integer_type(symbol_c *type_symbol) {
       
   107       if (typeid(*type_symbol) == typeid(sint_type_name_c)) {return true;}
       
   108       if (typeid(*type_symbol) == typeid(int_type_name_c)) {return true;}
       
   109       if (typeid(*type_symbol) == typeid(dint_type_name_c)) {return true;}
       
   110       if (typeid(*type_symbol) == typeid(lint_type_name_c)) {return true;}
       
   111       if (typeid(*type_symbol) == typeid(usint_type_name_c)) {return true;}
       
   112       if (typeid(*type_symbol) == typeid(uint_type_name_c)) {return true;}
       
   113       if (typeid(*type_symbol) == typeid(udint_type_name_c)) {return true;}
       
   114       if (typeid(*type_symbol) == typeid(ulint_type_name_c)) {return true;}
       
   115       if (typeid(*type_symbol) == typeid(constant_int_type_name_c)) {return true;}
       
   116       return false;
       
   117     }
       
   118 
       
   119     bool is_real_type(symbol_c *type_symbol) {
       
   120       if (typeid(*type_symbol) == typeid(real_type_name_c)) {return true;}
       
   121       if (typeid(*type_symbol) == typeid(lreal_type_name_c)) {return true;}
       
   122       if (typeid(*type_symbol) == typeid(constant_real_type_name_c)) {return true;}
       
   123       return false;
       
   124     }
       
   125 
       
   126     bool is_num_type(symbol_c *type_symbol) {
       
   127       return is_real_type(type_symbol) || is_integer_type(type_symbol);
       
   128     }
       
   129 
       
   130     bool is_nbinary_type(symbol_c *type_symbol) {
       
   131       if (typeid(*type_symbol) == typeid(byte_type_name_c)) {return true;}
       
   132       if (typeid(*type_symbol) == typeid(word_type_name_c)) {return true;}
       
   133       if (typeid(*type_symbol) == typeid(dword_type_name_c)) {return true;}
       
   134       if (typeid(*type_symbol) == typeid(lword_type_name_c)) {return true;}
       
   135       if (typeid(*type_symbol) == typeid(constant_int_type_name_c)) {return true;}
       
   136       return false;
       
   137     }
       
   138 
       
   139     bool is_binary_type(symbol_c *type_symbol) {
       
   140       if (typeid(*type_symbol) == typeid(bool_type_name_c)) {return true;}
       
   141       return is_nbinary_type(type_symbol);
       
   142     }
       
   143     
       
   144     bool is_same_type(symbol_c *first_type, symbol_c *second_type) {
       
   145       if (typeid(*first_type) == typeid(*second_type)) {return true;}
       
   146       if (is_integer_type(first_type) && (typeid(*second_type) == typeid(constant_int_type_name_c))) {return true;}
       
   147       if ((typeid(*first_type) == typeid(constant_int_type_name_c) && is_integer_type(second_type))) {return true;}
       
   148       if (is_binary_type(first_type) && (typeid(*second_type) == typeid(constant_int_type_name_c))) {return true;}
       
   149       if ((typeid(*first_type) == typeid(constant_int_type_name_c) && is_binary_type(second_type))) {return true;}
       
   150       if (is_real_type(first_type) && (typeid(*second_type) == typeid(constant_real_type_name_c))) {return true;}
       
   151       if ((typeid(*first_type) == typeid(constant_real_type_name_c) && is_real_type(second_type))) {return true;}
       
   152       return false;
       
   153     }
       
   154 
       
   155     symbol_c* common_type(symbol_c *first_type, symbol_c *second_type) {
       
   156       if (typeid(*first_type) == typeid(*second_type)) {return first_type;}
       
   157       if (is_integer_type(first_type) && (typeid(*second_type) == typeid(constant_int_type_name_c))) {return first_type;}
       
   158       if ((typeid(*first_type) == typeid(constant_int_type_name_c) && is_integer_type(second_type))) {return second_type;}
       
   159       if (is_binary_type(first_type) && (typeid(*second_type) == typeid(constant_int_type_name_c))) {return first_type;}
       
   160       if ((typeid(*first_type) == typeid(constant_int_type_name_c) && is_binary_type(second_type))) {return second_type;}
       
   161       if (is_real_type(first_type) && (typeid(*second_type) == typeid(constant_real_type_name_c))) {return first_type;}
       
   162       if ((typeid(*first_type) == typeid(constant_real_type_name_c) && is_real_type(second_type))) {return second_type;}
       
   163       return NULL;
       
   164     }
       
   165 
       
   166 #include "search_type_code.c"
       
   167 
       
   168 #if 0
       
   169   void *compute_standard_function_st(function_invocation_c *symbol) {
       
   170     symbol_c *current_type = NULL;
       
   171     symbol_c *return_type = NULL;
       
   172 
       
   173     function_type_t current_function_type = get_function_type((identifier_c *)symbol->function_name);
       
   174     function_call_param_iterator_c function_call_param_iterator(symbol);
       
   175     search_expression_type_c* search_expression_type = this;
       
   176     
       
   177     for(int current_param = 0; current_param < ((list_c *)symbol->parameter_assignment_list)->n; current_param++) {
       
   178       symbol_c *param_name = NULL;
       
   179       switch (current_function_type) {
       
   180         case function_add:
       
   181         case function_and:
       
   182         case function_or:
       
   183           param_name = generate_param_name("IN%d", current_param + 1);
       
   184           break;
       
   185         case function_sub:
       
   186           if (current_param < 2)
       
   187             param_name = generate_param_name("IN%d", current_param + 1);
       
   188           else ERROR;
       
   189           break;
       
   190         default: ERROR;
       
   191       }
       
   192       
       
   193       /* Get the value from a foo(<param_name> = <param_value>) style call */
       
   194       symbol_c *param_value = function_call_param_iterator.search(param_name);
       
   195       delete param_name;
       
   196       
       
   197       /* Get the value from a foo(<param_value>) style call */
       
   198       if (param_value == NULL)
       
   199         param_value = function_call_param_iterator.next();
       
   200       
       
   201       if (param_value == NULL) ERROR;
       
   202       
       
   203       symbol_c *param_type = (symbol_c *)param_value->accept(*this);
       
   204       
       
   205       switch (current_function_type) {
       
   206         case function_add:
       
   207           if (current_param == 0)
       
   208             current_type = param_type;
       
   209           else if (current_param == 1) {
       
   210             if ((is_integer_type(current_type) && is_same_type(current_type, param_type)) ||
       
   211                 (is_real_type(current_type) && is_same_type(current_type, param_type))) {
       
   212               current_type = common_type(current_type, param_type);
       
   213               return_type = current_type;
       
   214             }
       
   215             else if (is_time_type(current_type)) {
       
   216               if ((typeid(*current_type) == typeid(time_type_name_c)) && (typeid(*param_type) == typeid(time_type_name_c))) {return_type = (symbol_c *)&time_type_name;}
       
   217               else if (typeid(*current_type) == typeid(tod_type_name_c) && typeid(*param_type) == typeid(time_type_name_c)) {return_type = (symbol_c *)&tod_type_name;}
       
   218               else if (typeid(*current_type) == typeid(dt_type_name_c) && typeid(*param_type) == typeid(time_type_name_c)) {return_type = (symbol_c *)&dt_type_name;}
       
   219               else ERROR;
       
   220             }
       
   221             else ERROR;
       
   222           }
       
   223           else if (!is_time_type(current_type) && is_same_type(current_type, param_type)) {
       
   224             current_type = common_type(current_type, param_type);
       
   225             return_type = current_type;
       
   226           }
       
   227           else ERROR;
       
   228           break;
       
   229         case function_sub:
       
   230           if (current_param == 0)
       
   231             current_type = param_type;
       
   232           else if (current_param == 1) {
       
   233             if ((is_integer_type(current_type) && is_same_type(current_type, param_type)) ||
       
   234                 (is_real_type(current_type) && is_same_type(current_type, param_type)))
       
   235               return_type = common_type(current_type, param_type);
       
   236             else if (is_time_type(current_type)) {
       
   237               if (typeid(*current_type) == typeid(time_type_name_c) && typeid(*param_type) == typeid(time_type_name_c)) {return_type = (symbol_c *)&time_type_name;}
       
   238               else if (typeid(*current_type) == typeid(date_type_name_c) && typeid(*param_type) == typeid(date_type_name_c)) {return_type = (symbol_c *)&time_type_name;}
       
   239               else if (typeid(*current_type) == typeid(tod_type_name_c) && typeid(*param_type) == typeid(time_type_name_c)) {return_type = (symbol_c *)&tod_type_name;}
       
   240               else if (typeid(*current_type) == typeid(tod_type_name_c) && typeid(*param_type) == typeid(tod_type_name_c)) {return_type = (symbol_c *)&time_type_name;}
       
   241               else if (typeid(*current_type) == typeid(dt_type_name_c) && typeid(*param_type) == typeid(time_type_name_c)) {return_type = (symbol_c *)&dt_type_name;}
       
   242               else if (typeid(*current_type) == typeid(dt_type_name_c) && typeid(*param_type) == typeid(dt_type_name_c)) {return_type = (symbol_c *)&time_type_name;}
       
   243               else ERROR;
       
   244             }
       
   245             else ERROR;
       
   246           }
       
   247           else ERROR;
       
   248           break;
       
   249         case function_and:
       
   250         case function_or:
       
   251           if (current_param == 0)
       
   252             if (is_binary_type(param_type))
       
   253               current_type = param_type;
       
   254             else ERROR;
       
   255           else if (is_same_type(current_type, param_type))
       
   256             return_type = common_type(current_type, param_type);
       
   257           else ERROR;
       
   258           break;
       
   259         default: ERROR;
       
   260       }
       
   261     }
       
   262     return (void *)return_type;
       
   263   }
       
   264 
       
   265   void *compute_standard_function_il(il_function_call_c *symbol, symbol_c *param_type) {
       
   266     /*symbol_c *current_type = NULL;*/
       
   267     symbol_c *return_type = NULL;
       
   268     function_type_t current_function_type = get_function_type((identifier_c *)symbol->function_name);
       
   269     if (current_function_type == function_none) ERROR;
       
   270     
       
   271     function_call_param_iterator_c function_call_param_iterator(symbol);
       
   272     
       
   273     int nb_param = 1;
       
   274     if (symbol->il_operand_list != NULL)
       
   275       nb_param += ((list_c *)symbol->il_operand_list)->n;
       
   276 
       
   277     for(int current_param = 0; current_param < nb_param; current_param++) {
       
   278       
       
   279       if (current_param != 0) {
       
   280         symbol_c *param_name = NULL;
       
   281         switch (current_function_type) {
       
   282           default: ERROR;
       
   283         }
       
   284         
       
   285         /* Get the value from a foo(<param_name> = <param_value>) style call */
       
   286         symbol_c *param_value = function_call_param_iterator.search(param_name);
       
   287         delete param_name;
       
   288         
       
   289         /* Get the value from a foo(<param_value>) style call */
       
   290         if (param_value == NULL)
       
   291           param_value = function_call_param_iterator.next();
       
   292         
       
   293         if (param_value == NULL) ERROR;
       
   294         
       
   295         param_type = (symbol_c *)param_value->accept(*this);
       
   296       }
       
   297       
       
   298       switch (current_function_type) {
       
   299         case function_sqrt:
       
   300           if (current_param == 0 && is_real_type(param_type))
       
   301             return_type = param_type;
       
   302           else ERROR;
       
   303           break;
       
   304         default: ERROR;
       
   305       }
       
   306     }
       
   307     
       
   308     return (void *)return_type;
       
   309   }
       
   310 #endif
       
   311 
       
   312   /*static bool_type_name_c bool_type_name;*/
       
   313 
       
   314   /* A helper function... */
       
   315   void *compute_boolean_expression(symbol_c *left_type, symbol_c *right_type) {
       
   316     if (!is_same_type(left_type, right_type))
       
   317       ERROR;
       
   318     if (!is_bool_type(left_type) && !is_binary_type(left_type))
       
   319       ERROR;
       
   320     if (typeid(*left_type) == typeid(constant_int_type_name_c)) {return (void *)right_type;}
       
   321     else {return (void *)left_type;}
       
   322   }
       
   323 
       
   324   /* A helper function... */
       
   325   void *compute_numeric_expression(symbol_c *left_type, symbol_c *right_type) {
       
   326     if (!is_same_type(left_type, right_type))
       
   327       ERROR;
       
   328     if (!is_integer_type(left_type) && !is_real_type(left_type))
       
   329       ERROR;
       
   330     if ((typeid(*left_type) == typeid(constant_int_type_name_c)) || (typeid(*left_type) == typeid(constant_real_type_name_c))) {return (void *)right_type;}
       
   331     else {return (void *)left_type;}
       
   332     return NULL;
       
   333   }
       
   334 
       
   335   /* a helper function... */
       
   336   symbol_c *base_type(symbol_c *symbol) {
       
   337     return (symbol_c *)symbol->accept(search_base_type);
       
   338   }
       
   339 
       
   340 /*********************/
       
   341 /* B 1.4 - Variables */
       
   342 /*********************/
       
   343 
       
   344   void *visit(symbolic_variable_c *symbol) {
       
   345     symbol_c *res;
       
   346     
       
   347     /* Nope, now we assume it is a variable, and determine its type... */
       
   348     res = search_varfb_instance_type->get_type(symbol);
       
   349     if (NULL != res) return res;
       
   350     
       
   351     return NULL;
       
   352   }
       
   353 
       
   354 /*************************************/
       
   355 /* B 1.4.2 - Multi-element variables */
       
   356 /*************************************/
       
   357 
       
   358   void *visit(array_variable_c *symbol) {
       
   359     symbol_c *res;
       
   360     
       
   361     /* Nope, now we assume it is a variable, and determine its type... */
       
   362     res = search_varfb_instance_type->get_type(symbol);
       
   363     if (NULL != res) return res;
       
   364     
       
   365     return NULL;
       
   366   }
       
   367 
       
   368   void *visit(structured_variable_c *symbol) {
       
   369     symbol_c *res;
       
   370     
       
   371     /* Nope, now we assume it is a variable, and determine its type... */
       
   372     res = search_varfb_instance_type->get_type(symbol);
       
   373     if (NULL != res) return res;
       
   374     
       
   375     return NULL;
       
   376   }
       
   377 
       
   378 /***************************************/
       
   379 /* B.3 - Language ST (Structured Text) */
       
   380 /***************************************/
       
   381 /***********************/
       
   382 /* B 3.1 - Expressions */
       
   383 /***********************/
       
   384   void *visit(or_expression_c *symbol) {
       
   385     symbol_c *left_type = base_type((symbol_c *)symbol->l_exp->accept(*this));
       
   386     symbol_c *right_type = base_type((symbol_c *)symbol->r_exp->accept(*this));
       
   387     return compute_boolean_expression(left_type, right_type);
       
   388   }
       
   389 
       
   390   void *visit(xor_expression_c *symbol) {
       
   391     symbol_c *left_type = base_type((symbol_c *)symbol->l_exp->accept(*this));
       
   392     symbol_c *right_type = base_type((symbol_c *)symbol->r_exp->accept(*this));
       
   393     return compute_boolean_expression(left_type, right_type);
       
   394   }
       
   395 
       
   396   void *visit(and_expression_c *symbol) {
       
   397     symbol_c *left_type = base_type((symbol_c *)symbol->l_exp->accept(*this));
       
   398     symbol_c *right_type = base_type((symbol_c *)symbol->r_exp->accept(*this));
       
   399     return compute_boolean_expression(left_type, right_type); 
       
   400   }
       
   401 
       
   402   void *visit(equ_expression_c *symbol) {return (void *)&bool_type_name;}
       
   403   void *visit(notequ_expression_c *symbol) {return (void *)&bool_type_name;}
       
   404   void *visit(lt_expression_c *symbol) {return (void *)&bool_type_name;}
       
   405   void *visit(gt_expression_c *symbol) {return (void *)&bool_type_name;}
       
   406   void *visit(le_expression_c *symbol) {return (void *)&bool_type_name;}
       
   407   void *visit(ge_expression_c *symbol) {return (void *)&bool_type_name;}
       
   408 
       
   409   void *visit(add_expression_c *symbol) {
       
   410     symbol_c *left_type = base_type((symbol_c *)symbol->l_exp->accept(*this));
       
   411     symbol_c *right_type = base_type((symbol_c *)symbol->r_exp->accept(*this));
       
   412     if (typeid(*left_type) == typeid(time_type_name_c) && typeid(*right_type) == typeid(time_type_name_c)) {return (void *)&time_type_name;}
       
   413     if (typeid(*left_type) == typeid(tod_type_name_c) && typeid(*right_type) == typeid(time_type_name_c)) {return (void *)&tod_type_name;}
       
   414     if (typeid(*left_type) == typeid(dt_type_name_c) && typeid(*right_type) == typeid(time_type_name_c)) {return (void *)&dt_type_name;}
       
   415     return compute_numeric_expression(left_type, right_type);
       
   416   }
       
   417 
       
   418   void *visit(sub_expression_c *symbol) {
       
   419     symbol_c *left_type = base_type((symbol_c *)symbol->l_exp->accept(*this));
       
   420     symbol_c *right_type = base_type((symbol_c *)symbol->r_exp->accept(*this));
       
   421     if (typeid(*left_type) == typeid(time_type_name_c) && typeid(*right_type) == typeid(time_type_name_c)) {return (void *)&time_type_name;}
       
   422     if (typeid(*left_type) == typeid(date_type_name_c) && typeid(*right_type) == typeid(date_type_name_c)) {return (void *)&time_type_name;}
       
   423     if (typeid(*left_type) == typeid(tod_type_name_c) && typeid(*right_type) == typeid(time_type_name_c)) {return (void *)&tod_type_name;}
       
   424     if (typeid(*left_type) == typeid(tod_type_name_c) && typeid(*right_type) == typeid(tod_type_name_c)) {return (void *)&time_type_name;}
       
   425     if (typeid(*left_type) == typeid(dt_type_name_c) && typeid(*right_type) == typeid(time_type_name_c)) {return (void *)&dt_type_name;}
       
   426     if (typeid(*left_type) == typeid(dt_type_name_c) && typeid(*right_type) == typeid(dt_type_name_c)) {return (void *)&time_type_name;}
       
   427     return compute_numeric_expression(left_type, right_type);
       
   428   }
       
   429   
       
   430   void *visit(mul_expression_c *symbol) {
       
   431     symbol_c *left_type = base_type((symbol_c *)symbol->l_exp->accept(*this));
       
   432     symbol_c *right_type = base_type((symbol_c *)symbol->r_exp->accept(*this));
       
   433     if (typeid(*left_type) == typeid(time_type_name_c) && is_num_type(right_type)) {
       
   434         return (void *)&time_type_name;
       
   435     }
       
   436     return compute_numeric_expression(left_type, right_type);
       
   437   }
       
   438   
       
   439   void *visit(div_expression_c *symbol) {
       
   440     symbol_c *left_type = base_type((symbol_c *)symbol->l_exp->accept(*this));
       
   441     symbol_c *right_type = base_type((symbol_c *)symbol->r_exp->accept(*this));
       
   442     if (typeid(*left_type) == typeid(time_type_name_c) && is_num_type(right_type)){
       
   443         return (void *)&time_type_name;
       
   444     }
       
   445     return compute_numeric_expression(left_type, right_type);
       
   446   }
       
   447 
       
   448   void *visit(mod_expression_c *symbol) {
       
   449     symbol_c *left_type = base_type((symbol_c *)symbol->l_exp->accept(*this));
       
   450     symbol_c *right_type = base_type((symbol_c *)symbol->r_exp->accept(*this));
       
   451     return compute_numeric_expression(left_type, right_type);
       
   452   }
       
   453 
       
   454   void *visit(power_expression_c *symbol) {
       
   455     symbol_c *left_type = base_type((symbol_c *)symbol->l_exp->accept(*this));
       
   456     symbol_c *right_type = base_type((symbol_c *)symbol->r_exp->accept(*this));
       
   457     if (is_real_type(left_type) && is_num_type(right_type)) {
       
   458         return (void *)left_type;
       
   459     }
       
   460     ERROR;
       
   461     return NULL;
       
   462   }
       
   463   
       
   464   void *visit(neg_expression_c *symbol) {
       
   465     symbol_c *exp_type = base_type((symbol_c *)symbol->exp->accept(*this));
       
   466     if (is_num_type(exp_type) || typeid(*exp_type) == typeid(time_type_name_c)){
       
   467             return (void *)exp_type;
       
   468          }
       
   469     ERROR;
       
   470     return NULL;
       
   471   }
       
   472   
       
   473   void *visit(not_expression_c *symbol) {
       
   474     symbol_c *exp_type = base_type((symbol_c *)symbol->exp->accept(*this));
       
   475     return compute_boolean_expression(exp_type, exp_type);
       
   476   }
       
   477   
       
   478   void *visit(function_invocation_c *symbol) {
       
   479 	  function_declaration_c *f_decl = function_symtable.find_value(symbol->function_name);
       
   480 	
       
   481 	  if (f_decl == function_symtable.end_value()) {
       
   482       void *res = compute_standard_function_st(symbol);
       
   483 	    if (res == NULL)
       
   484         ERROR;
       
   485       return res;
       
   486     }
       
   487 
       
   488     return base_type(f_decl->type_name);
       
   489   }
       
   490 
       
   491 };
       
   492 
       
   493 /*bool_type_name_c     search_expression_type_c::bool_type_name;*/
       
   494