stage4/generate_c/generate_c_inlinefcall.cc
changeset 683 2d96a47a75b1
parent 670 400bf52a2691
child 690 6156ee2b4e32
equal deleted inserted replaced
682:966f32af570d 683:2d96a47a75b1
     1 /*
     1 /*
     2  *  matiec - a compiler for the programming languages defined in IEC 61131-3
     2  *  matiec - a compiler for the programming languages defined in IEC 61131-3
     3  *
     3  *
     4  *  Copyright (C) 2003-2011  Mario de Sousa (msousa@fe.up.pt)
     4  *  Copyright (C) 2003-2012  Mario de Sousa (msousa@fe.up.pt)
     5  *  Copyright (C) 2007-2011  Laurent Bessard and Edouard Tisserant
     5  *  Copyright (C) 2007-2011  Laurent Bessard and Edouard Tisserant
     6  *
     6  *
     7  *  This program is free software: you can redistribute it and/or modify
     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
     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
     9  *  the Free Software Foundation, either version 3 of the License, or
    59 	 * parameter to the simple_instr_list_c visitor.
    59 	 * parameter to the simple_instr_list_c visitor.
    60 	 * Ergo, the existance of the following parameter...!
    60 	 * Ergo, the existance of the following parameter...!
    61 	 */
    61 	 */
    62 	symbol_c *il_default_variable_init_value;
    62 	symbol_c *il_default_variable_init_value;
    63 
    63 
    64     /* Operand to the IL operation currently being processed... */
       
    65 	/* These variables are used to pass data from the
       
    66 	 * il_simple_operation_c and il_expression_c visitors
       
    67 	 * to the il operator visitors (i.e. LD_operator_c,
       
    68 	 * LDN_operator_c, ST_operator_c, STN_operator_c, ...)
       
    69 	 */
       
    70 	symbol_c *current_operand;
       
    71 	symbol_c *current_operand_type;
       
    72 
       
    73 	 /* The result of the comparison IL operations (GT, EQ, LT, ...)
    64 	 /* The result of the comparison IL operations (GT, EQ, LT, ...)
    74 	 * is a boolean variable.
    65 	 * is a boolean variable.
    75 	 * This class keeps track of the current data type stored in the
    66 	 * This class keeps track of the current data type stored in the
    76 	 * il default variable. This is usually done by keeping a reference
    67 	 * il default variable. This is usually done by keeping a reference
    77 	 * to the data type of the last operand. Nevertheless, in the case of
    68 	 * to the data type of the last operand. Nevertheless, in the case of
    92 	/* The name of the variable used to pass the result of a
    83 	/* The name of the variable used to pass the result of a
    93 	 * parenthesised instruction list to the immediately preceding
    84 	 * parenthesised instruction list to the immediately preceding
    94 	 * scope ...
    85 	 * scope ...
    95 	 */
    86 	 */
    96     #define IL_DEFVAR_BACK   VAR_LEADER "IL_DEFVAR_BACK"
    87     #define IL_DEFVAR_BACK   VAR_LEADER "IL_DEFVAR_BACK"
    97     il_default_variable_c default_variable_name;
    88     il_default_variable_c implicit_variable_current;
    98 	il_default_variable_c default_variable_back_name;
    89 
    99 
    90     symbol_c* current_array_type;
   100 	symbol_c* current_array_type;
    91 
   101 
    92     int fcall_number;
   102 	int fcall_number;
    93     bool generating_inlinefunction;
   103 	bool generating_inlinefunction;
    94     symbol_c *fbname;
   104 	symbol_c *fbname;
       
   105 
    95 
   106     search_varfb_instance_type_c *search_varfb_instance_type;
    96     search_varfb_instance_type_c *search_varfb_instance_type;
   107     search_var_instance_decl_c   *search_var_instance_decl;
    97     search_var_instance_decl_c   *search_var_instance_decl;
   108 
    98 
   109     search_base_type_c search_base_type;
    99     search_base_type_c search_base_type;
   111     variablegeneration_t wanted_variablegeneration;
   101     variablegeneration_t wanted_variablegeneration;
   112 
   102 
   113   public:
   103   public:
   114     generate_c_inlinefcall_c(stage4out_c *s4o_ptr, symbol_c *name, symbol_c *scope, const char *variable_prefix = NULL)
   104     generate_c_inlinefcall_c(stage4out_c *s4o_ptr, symbol_c *name, symbol_c *scope, const char *variable_prefix = NULL)
   115     : generate_c_typedecl_c(s4o_ptr),
   105     : generate_c_typedecl_c(s4o_ptr),
   116       default_variable_name(IL_DEFVAR, NULL),
   106       implicit_variable_current(IL_DEFVAR, NULL)
   117       default_variable_back_name(IL_DEFVAR_BACK, NULL)
       
   118     {
   107     {
   119       search_varfb_instance_type = new search_varfb_instance_type_c(scope);
   108       search_varfb_instance_type = new search_varfb_instance_type_c(scope);
   120       search_var_instance_decl   = new search_var_instance_decl_c  (scope);
   109       search_var_instance_decl   = new search_var_instance_decl_c  (scope);
   121       
   110       
   122       this->set_variable_prefix(variable_prefix);
   111       this->set_variable_prefix(variable_prefix);
   123       current_operand = NULL;
       
   124       current_operand_type = NULL;
       
   125       il_default_variable_init_value = NULL;
   112       il_default_variable_init_value = NULL;
   126       fcall_number = 0;
   113       fcall_number = 0;
   127       fbname = name;
   114       fbname = name;
   128       wanted_variablegeneration = expression_vg;
   115       wanted_variablegeneration = expression_vg;
   129       generating_inlinefunction = false;
   116       generating_inlinefunction = false;
   276         return &search_constant_type_c::lreal_type_name;
   263         return &search_constant_type_c::lreal_type_name;
   277       }
   264       }
   278       return symbol;
   265       return symbol;
   279     }
   266     }
   280 
   267 
   281     /* A helper function... */
   268 
   282 	void CMP_operator_result_type() {
       
   283 	  /* the data type resulting from this operation... */
       
   284 	  this->default_variable_name.current_type = &(this->bool_type);
       
   285 	}
       
   286 
       
   287 	/* A helper function... */
       
   288     void BYTE_operator_result_type(void) {
       
   289 	  if (get_datatype_info_c::is_ANY_INT_literal(this->default_variable_name.current_type)) {
       
   290 		if (get_datatype_info_c::is_ANY_INT_literal(this->current_operand_type))
       
   291 		  this->default_variable_name.current_type = &(this->lword_type);
       
   292 		else
       
   293 		  this->default_variable_name.current_type = this->current_operand_type;
       
   294 	  }
       
   295 	  else if (get_datatype_info_c::is_ANY_INT_literal(this->current_operand_type))
       
   296 		  this->current_operand_type = this->default_variable_name.current_type;
       
   297 	}
       
   298 
       
   299     /* A helper function... */
       
   300     void NUM_operator_result_type(void) {
       
   301 	  if (get_datatype_info_c::is_ANY_REAL_literal(this->default_variable_name.current_type)) {
       
   302 		if (get_datatype_info_c::is_ANY_INT_literal(this->current_operand_type) ||
       
   303 			get_datatype_info_c::is_ANY_REAL_literal(this->current_operand_type))
       
   304 		  this->default_variable_name.current_type = &(this->lreal_type);
       
   305 		else
       
   306 		  this->default_variable_name.current_type = this->current_operand_type;
       
   307 	  }
       
   308 	  else if (get_datatype_info_c::is_ANY_INT_literal(this->default_variable_name.current_type)) {
       
   309 		if (get_datatype_info_c::is_ANY_INT_literal(this->current_operand_type))
       
   310 		  this->default_variable_name.current_type = &(this->lint_type);
       
   311 		else if (get_datatype_info_c::is_ANY_REAL_literal(this->current_operand_type))
       
   312 		  this->default_variable_name.current_type = &(this->lreal_type);
       
   313 		else
       
   314 		  this->default_variable_name.current_type = this->current_operand_type;
       
   315 	  }
       
   316 	  else if (get_datatype_info_c::is_ANY_INT_literal(this->current_operand_type) ||
       
   317 			   get_datatype_info_c::is_ANY_REAL_literal(this->current_operand_type))
       
   318 		this->current_operand_type = this->default_variable_name.current_type;
       
   319 	}
       
   320 
   269 
   321     void *print_getter(symbol_c *symbol) {
   270     void *print_getter(symbol_c *symbol) {
   322       unsigned int vartype = search_var_instance_decl->get_vartype(symbol);
   271       unsigned int vartype = search_var_instance_decl->get_vartype(symbol);
   323       if (vartype == search_var_instance_decl_c::external_vt)
   272       if (vartype == search_var_instance_decl_c::external_vt)
   324     	s4o.print(GET_EXTERNAL);
   273         s4o.print(GET_EXTERNAL);
   325       else if (vartype == search_var_instance_decl_c::located_vt)
   274       else if (vartype == search_var_instance_decl_c::located_vt)
   326     	s4o.print(GET_LOCATED);
   275         s4o.print(GET_LOCATED);
   327       else
   276       else
   328     	s4o.print(GET_VAR);
   277         s4o.print(GET_VAR);
   329       s4o.print("(");
   278       s4o.print("(");
   330 
   279 
   331       wanted_variablegeneration = complextype_base_vg;
   280       wanted_variablegeneration = complextype_base_vg;
   332       symbol->accept(*this);
   281       symbol->accept(*this);
   333       if (search_var_instance_decl->type_is_complex(symbol))
   282       if (search_var_instance_decl->type_is_complex(symbol))
   334     	s4o.print(",");
   283         s4o.print(",");
   335       wanted_variablegeneration = complextype_suffix_vg;
   284       wanted_variablegeneration = complextype_suffix_vg;
   336       symbol->accept(*this);
   285       symbol->accept(*this);
   337       s4o.print(")");
   286       s4o.print(")");
   338       wanted_variablegeneration = expression_vg;
   287       wanted_variablegeneration = expression_vg;
   339       return NULL;
   288       return NULL;
   468     /***********************************/
   417     /***********************************/
   469 
   418 
   470     /* | label ':' [il_incomplete_instruction] eol_list */
   419     /* | label ':' [il_incomplete_instruction] eol_list */
   471     // SYM_REF2(il_instruction_c, label, il_instruction)
   420     // SYM_REF2(il_instruction_c, label, il_instruction)
   472     void *visit(il_instruction_c *symbol) {
   421     void *visit(il_instruction_c *symbol) {
   473       if (NULL != symbol->il_instruction) {
   422       /* all previous IL instructions should have the same datatype (checked in stage3), so we get the datatype from the first previous IL instruction we find */
   474         symbol->il_instruction->accept(*this);
   423       implicit_variable_current.datatype = (symbol->prev_il_instruction.empty())? NULL : symbol->prev_il_instruction[0]->datatype;
   475       }
   424       if (NULL != symbol->il_instruction)  symbol->il_instruction->accept(*this); 
   476       return NULL;
   425       implicit_variable_current.datatype = NULL;
   477     }
   426       return NULL;
       
   427     }
       
   428 
   478 
   429 
   479     /* | il_simple_operator [il_operand] */
   430     /* | il_simple_operator [il_operand] */
   480     //SYM_REF2(il_simple_operation_c, il_simple_operator, il_operand)
   431     //SYM_REF2(il_simple_operation_c, il_simple_operator, il_operand)
   481     void *visit(il_simple_operation_c *symbol) {
   432     void *visit(il_simple_operation_c *symbol) {
   482       this->current_operand = symbol->il_operand;
       
   483       if (NULL == this->current_operand) {
       
   484         this->current_operand_type = NULL;
       
   485       } else {
       
   486         this->current_operand_type = this->current_operand->datatype;
       
   487         if (NULL == this->current_operand_type) ERROR;
       
   488       }
       
   489 
       
   490       symbol->il_simple_operator->accept(*this);
   433       symbol->il_simple_operator->accept(*this);
   491 
   434       return NULL;
   492       this->current_operand = NULL;
   435     }
   493       this->current_operand_type = NULL;
   436 
   494       return NULL;
       
   495     }
       
   496 
   437 
   497     void *visit(il_function_call_c *symbol) {
   438     void *visit(il_function_call_c *symbol) {
   498       symbol_c* function_type_prefix = NULL;
   439       symbol_c* function_type_prefix = NULL;
   499       symbol_c* function_name = NULL;     
   440       symbol_c* function_name = NULL;     
   500       symbol_c* function_type_suffix = NULL;
   441       symbol_c* function_type_suffix = NULL;
   501       DECLARE_PARAM_LIST()
   442       DECLARE_PARAM_LIST()
   502 
       
   503       symbol_c *param_data_type = default_variable_name.current_type;
       
   504 
   443 
   505       function_call_param_iterator_c function_call_param_iterator(symbol);
   444       function_call_param_iterator_c function_call_param_iterator(symbol);
   506 
   445 
   507       function_declaration_c *f_decl = (function_declaration_c *)symbol->called_function_declaration;
   446       function_declaration_c *f_decl = (function_declaration_c *)symbol->called_function_declaration;
   508       if (f_decl == NULL) ERROR;
   447       if (f_decl == NULL) ERROR;
   573          *
   512          *
   574          * However, if the parameter is an implicitly defined EN or ENO parameter, we should not
   513          * However, if the parameter is an implicitly defined EN or ENO parameter, we should not
   575          * use the default variable as a source of data to pass to those parameters!
   514          * use the default variable as a source of data to pass to those parameters!
   576          */
   515          */
   577         if ((param_value == NULL) && (!used_defvar) && !fp_iterator.is_en_eno_param_implicit()) {
   516         if ((param_value == NULL) && (!used_defvar) && !fp_iterator.is_en_eno_param_implicit()) {
   578           param_value = &this->default_variable_name;
   517 	  if (NULL == implicit_variable_current.datatype) ERROR;
       
   518           param_value = &this->implicit_variable_current;
   579           used_defvar = true;
   519           used_defvar = true;
   580         }
   520         }
   581 
   521 
   582         /* Get the value from a foo(<param_value>) style call */
   522         /* Get the value from a foo(<param_value>) style call */
   583         if ((param_value == NULL) && !fp_iterator.is_en_eno_param_implicit()) {
   523         if ((param_value == NULL) && !fp_iterator.is_en_eno_param_implicit()) {
   624 
   564 
   625       if (has_output_params)
   565       if (has_output_params)
   626         generate_inline(function_name, function_type_prefix, function_type_suffix, param_list, f_decl);
   566         generate_inline(function_name, function_type_prefix, function_type_suffix, param_list, f_decl);
   627 
   567 
   628       CLEAR_PARAM_LIST()
   568       CLEAR_PARAM_LIST()
   629 
   569       return NULL;
   630       /* the data type resulting from this operation... */
   570     }
   631       default_variable_name.current_type = function_type_prefix;
   571 
   632       return NULL;
   572 
   633     }
       
   634 
   573 
   635     /* | il_expr_operator '(' [il_operand] eol_list [simple_instr_list] ')' */
   574     /* | il_expr_operator '(' [il_operand] eol_list [simple_instr_list] ')' */
   636     //SYM_REF4(il_expression_c, il_expr_operator, il_operand, simple_instr_list, unused)
   575     //SYM_REF4(il_expression_c, il_expr_operator, il_operand, simple_instr_list, unused)
   637     void *visit(il_expression_c *symbol) {
   576     void *visit(il_expression_c *symbol) {
   638       /* We will be recursevely interpreting an instruction list,
   577       /* We will be recursevely interpreting an instruction list, so we store a backup of the implicit_variable_result/current.
   639        * so we store a backup of the data type of the value currently stored
   578        * Notice that they will be overwriten while processing the parenthsized instruction list.
   640        * in the default variable, and set the current data type to NULL
       
   641        */
   579        */
   642       symbol_c *old_current_default_variable_data_type = this->default_variable_name.current_type;
   580       // il_default_variable_c old_implicit_variable_current = this->implicit_variable_current;      // no longer needed!
   643       this->default_variable_name.current_type = NULL;
   581       
   644 
   582 
   645      /* Pass the symbol->il_operand to the simple_instr_list visitor
   583      /* Pass the symbol->il_operand to the simple_instr_list visitor
   646       * using the il_default_variable_init_value parameter...
   584       * using the il_default_variable_init_value parameter...
   647       * Note that the simple_instr_list_c visitor will set this parameter
   585       * Note that the simple_instr_list_c visitor will set this parameter
   648       * to NULL as soon as it does not require it any longer,
   586       * to NULL as soon as it does not require it any longer,
   651       * returns...
   589       * returns...
   652       */
   590       */
   653       this->il_default_variable_init_value = symbol->il_operand;
   591       this->il_default_variable_init_value = symbol->il_operand;
   654 
   592 
   655       /* Now do the parenthesised instructions... */
   593       /* Now do the parenthesised instructions... */
   656       /* NOTE: the following code line will get the variable
   594       /* NOTE: the following code line will get the variable this->implicit_variable_current.datatype updated!  */
   657        * this->default_variable_name.current_type updated!
       
   658        */
       
   659       symbol->simple_instr_list->accept(*this);
   595       symbol->simple_instr_list->accept(*this);
   660 
   596 
   661       /* Now do the operation, using the previous result! */
   597       /* Now do the operation, using the previous result! */
   662       /* NOTE: The result of the previous instruction list will be stored
   598       /* NOTE: Actually, we do not need to call this, as it can never be a function call, which is what we are handling here... */
   663        * in a variable named IL_DEFVAR_BACK. This is done in the visitor
   599       // this->implicit_variable_current.datatype = old_current_default_variable_data_type;
   664        * to instruction_list_c objects...
   600       // symbol->il_expr_operator->accept(*this);
   665        */
   601       return NULL;
   666       this->current_operand = &(this->default_variable_back_name);
   602     }
   667       this->current_operand_type = this->default_variable_back_name.current_type;
   603 
   668 
       
   669       this->default_variable_name.current_type = old_current_default_variable_data_type;
       
   670       if (NULL == this->current_operand_type) ERROR;
       
   671 
       
   672       symbol->il_expr_operator->accept(*this);
       
   673 
       
   674       this->current_operand = NULL;
       
   675       this->current_operand_type = NULL;
       
   676       this->default_variable_back_name.current_type = NULL;
       
   677       return NULL;
       
   678     }
       
   679 
   604 
   680     /* | function_name '(' eol_list [il_param_list] ')' */
   605     /* | function_name '(' eol_list [il_param_list] ')' */
   681     // SYM_REF2(il_formal_funct_call_c, function_name, il_param_list)
   606     // SYM_REF2(il_formal_funct_call_c, function_name, il_param_list)
   682     void *visit(il_formal_funct_call_c *symbol) {
   607     void *visit(il_formal_funct_call_c *symbol) {
   683       symbol_c* function_type_prefix = NULL;
   608       symbol_c* function_type_prefix = NULL;
   805 
   730 
   806       if (has_output_params)
   731       if (has_output_params)
   807         generate_inline(function_name, function_type_prefix, function_type_suffix, param_list, f_decl);
   732         generate_inline(function_name, function_type_prefix, function_type_suffix, param_list, f_decl);
   808 
   733 
   809       CLEAR_PARAM_LIST()
   734       CLEAR_PARAM_LIST()
   810 
   735       return NULL;
   811       /* the data type resulting from this operation... */
   736     }
   812       default_variable_name.current_type = function_type_prefix;
   737 
   813       return NULL;
   738 
   814     }
       
   815 
   739 
   816     /* | simple_instr_list il_simple_instruction */
   740     /* | simple_instr_list il_simple_instruction */
   817     // SYM_LIST(simple_instr_list_c)
   741     // SYM_LIST(simple_instr_list_c)
   818     void *visit(simple_instr_list_c *symbol) {
   742     void *visit(simple_instr_list_c *symbol) {
   819       /* Check whether we should initiliase the il default variable... */
   743       /* Check whether we should initiliase the il default variable... */
   820       if (NULL != this->il_default_variable_init_value) {
   744       // TODO: fix the way we handle this... It is currently not working!!
   821         /* Yes, we must... */
   745 //      if (NULL != this->il_default_variable_init_value)   implicit_variable_current = il_default_variable_init_value;
   822         /* We will do it by instatiating a LD operator, and having this
   746       this->il_default_variable_init_value = NULL;       // this parameter no longer required...
   823          * same generate_c_il_c class visiting it!
       
   824          */
       
   825         LD_operator_c ld_oper;
       
   826         il_simple_operation_c il_simple_oper(&ld_oper, this->il_default_variable_init_value);
       
   827 
       
   828         il_simple_oper.accept(*this);
       
   829       }
       
   830 
       
   831       /* this parameter no longer required... */
       
   832       this->il_default_variable_init_value = NULL;
       
   833 
   747 
   834       iterator_visitor_c::visit(symbol);
   748       iterator_visitor_c::visit(symbol);
   835 
   749       return NULL;
   836       /* copy the result in the default variable to the variable
   750     }
   837 	   * used to pass the data out to the scope enclosing
   751 
   838 	   * the current scope!
   752 
   839 	   *
       
   840 	   * We also need to update the data type currently stored within
       
   841 	   * the variable used to pass the data to the outside scope...
       
   842 	   */
       
   843 	  this->default_variable_back_name.current_type = this->default_variable_name.current_type;
       
   844 	  return NULL;
       
   845     }
       
   846     
       
   847     // SYM_REF1(il_simple_instruction_c, il_simple_instruction, symbol_c *prev_il_instruction;)
   753     // SYM_REF1(il_simple_instruction_c, il_simple_instruction, symbol_c *prev_il_instruction;)
   848     void *visit(il_simple_instruction_c *symbol)	{
   754     void *visit(il_simple_instruction_c *symbol)	{
   849       return symbol->il_simple_instruction->accept(*this);
   755       return symbol->il_simple_instruction->accept(*this);
   850     }
   756     }
   851 
   757 
   852     void *visit(LD_operator_c *symbol)	{
   758 
   853       /* the data type resulting from this operation... */
       
   854       this->default_variable_name.current_type = this->current_operand_type;
       
   855       return NULL;
       
   856     }
       
   857 
       
   858     void *visit(LDN_operator_c *symbol)	{
       
   859       /* the data type resulting from this operation... */
       
   860       this->default_variable_name.current_type = this->current_operand_type;
       
   861       return NULL;
       
   862     }
       
   863 
       
   864     void *visit(AND_operator_c *symbol)	{
       
   865       if (get_datatype_info_c::is_ANY_BIT_compatible(this->default_variable_name.current_type)) {
       
   866     	BYTE_operator_result_type();
       
   867       }
       
   868       else {ERROR;}
       
   869       return NULL;
       
   870     }
       
   871 
       
   872     void *visit(OR_operator_c *symbol)	{
       
   873       if (get_datatype_info_c::is_ANY_BIT_compatible(this->default_variable_name.current_type)) {
       
   874     	BYTE_operator_result_type();
       
   875       }
       
   876       else {ERROR;}
       
   877       return NULL;
       
   878     }
       
   879 
       
   880     void *visit(XOR_operator_c *symbol)	{
       
   881       if (get_datatype_info_c::is_ANY_BIT_compatible(this->default_variable_name.current_type)) {
       
   882     	BYTE_operator_result_type();
       
   883       }
       
   884       else {ERROR;}
       
   885       return NULL;
       
   886     }
       
   887 
       
   888     void *visit(ANDN_operator_c *symbol)	{
       
   889       if (get_datatype_info_c::is_ANY_BIT_compatible(this->default_variable_name.current_type)) {
       
   890     	BYTE_operator_result_type();
       
   891       }
       
   892       else {ERROR;}
       
   893       return NULL;
       
   894     }
       
   895 
       
   896     void *visit(ORN_operator_c *symbol)	{
       
   897       if (get_datatype_info_c::is_ANY_BIT_compatible(this->default_variable_name.current_type)) {
       
   898     	BYTE_operator_result_type();
       
   899       }
       
   900       else {ERROR;}
       
   901       return NULL;
       
   902     }
       
   903 
       
   904     void *visit(XORN_operator_c *symbol)	{
       
   905       if (get_datatype_info_c::is_ANY_BIT_compatible(this->default_variable_name.current_type)) {
       
   906     	BYTE_operator_result_type();
       
   907       }
       
   908       else {ERROR;}
       
   909       return NULL;
       
   910     }
       
   911 
       
   912     void *visit(ADD_operator_c *symbol)	{
       
   913       if (get_datatype_info_c::is_TIME_compatible      (symbol->datatype) ||
       
   914           get_datatype_info_c::is_ANY_DATE_compatible  (symbol->datatype)) {
       
   915         /* the data type resulting from this operation... */
       
   916         this->default_variable_name.current_type = this->current_operand_type;
       
   917       } else {
       
   918         NUM_operator_result_type();
       
   919       }
       
   920       return NULL;
       
   921     }
       
   922 
       
   923     void *visit(SUB_operator_c *symbol)	{
       
   924       if (get_datatype_info_c::is_TIME_compatible      (symbol->datatype) ||
       
   925           get_datatype_info_c::is_ANY_DATE_compatible  (symbol->datatype)) {
       
   926         /* the data type resulting from this operation... */
       
   927         this->default_variable_name.current_type = this->current_operand_type;
       
   928       } else {
       
   929         NUM_operator_result_type();
       
   930       }
       
   931       return NULL;
       
   932     }
       
   933 
       
   934     void *visit(MUL_operator_c *symbol)	{
       
   935       if (get_datatype_info_c::is_TIME_compatible      (symbol->datatype)) {
       
   936         /* the data type resulting from this operation is unchanged! */
       
   937       } else {
       
   938         NUM_operator_result_type();
       
   939       }
       
   940       return NULL;
       
   941     }
       
   942 
       
   943     void *visit(DIV_operator_c *symbol)	{
       
   944       if (get_datatype_info_c::is_TIME_compatible      (symbol->datatype)) {
       
   945         /* the data type resulting from this operation is unchanged! */
       
   946       } else {
       
   947         NUM_operator_result_type();
       
   948       }
       
   949       return NULL;
       
   950     }
       
   951 
       
   952     void *visit(MOD_operator_c *symbol)	{
       
   953       NUM_operator_result_type();
       
   954       return NULL;
       
   955     }
       
   956 
       
   957     void *visit(GT_operator_c *symbol)	{CMP_operator_result_type(); return NULL;}
       
   958     void *visit(GE_operator_c *symbol)	{CMP_operator_result_type(); return NULL;}
       
   959     void *visit(EQ_operator_c *symbol)	{CMP_operator_result_type(); return NULL;}
       
   960     void *visit(LT_operator_c *symbol)	{CMP_operator_result_type(); return NULL;}
       
   961     void *visit(LE_operator_c *symbol)	{CMP_operator_result_type(); return NULL;}
       
   962     void *visit(NE_operator_c *symbol)	{CMP_operator_result_type(); return NULL;}
       
   963 
   759 
   964     /***************************************/
   760     /***************************************/
   965     /* B.3 - Language ST (Structured Text) */
   761     /* B.3 - Language ST (Structured Text) */
   966     /***************************************/
   762     /***************************************/
   967     /***********************/
   763     /***********************/