stage4/generate_c/generate_c_il.cc
changeset 682 966f32af570d
parent 669 7049fd6fe515
child 683 2d96a47a75b1
equal deleted inserted replaced
681:e837adad2437 682:966f32af570d
    46 /***********************************************************************/
    46 /***********************************************************************/
    47 /***********************************************************************/
    47 /***********************************************************************/
    48 /***********************************************************************/
    48 /***********************************************************************/
    49 
    49 
    50 
    50 
    51 /* A new class to ouput the il default variable to c++ code
    51 /* A new class to ouput the IL implicit variable to c++ code
    52  * We use this class, inheriting from symbol_c, so it may be used
    52  * We use this class, inheriting from symbol_c, so it may be used
    53  * as any other symbol_c object in the intermediate parse tree,
    53  * as any other symbol_c object in the intermediate parse tree,
    54  * more specifically, so it can be used as any other il operand.
    54  * more specifically, so it can be used as any other il operand.
    55  * This makes the rest of the code much easier...
    55  * This makes the rest of the code much easier...
    56  *
    56  *
    75     virtual ~il_default_variable_visitor_c(void) {return;}
    75     virtual ~il_default_variable_visitor_c(void) {return;}
    76 };
    76 };
    77 
    77 
    78 
    78 
    79 /* A class to print out to the resulting C++ code
    79 /* A class to print out to the resulting C++ code
    80  * the IL default variable name.
    80  * the IL implicit variable name.
    81  *
    81  *
    82  * It includes a reference to its name,
    82  * It includes a reference to its name,
    83  * and the data type of the data currently stored
    83  * and the data type of the data currently stored
    84  * in this C++ variable... This is required because the
    84  * in this C++ variable... This is required because the
    85  * C++ variable is a union, and we must know which member
    85  * C++ variable is a union, and we must know which member
    86  * of the union top reference!!
    86  * of the union top reference!!
    87  *
    87  *
    88  * Note that we also need to keep track of the data type of
    88  * Note that we also need to keep track of the data type of
    89  * the value currently being stored in the default variable.
    89  * the value currently being stored in the IL implicit variable.
    90  * This is required so we can process parenthesis,
    90  * This is required so we can process parenthesis,
    91  *
    91  *
    92  * e.g. :
    92  * e.g. :
    93  *         LD var1
    93  *         LD var1
    94  *         AND (
    94  *         AND (
   100  * the ')', i.e. once we have evaluated the result of the
   100  * the ')', i.e. once we have evaluated the result of the
   101  * instructions inside the parenthesis.
   101  * instructions inside the parenthesis.
   102  * When we do execute the 'AND (' operation, we need to know the data type
   102  * When we do execute the 'AND (' operation, we need to know the data type
   103  * of the operand, which in this case is the result of the evaluation of the
   103  * of the operand, which in this case is the result of the evaluation of the
   104  * instruction list inside the parenthesis. We can only know this if we
   104  * instruction list inside the parenthesis. We can only know this if we
   105  * keep track of the data type currently stored in the default variable!
   105  * keep track of the data type currently stored in the IL implicit variable!
   106  *
   106  *
   107  * We use the current_type inside the generate_c_il::default_variable_name variable
   107  * We use the current_type inside the generate_c_il::default_variable_name variable
   108  * to track this!
   108  * to track this!
   109  */
   109  */
   110 class il_default_variable_c: public symbol_c {
   110 class il_default_variable_c: public symbol_c {
   111   public:
   111   public:
   112     symbol_c *var_name;  /* in principle, this should point to an indentifier_c */
   112     symbol_c *var_name;  /* in principle, this should point to an indentifier_c */
   113     symbol_c *current_type;
       
   114 
   113 
   115   public:
   114   public:
   116     il_default_variable_c(const char *var_name_str, symbol_c *current_type);
   115     il_default_variable_c(const char *var_name_str, symbol_c *current_type);
   117     virtual void *accept(visitor_c &visitor);
   116     virtual void *accept(visitor_c &visitor);
   118 };
   117 };
   138       complextype_suffix_vg,
   137       complextype_suffix_vg,
   139       fparam_output_vg
   138       fparam_output_vg
   140     } variablegeneration_t;
   139     } variablegeneration_t;
   141 
   140 
   142   private:
   141   private:
   143     /* The initial value that should be given to the IL default variable
   142     /* Label to which the current IL jump operation should jump to... */
   144      * imediately after a parenthesis is opened.
   143     /* This variable is used to pass data from the
   145      * This variable is only used to pass data from the
   144      * il_jump_operation_c visitor
   146      * il_expression_c visitor to the simple_instr_list_c visitor.
   145      * to the il jump operator visitors (i.e. JMP_operator_c,
   147      *
   146      * JMPC_operator_c, JMPCN_operator_c, ...)
   148      * e.g.:
       
   149      *         LD var1
       
   150      *         AND ( var2
       
   151      *         OR var3
       
   152      *         )
       
   153      *
       
   154      * In the above code sample, the line 'AND ( var2' constitutes
       
   155      * an il_expression_c, where var2 should be loaded into the
       
   156      * il default variable before continuing with the expression
       
   157      * inside the parenthesis.
       
   158      * Unfortunately, only the simple_instr_list_c may do the
       
   159      * initial laoding of the var2 bariable following the parenthesis,
       
   160      * so the il_expression_c visitor will have to pass 'var2' as a
       
   161      * parameter to the simple_instr_list_c visitor.
       
   162      * Ergo, the existance of the following parameter...!
       
   163      */
   147      */
   164     symbol_c *il_default_variable_init_value;
   148     symbol_c *jump_label;
   165 
   149 
       
   150     /* the data type of the IL implicit variable... */
       
   151     #define IL_DEFVAR_T VAR_LEADER "IL_DEFVAR_T"
       
   152     /* The name of the IL implicit variable... */
       
   153     #define IL_DEFVAR   VAR_LEADER "IL_DEFVAR"
       
   154     /* The name of the variable used to pass the result of a
       
   155      * parenthesised instruction list to the immediately preceding
       
   156      * scope ...
       
   157      */
       
   158     #define IL_DEFVAR_BACK   VAR_LEADER "IL_DEFVAR_BACK"
       
   159     
       
   160     il_default_variable_c implicit_variable_current;      /* the current   implicit variable, with the datatype resulting from the previous IL operation */
       
   161     il_default_variable_c implicit_variable_result;       /* the resulting implicit variable, with the datatype resulting from the current  IL operation */
       
   162     il_default_variable_c implicit_variable_result_back;
       
   163     
   166     /* Operand to the IL operation currently being processed... */
   164     /* Operand to the IL operation currently being processed... */
   167     /* These variables are used to pass data from the
   165     /* These variables are used to pass data from the
   168      * il_simple_operation_c and il_expression_c visitors
   166      * il_simple_operation_c and il_expression_c visitors
   169      * to the il operator visitors (i.e. LD_operator_c,
   167      * to the il operator visitors (i.e. LD_operator_c,
   170      * LDN_operator_c, ST_operator_c, STN_operator_c, ...)
   168      * LDN_operator_c, ST_operator_c, STN_operator_c, ...)
   171      */
   169      */
   172     symbol_c *current_operand;
   170     symbol_c *current_operand;
   173     symbol_c *current_operand_type;
       
   174 
       
   175     /* Label to which the current IL jump operation should jump to... */
       
   176     /* This variable is used to pass data from the
       
   177      * il_jump_operation_c visitor
       
   178      * to the il jump operator visitors (i.e. JMP_operator_c,
       
   179      * JMPC_operator_c, JMPCN_operator_c, ...)
       
   180      */
       
   181     symbol_c *jump_label;
       
   182 
       
   183     /* The result of the comparison IL operations (GT, EQ, LT, ...)
       
   184      * is a boolean variable.
       
   185      * This class keeps track of the current data type stored in the
       
   186      * il default variable. This is usually done by keeping a reference
       
   187      * to the data type of the last operand. Nevertheless, in the case of
       
   188      * the comparison IL operators, the data type of the result (a boolean)
       
   189      * is not the data type of the operand. We therefore need an object
       
   190      * of the boolean data type to keep as a reference of the current
       
   191      * data type.
       
   192      * The following object is it...
       
   193      */
       
   194     bool_type_name_c bool_type;
       
   195     lint_type_name_c lint_type;
       
   196     lword_type_name_c lword_type;
       
   197     lreal_type_name_c lreal_type;
       
   198 
       
   199     /* the data type of the IL default variable... */
       
   200     #define IL_DEFVAR_T VAR_LEADER "IL_DEFVAR_T"
       
   201     /* The name of the IL default variable... */
       
   202     #define IL_DEFVAR   VAR_LEADER "IL_DEFVAR"
       
   203     /* The name of the variable used to pass the result of a
       
   204      * parenthesised instruction list to the immediately preceding
       
   205      * scope ...
       
   206      */
       
   207     #define IL_DEFVAR_BACK   VAR_LEADER "IL_DEFVAR_BACK"
       
   208     il_default_variable_c default_variable_name;
       
   209     il_default_variable_c default_variable_back_name;
       
   210 
   171 
   211     /* When calling a function block, we must first find it's type,
   172     /* When calling a function block, we must first find it's type,
   212      * by searching through the declarations of the variables currently
   173      * by searching through the declarations of the variables currently
   213      * in scope.
   174      * in scope.
   214      * This class does just that...
   175      * This class does just that...
   235     variablegeneration_t wanted_variablegeneration;
   196     variablegeneration_t wanted_variablegeneration;
   236 
   197 
   237   public:
   198   public:
   238     generate_c_il_c(stage4out_c *s4o_ptr, symbol_c *name, symbol_c *scope, const char *variable_prefix = NULL)
   199     generate_c_il_c(stage4out_c *s4o_ptr, symbol_c *name, symbol_c *scope, const char *variable_prefix = NULL)
   239     : generate_c_typedecl_c(s4o_ptr),
   200     : generate_c_typedecl_c(s4o_ptr),
   240       default_variable_name(IL_DEFVAR, NULL),
   201       implicit_variable_current    (IL_DEFVAR,      NULL),
   241       default_variable_back_name(IL_DEFVAR_BACK, NULL)
   202       implicit_variable_result     (IL_DEFVAR,      NULL),
       
   203       implicit_variable_result_back(IL_DEFVAR_BACK, NULL)
   242     {
   204     {
   243       search_fb_instance_decl    = new search_fb_instance_decl_c   (scope);
   205       search_fb_instance_decl    = new search_fb_instance_decl_c   (scope);
   244       search_varfb_instance_type = new search_varfb_instance_type_c(scope);
   206       search_varfb_instance_type = new search_varfb_instance_type_c(scope);
   245       search_var_instance_decl   = new search_var_instance_decl_c  (scope);
   207       search_var_instance_decl   = new search_var_instance_decl_c  (scope);
   246       
   208       
   247       current_operand = NULL;
   209       current_operand = NULL;
   248       current_operand_type = NULL;
       
   249       il_default_variable_init_value = NULL;
       
   250       current_array_type = NULL;
   210       current_array_type = NULL;
   251       current_param_type = NULL;
   211       current_param_type = NULL;
   252       fcall_number = 0;
   212       fcall_number = 0;
   253       fbname = name;
   213       fbname = name;
   254       wanted_variablegeneration = expression_vg;
   214       wanted_variablegeneration = expression_vg;
   263 
   223 
   264     void generate(instruction_list_c *il) {
   224     void generate(instruction_list_c *il) {
   265       il->accept(*this);
   225       il->accept(*this);
   266     }
   226     }
   267 
   227 
   268     /* Declare the backup to the default variable, that will store the result
   228   private:
   269      * of the IL operations executed inside a parenthesis...
   229     /* Declare an implicit IL variable... */
   270      */
   230     void declare_implicit_variable(il_default_variable_c *implicit_var) {
   271     void declare_backup_variable(void) {
       
   272       s4o.print(s4o.indent_spaces);
   231       s4o.print(s4o.indent_spaces);
   273       s4o.print(IL_DEFVAR_T);
   232       s4o.print(IL_DEFVAR_T);
   274       s4o.print(" ");
   233       s4o.print(" ");
   275       print_backup_variable();
   234       implicit_var->datatype = NULL;
       
   235       implicit_var->accept(*this);
   276       s4o.print(";\n");
   236       s4o.print(";\n");
   277     }
   237     }
   278     
   238     
   279     void print_backup_variable(void) {
   239   public:  
   280       this->default_variable_back_name.accept(*this);
   240     /* Declare the default variable, that will store the result of the IL operations */
   281     }
   241     void declare_implicit_variable(void) {
   282 
   242       declare_implicit_variable(&this->implicit_variable_result);
   283     void reset_default_variable_name(void) {
   243     }
   284       this->default_variable_name.current_type = NULL;
   244     
   285       this->default_variable_back_name.current_type = NULL;
   245     /* Declare the backup to the default variable, that will store the result of the IL operations executed inside a parenthesis... */
   286     }
   246     void declare_implicit_variable_back(void) {
       
   247       declare_implicit_variable(&this->implicit_variable_result_back);
       
   248     }
       
   249     
       
   250     void print_implicit_variable_back(void) {
       
   251       this->implicit_variable_result_back.accept(*this);
       
   252     }    
       
   253 
   287 
   254 
   288   private:
   255   private:
   289     /* a small helper function */
   256     /* a small helper function */
   290     symbol_c *default_literal_type(symbol_c *symbol) {
   257     symbol_c *default_literal_type(symbol_c *symbol) {
   291       if (get_datatype_info_c::is_ANY_INT_literal(symbol)) {
   258       if (get_datatype_info_c::is_ANY_INT_literal(symbol)) {
   306       ro->accept(*this);
   273       ro->accept(*this);
   307       return NULL;
   274       return NULL;
   308     }
   275     }
   309 
   276 
   310     /* A helper function... */
   277     /* A helper function... */
   311     void *XXX_function(const char *func, symbol_c *lo, symbol_c *ro) {
   278     void *XXX_function(symbol_c *res, const char *func, symbol_c *lo, symbol_c *ro) {
   312       if ((NULL == lo) || (NULL == ro)) ERROR;
   279       if ((NULL == res) || (NULL == lo) || (NULL == ro)) ERROR;
   313       if (NULL == func) ERROR;
   280       if  (NULL == func) ERROR;
   314 
   281 
   315       lo->accept(*this);
   282       res->accept(*this);
   316       s4o.print(" = ");
   283       s4o.print(" = ");
   317       s4o.print(func);
   284       s4o.print(func);
   318       s4o.print("(");
   285       s4o.print("(");
   319       lo->accept(*this);
   286       lo->accept(*this);
   320       s4o.print(", ");
   287       s4o.print(", ");
   321       ro->accept(*this);
   288       ro->accept(*this);
   322       s4o.print(")");
   289       s4o.print(")");
   323       return NULL;
   290       return NULL;
   324     }
   291     }
   325 
   292 
   326     /* A helper function... */
   293     /* A helper function... used for implicit FB calls: S1, R1, CLK, CU, CD, PV, IN, and PT */
   327     void *XXX_CAL_operator(const char *param_name, symbol_c *fb_name) {
   294     void *XXX_CAL_operator(const char *param_name, symbol_c *fb_name) {
   328       if (wanted_variablegeneration != expression_vg) {
   295       if (wanted_variablegeneration != expression_vg) {
   329         s4o.print(param_name);
   296         s4o.print(param_name);
   330         return NULL;
   297         return NULL;
   331       }
   298       }
   338       
   305       
   339       identifier_c param(param_name);
   306       identifier_c param(param_name);
   340 
   307 
   341       //SYM_REF3(il_param_assignment_c, il_assign_operator, il_operand, simple_instr_list)
   308       //SYM_REF3(il_param_assignment_c, il_assign_operator, il_operand, simple_instr_list)
   342       il_assign_operator_c il_assign_operator(&param);
   309       il_assign_operator_c il_assign_operator(&param);
   343       il_param_assignment_c il_param_assignment(&il_assign_operator, &this->default_variable_name, NULL);
   310       il_param_assignment_c il_param_assignment(&il_assign_operator, &this->implicit_variable_current, NULL);
   344       // SYM_LIST(il_param_list_c)
   311       // SYM_LIST(il_param_list_c)
   345       il_param_list_c il_param_list;   
   312       il_param_list_c il_param_list;   
   346       il_param_list.add_element(&il_param_assignment);
   313       il_param_list.add_element(&il_param_assignment);
   347       CAL_operator_c CAL_operator;
   314       CAL_operator_c CAL_operator;
   348       // SYM_REF4(il_fb_call_c, il_call_operator, fb_name, il_operand_list, il_param_list)
   315       // SYM_REF4(il_fb_call_c, il_call_operator, fb_name, il_operand_list, il_param_list)
   351       il_fb_call.accept(*this);
   318       il_fb_call.accept(*this);
   352       return NULL;
   319       return NULL;
   353     }
   320     }
   354 
   321 
   355     /* A helper function... */
   322     /* A helper function... */
   356     void *CMP_operator(symbol_c *o, const char *operation) {
   323     void *CMP_operator(symbol_c *operand, const char *operation) {
   357       if (NULL == o) ERROR;
   324       if (NULL == operand) ERROR;
   358       if (NULL == this->default_variable_name.current_type) ERROR;
   325       if (NULL == operand->datatype) ERROR;
   359 
   326       if (NULL == this->implicit_variable_current.datatype) ERROR;
   360       symbol_c *backup = this->default_variable_name.current_type;
   327 
   361       this->default_variable_name.current_type = &(this->bool_type);
   328       this->implicit_variable_result.accept(*this);
   362       this->default_variable_name.accept(*this);
       
   363       this->default_variable_name.current_type = backup;
       
   364 
       
   365       s4o.print(" = ");
   329       s4o.print(" = ");
   366       s4o.print(operation);
   330       s4o.print(operation);
   367       this->default_variable_name.current_type->accept(*this);
   331       operand->datatype->accept(*this);
       
   332       /* NOTE: we are calling a standard Function: 
       
   333        *         1st parameter: EN  (enable)
       
   334        *         2nd parameter: ENO (enable output)
       
   335        *         3rd parameter: number of operands we will be passing (required because we are calling an extensible standard function!)
       
   336        *         4th parameter: the left  hand side of the comparison expression (in out case, the IL implicit variable)
       
   337        *         4th parameter: the right hand side of the comparison expression (in out case, current operand)
       
   338        */
   368       s4o.print("(__BOOL_LITERAL(TRUE), NULL, 2, ");
   339       s4o.print("(__BOOL_LITERAL(TRUE), NULL, 2, ");
   369       this->default_variable_name.accept(*this);
   340       this->implicit_variable_current.accept(*this);
   370       s4o.print(", ");
   341       s4o.print(", ");
   371       o->accept(*this);
   342       operand->accept(*this);
   372       s4o.print(")");
   343       s4o.print(")");
   373 
   344 
   374       /* the data type resulting from this operation... */
       
   375       this->default_variable_name.current_type = &(this->bool_type);
       
   376       return NULL;
   345       return NULL;
   377     }
   346     }
   378 
   347 
   379 
   348 
   380     /* A helper function... */
   349     /* A helper function... */
   381     void C_modifier(void) {
   350     void C_modifier(void) {
   382       if (get_datatype_info_c::is_BOOL_compatible(default_variable_name.current_type)) {
   351       if (!get_datatype_info_c::is_BOOL_compatible(implicit_variable_current.datatype)) ERROR;
   383         s4o.print("if (");
   352       s4o.print("if (");
   384         this->default_variable_name.accept(*this);
   353       this->implicit_variable_current.accept(*this);
   385         s4o.print(") ");
   354       s4o.print(") ");
   386       }
       
   387       else {ERROR;}
       
   388     }
   355     }
   389 
   356 
   390     /* A helper function... */
   357     /* A helper function... */
   391     void CN_modifier(void) {
   358     void CN_modifier(void) {
   392       if (get_datatype_info_c::is_BOOL_compatible(default_variable_name.current_type)) {
   359       if (!get_datatype_info_c::is_BOOL_compatible(implicit_variable_current.datatype)) ERROR;
   393         s4o.print("if (!");
   360       s4o.print("if (!");
   394         this->default_variable_name.accept(*this);
   361       this->implicit_variable_current.accept(*this);
   395         s4o.print(") ");
   362       s4o.print(") ");
   396       }
   363     }
   397       else {ERROR;}
   364 
   398     }
       
   399 
       
   400     void BYTE_operator_result_type(void) {
       
   401       if (get_datatype_info_c::is_ANY_INT_literal(this->default_variable_name.current_type)) {
       
   402         if (get_datatype_info_c::is_ANY_INT_literal(this->current_operand_type))
       
   403           this->default_variable_name.current_type = &(this->lword_type);
       
   404         else
       
   405           this->default_variable_name.current_type = this->current_operand_type;
       
   406       }
       
   407       else if (get_datatype_info_c::is_ANY_INT_literal(this->current_operand_type))
       
   408     	  this->current_operand_type = this->default_variable_name.current_type;
       
   409     }
       
   410 
       
   411     void NUM_operator_result_type(void) {
       
   412       if (get_datatype_info_c::is_ANY_REAL_literal(this->default_variable_name.current_type)) {
       
   413         if (get_datatype_info_c::is_ANY_INT_literal(this->current_operand_type) ||
       
   414             get_datatype_info_c::is_ANY_REAL_literal(this->current_operand_type))
       
   415           this->default_variable_name.current_type = &(this->lreal_type);
       
   416         else
       
   417           this->default_variable_name.current_type = this->current_operand_type;
       
   418       }
       
   419       else if (get_datatype_info_c::is_ANY_INT_literal(this->default_variable_name.current_type)) {
       
   420         if (get_datatype_info_c::is_ANY_INT_literal(this->current_operand_type))
       
   421           this->default_variable_name.current_type = &(this->lint_type);
       
   422         else if (get_datatype_info_c::is_ANY_REAL_literal(this->current_operand_type))
       
   423           this->default_variable_name.current_type = &(this->lreal_type);
       
   424         else
       
   425           this->default_variable_name.current_type = this->current_operand_type;
       
   426       }
       
   427       else if (get_datatype_info_c::is_ANY_INT_literal(this->current_operand_type) ||
       
   428                get_datatype_info_c::is_ANY_REAL_literal(this->current_operand_type))
       
   429         this->current_operand_type = this->default_variable_name.current_type;
       
   430     }
       
   431 
   365 
   432     void *print_getter(symbol_c *symbol) {
   366     void *print_getter(symbol_c *symbol) {
   433       unsigned int vartype = search_var_instance_decl->get_vartype(symbol);
   367       unsigned int vartype = search_var_instance_decl->get_vartype(symbol);
   434       if (wanted_variablegeneration == fparam_output_vg) {
   368       if (wanted_variablegeneration == fparam_output_vg) {
   435       	if (vartype == search_var_instance_decl_c::external_vt)
   369       	if (vartype == search_var_instance_decl_c::external_vt)
   494         wanted_variablegeneration = assignment_vg;
   428         wanted_variablegeneration = assignment_vg;
   495 
   429 
   496       symbol->accept(*this);
   430       symbol->accept(*this);
   497       s4o.print(",");
   431       s4o.print(",");
   498       if (negative) {
   432       if (negative) {
   499 	    if (get_datatype_info_c::is_BOOL_compatible(this->current_operand_type))
   433 	    if (get_datatype_info_c::is_BOOL_compatible(this->current_operand->datatype))
   500 		  s4o.print("!");
   434 		  s4o.print("!");
   501 	    else
   435 	    else
   502 		  s4o.print("~");
   436 		  s4o.print("~");
   503       }
   437       }
   504       wanted_variablegeneration = expression_vg;
   438       wanted_variablegeneration = expression_vg;
   514     }
   448     }
   515 
   449 
   516 public:
   450 public:
   517 void *visit(il_default_variable_c *symbol) {
   451 void *visit(il_default_variable_c *symbol) {
   518   symbol->var_name->accept(*this);
   452   symbol->var_name->accept(*this);
   519   if (NULL != symbol->current_type) {
   453   if (NULL != symbol->datatype) {
   520     s4o.print(".");
   454     s4o.print(".");
   521     if      ( get_datatype_info_c::is_ANY_INT_literal(symbol->current_type))                        this->lint_type.accept(*this);
   455     symbol->datatype->accept(*this);
   522     else if ( get_datatype_info_c::is_ANY_REAL_literal(this->default_variable_name.current_type))   this->lreal_type.accept(*this);
       
   523     else if ( get_datatype_info_c::is_BOOL_compatible(this->default_variable_name.current_type))    this->bool_type.accept(*this); 
       
   524     else symbol->current_type->accept(*this);
       
   525     s4o.print("var");
   456     s4o.print("var");
   526   } return NULL;
   457   } return NULL;
   527 }
   458 }
   528 
   459 
   529 
   460 
   530 private:
   461 private:
   531 
   462 
   532 #if 0
       
   533 I NEED TO FIX THIS!!!
       
   534 TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO
       
   535 void *visit(eno_param_c *symbol) {
       
   536   if (this->is_variable_prefix_null()) {
       
   537     s4o.print("*");
       
   538   }
       
   539   else {
       
   540     this->print_variable_prefix();
       
   541   }
       
   542   s4o.print("ENO");
       
   543   return NULL;
       
   544 }
       
   545 TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO
       
   546 #endif
       
   547 
   463 
   548 
   464 
   549 /********************************/
   465 /********************************/
   550 /* B 1.3.3 - Derived data types */
   466 /* B 1.3.3 - Derived data types */
   551 /********************************/
   467 /********************************/
   762 /***********************************/
   678 /***********************************/
   763 
   679 
   764 /*| instruction_list il_instruction */
   680 /*| instruction_list il_instruction */
   765 void *visit(instruction_list_c *symbol) {
   681 void *visit(instruction_list_c *symbol) {
   766   
   682   
   767   /* Declare the backup to the default variable, that will store the result
   683   /* Declare the IL implicit variable, that will store the result of the IL operations... */
   768    * of the IL operations executed inside a parenthesis...
   684   declare_implicit_variable();
   769    */
   685 
   770   declare_backup_variable();
   686   /* Declare the backup to the IL implicit variable, that will store the result of the IL operations executed inside a parenthesis... */
   771   
   687   declare_implicit_variable_back();
   772   /* Declare the default variable, that will store the result of the IL operations... */
   688   /*
   773   s4o.print(s4o.indent_spaces);
   689   s4o.print(s4o.indent_spaces);
   774   s4o.print(IL_DEFVAR_T);
   690   this->implicit_variable_result_back.accept(*this);
   775   s4o.print(" ");
       
   776   this->default_variable_name.accept(*this);
       
   777   s4o.print(";\n");
       
   778   s4o.print(s4o.indent_spaces);
       
   779   print_backup_variable();
       
   780   s4o.print(".INTvar = 0;\n\n");
   691   s4o.print(".INTvar = 0;\n\n");
   781 
   692   */
   782   print_list(symbol, s4o.indent_spaces, ";\n" + s4o.indent_spaces, ";\n");
   693   print_list(symbol, s4o.indent_spaces, ";\n" + s4o.indent_spaces, ";\n");
   783 
       
   784   return NULL;
   694   return NULL;
   785 }
   695 }
   786 
   696 
   787 
   697 
   788 /* | label ':' [il_incomplete_instruction] eol_list */
   698 /* | label ':' [il_incomplete_instruction] eol_list */
   789 // SYM_REF2(il_instruction_c, label, il_instruction)
   699 // SYM_REF2(il_instruction_c, label, il_instruction)
   790 void *visit(il_instruction_c *symbol) {
   700 void *visit(il_instruction_c *symbol) {
       
   701   /* 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 */
       
   702   implicit_variable_current.datatype = (symbol->prev_il_instruction.empty())? NULL : symbol->prev_il_instruction[0]->datatype;
       
   703   implicit_variable_result .datatype = symbol->datatype;
       
   704   
   791   if (NULL != symbol->label) {
   705   if (NULL != symbol->label) {
   792     symbol->label->accept(*this);
   706     symbol->label->accept(*this);
   793     s4o.print(":\n");
   707     s4o.print(":\n");
   794     s4o.print(s4o.indent_spaces);
   708     s4o.print(s4o.indent_spaces);
   795   }
   709   }
       
   710 
   796   if (NULL != symbol->il_instruction) {
   711   if (NULL != symbol->il_instruction) {
   797     symbol->il_instruction->accept(*this);
   712     symbol->il_instruction->accept(*this);
   798   }  
   713   }  
   799   return NULL;
   714   
   800 }
   715   implicit_variable_result .datatype = NULL;
       
   716   implicit_variable_current.datatype = NULL;
       
   717   return NULL;
       
   718 }
       
   719 
   801 
   720 
   802 /* | il_simple_operator [il_operand] */
   721 /* | il_simple_operator [il_operand] */
   803 //SYM_REF2(il_simple_operation_c, il_simple_operator, il_operand)
   722 //SYM_REF2(il_simple_operation_c, il_simple_operator, il_operand)
   804 void *visit(il_simple_operation_c *symbol) {
   723 void *visit(il_simple_operation_c *symbol) {
   805   this->current_operand = symbol->il_operand;
   724   this->current_operand = symbol->il_operand;
   806   if (NULL == this->current_operand) {
       
   807     this->current_operand_type = NULL;
       
   808   } else {
       
   809     this->current_operand_type = this->current_operand->datatype;
       
   810     if (NULL == this->current_operand_type) ERROR;
       
   811   }
       
   812 
       
   813   symbol->il_simple_operator->accept(*this);
   725   symbol->il_simple_operator->accept(*this);
   814 
       
   815   this->current_operand = NULL;
   726   this->current_operand = NULL;
   816   this->current_operand_type = NULL;
       
   817   return NULL;
   727   return NULL;
   818 }
   728 }
   819 
   729 
   820 
   730 
   821 /* | function_name [il_operand_list] */
   731 /* | function_name [il_operand_list] */
   824   symbol_c* function_type_prefix = NULL;
   734   symbol_c* function_type_prefix = NULL;
   825   symbol_c* function_name = NULL;
   735   symbol_c* function_name = NULL;
   826   symbol_c* function_type_suffix = NULL;
   736   symbol_c* function_type_suffix = NULL;
   827   DECLARE_PARAM_LIST()
   737   DECLARE_PARAM_LIST()
   828   
   738   
   829   symbol_c *param_data_type = default_variable_name.current_type;
       
   830   symbol_c *return_data_type = NULL;
       
   831   
       
   832   function_call_param_iterator_c function_call_param_iterator(symbol);
   739   function_call_param_iterator_c function_call_param_iterator(symbol);
   833 
   740 
   834   function_declaration_c *f_decl = (function_declaration_c *)symbol->called_function_declaration;
   741   function_declaration_c *f_decl = (function_declaration_c *)symbol->called_function_declaration;
   835   if (f_decl == NULL) ERROR;
   742   if (f_decl == NULL) ERROR;
   836 
       
   837   /* determine the base data type returned by the function being called... */
       
   838   search_base_type_c search_base_type;
       
   839   return_data_type = (symbol_c *)f_decl->type_name->accept(search_base_type);
       
   840   if (NULL == return_data_type) ERROR;
       
   841 
   743 
   842   function_name = symbol->function_name;
   744   function_name = symbol->function_name;
   843   
   745   
   844   /* loop through each function parameter, find the value we should pass
   746   /* loop through each function parameter, find the value we should pass
   845    * to it, and then output the c equivalent...
   747    * to it, and then output the c equivalent...
   846    */
   748    */
   847   function_param_iterator_c fp_iterator(f_decl);
   749   function_param_iterator_c fp_iterator(f_decl);
   848   identifier_c *param_name;
   750   identifier_c *param_name;
   849     /* flag to remember whether we have already used the value stored in the default variable to pass to the first parameter */
   751     /* flag to remember whether we have already used the value stored in the implicit variable to pass to the first parameter */
   850   bool used_defvar = false; 
   752   bool used_defvar = false; 
   851     /* flag to cirreclty handle calls to extensible standard functions (i.e. functions with variable number of input parameters) */
   753     /* flag to cirreclty handle calls to extensible standard functions (i.e. functions with variable number of input parameters) */
   852   bool found_first_extensible_parameter = false;  
   754   bool found_first_extensible_parameter = false;  
   853   for(int i = 1; (param_name = fp_iterator.next()) != NULL; i++) {
   755   for(int i = 1; (param_name = fp_iterator.next()) != NULL; i++) {
   854     if (fp_iterator.is_extensible_param() && (!found_first_extensible_parameter)) {
   756     if (fp_iterator.is_extensible_param() && (!found_first_extensible_parameter)) {
   895     if (param_value == NULL)
   797     if (param_value == NULL)
   896       param_value = function_call_param_iterator.search_f(param_name);
   798       param_value = function_call_param_iterator.search_f(param_name);
   897 
   799 
   898     /* if it is the first parameter in a non-formal function call (which is the
   800     /* if it is the first parameter in a non-formal function call (which is the
   899      * case being handled!), semantics specifies that we should
   801      * case being handled!), semantics specifies that we should
   900      * get the value off the IL default variable!
   802      * get the value off the IL implicit variable!
   901      *
   803      *
   902      * However, if the parameter is an implicitly defined EN or ENO parameter, we should not
   804      * However, if the parameter is an implicitly defined EN or ENO parameter, we should not
   903      * use the default variable as a source of data to pass to those parameters!
   805      * use the IL implicit variable as a source of data to pass to those parameters!
   904      */
   806      */
   905     if ((param_value == NULL) &&  (!used_defvar) && !fp_iterator.is_en_eno_param_implicit()) {
   807     if ((param_value == NULL) &&  (!used_defvar) && !fp_iterator.is_en_eno_param_implicit()) {
   906       param_value = &this->default_variable_name;
   808       param_value = &this->implicit_variable_current;
   907       used_defvar = true;
   809       used_defvar = true;
   908     }
   810     }
   909 
   811 
   910     /* Get the value from a foo(<param_value>) style call */
   812     /* Get the value from a foo(<param_value>) style call */
   911     if ((param_value == NULL) && !fp_iterator.is_en_eno_param_implicit()) {
   813     if ((param_value == NULL) && !fp_iterator.is_en_eno_param_implicit()) {
   946   /* Check whether we are calling an overloaded function! */
   848   /* Check whether we are calling an overloaded function! */
   947   /* (fdecl_mutiplicity==2)  => calling overloaded function */
   849   /* (fdecl_mutiplicity==2)  => calling overloaded function */
   948   int fdecl_mutiplicity =  function_symtable.multiplicity(symbol->function_name);
   850   int fdecl_mutiplicity =  function_symtable.multiplicity(symbol->function_name);
   949   if (fdecl_mutiplicity == 0) ERROR;
   851   if (fdecl_mutiplicity == 0) ERROR;
   950 
   852 
   951   default_variable_name.current_type = return_data_type;
   853   this->implicit_variable_result.accept(*this);
   952   this->default_variable_name.accept(*this);
       
   953   default_variable_name.current_type = param_data_type;
       
   954   s4o.print(" = ");
   854   s4o.print(" = ");
   955     
   855     
   956   if (function_type_prefix != NULL) {
   856   if (function_type_prefix != NULL) {
   957     s4o.print("(");
   857     s4o.print("(");
   958     default_literal_type(function_type_prefix)->accept(*this);
   858     default_literal_type(function_type_prefix)->accept(*this);
  1042       s4o.print(",\n"+s4o.indent_spaces);
   942       s4o.print(",\n"+s4o.indent_spaces);
  1043     s4o.print(FB_FUNCTION_PARAM);
   943     s4o.print(FB_FUNCTION_PARAM);
  1044   }
   944   }
  1045   
   945   
  1046   s4o.print(")");
   946   s4o.print(")");
  1047   /* the data type returned by the function, and stored in the il default variable... */
       
  1048   default_variable_name.current_type = return_data_type;
       
  1049 
   947 
  1050   CLEAR_PARAM_LIST()
   948   CLEAR_PARAM_LIST()
  1051 
   949 
  1052   return NULL;
   950   return NULL;
  1053 }
   951 }
  1054 
   952 
  1055 
   953 
  1056 /* | il_expr_operator '(' [il_operand] eol_list [simple_instr_list] ')' */
   954 /* | il_expr_operator '(' [il_operand] eol_list [simple_instr_list] ')' */
  1057 //SYM_REF4(il_expression_c, il_expr_operator, il_operand, simple_instr_list, unused)
   955 //SYM_REF4(il_expression_c, il_expr_operator, il_operand, simple_instr_list, unused)
  1058 void *visit(il_expression_c *symbol) {
   956 void *visit(il_expression_c *symbol) {
  1059   /* We will be recursevely interpreting an instruction list,
   957   LD_operator_c           *tmp_LD_operator           = NULL;
  1060    * so we store a backup of the data type of the value currently stored
   958   il_simple_operation_c   *tmp_il_simple_operation   = NULL;
  1061    * in the default variable, and set the current data type to NULL
   959   il_simple_instruction_c *tmp_il_simple_instruction = NULL;
       
   960   
       
   961   /* We will be recursevely interpreting an instruction list, so we store a backup of the implicit_variable_result/current.
       
   962    * Notice that they will be overwriten while processing the parenthsized instruction list.
  1062    */
   963    */
  1063   symbol_c *old_current_default_variable_data_type = this->default_variable_name.current_type;
   964   il_default_variable_c old_implicit_variable_current = this->implicit_variable_current;
  1064   this->default_variable_name.current_type = NULL;
   965   il_default_variable_c old_implicit_variable_result  = this->implicit_variable_result;
  1065 
   966 
  1066  /* Pass the symbol->il_operand to the simple_instr_list visitor
   967   /* If the symbol->il_operand is not NULL, then we instantiate a 'LD' operation and insert it into the simple_instr_list
  1067   * using the il_default_variable_init_value parameter...
   968    * (i.e. add an equivalent LD operation to the Abstract Syntax Tree), and let it be handled like any other LD operation!
  1068   * Note that the simple_instr_list_c visitor will set this parameter
   969    */
  1069   * to NULL as soon as it does not require it any longer,
   970   if (NULL != symbol->il_operand) {
  1070   * so we don't do it here again after the
   971     tmp_LD_operator = new LD_operator_c();
  1071   *   symbol->simple_instr_list->accept(*this);
   972     if (NULL == tmp_LD_operator)  ERROR;
  1072   * returns...
   973     /* copy all the location, datatpe, etc.. data from symbol->il_operand to the new object! */
  1073   */
   974     *((symbol_c *)tmp_LD_operator) = *(symbol->il_operand);
  1074   this->il_default_variable_init_value = symbol->il_operand;
   975     
       
   976     tmp_il_simple_operation = new il_simple_operation_c(tmp_LD_operator, symbol->il_operand);
       
   977     if (NULL == tmp_il_simple_operation)  ERROR;
       
   978     /* copy all the location, datatpe, etc.. data from symbol->il_operand to the new object! */
       
   979     *((symbol_c *)tmp_il_simple_operation) = *(symbol->il_operand);
       
   980     
       
   981     tmp_il_simple_instruction = new il_simple_instruction_c(tmp_il_simple_operation);
       
   982     if (NULL == tmp_il_simple_instruction)  ERROR;
       
   983     /* copy all the location, datatpe, etc.. data from symbol->il_operand to the new object! */
       
   984     *((symbol_c *)tmp_il_simple_instruction) = *(symbol->il_operand);
       
   985 
       
   986     if (NULL == symbol->simple_instr_list)  {
       
   987       symbol->simple_instr_list = new simple_instr_list_c();
       
   988       if (NULL == symbol->simple_instr_list)  ERROR;
       
   989       /* copy all the location, datatpe, etc.. data from symbol->il_operand to the new object! */
       
   990       *((symbol_c *)symbol->simple_instr_list) = *(symbol->il_operand);
       
   991     }
       
   992     list_c *tmp_list = dynamic_cast <list_c *>(symbol->simple_instr_list);
       
   993     if (NULL == tmp_list)  ERROR;
       
   994     tmp_list->insert_element(tmp_il_simple_instruction, 0);
       
   995   }
  1075 
   996 
  1076   /* Now do the parenthesised instructions... */
   997   /* Now do the parenthesised instructions... */
  1077   /* NOTE: the following code line will get the variable
   998   /* NOTE: the following code line will overwrite the variables implicit_variable_current and implicit_variable_result */
  1078    * this->default_variable_name.current_type updated!
       
  1079    */
       
  1080   symbol->simple_instr_list->accept(*this);
   999   symbol->simple_instr_list->accept(*this);
  1081 
  1000 
       
  1001   /* delete/undo any changes made to the AST above */
       
  1002   if (NULL != symbol->il_operand) {
       
  1003     delete tmp_LD_operator;
       
  1004     delete tmp_il_simple_operation;
       
  1005     delete tmp_il_simple_instruction;
       
  1006     list_c *tmp_list = dynamic_cast <list_c *>(symbol->simple_instr_list);
       
  1007     if (NULL == tmp_list)  ERROR;
       
  1008     delete tmp_list->elements[0];
       
  1009     tmp_list->remove_element(0);
       
  1010     if (0 == tmp_list->n) {
       
  1011       delete symbol->simple_instr_list;
       
  1012       symbol->simple_instr_list = NULL;
       
  1013     }
       
  1014   }
       
  1015   
  1082   /* Now do the operation, using the previous result! */
  1016   /* Now do the operation, using the previous result! */
  1083   /* NOTE: The result of the previous instruction list will be stored
  1017   /* NOTE: The result of the previous instruction list in the parenthesis will be stored
  1084    * in a variable named IL_DEFVAR_BACK. This is done in the visitor
  1018    * in a variable named IL_DEFVAR_BACK. This is done in the visitor
  1085    * to instruction_list_c objects...
  1019    * to instruction_list_c objects...
  1086    */
  1020    */
  1087   this->current_operand = &(this->default_variable_back_name);
  1021   this->implicit_variable_result_back.datatype = symbol->simple_instr_list->datatype;
  1088   this->current_operand_type = this->default_variable_back_name.current_type;
  1022   this->current_operand = &(this->implicit_variable_result_back);
  1089 
  1023 
  1090   this->default_variable_name.current_type = old_current_default_variable_data_type;
  1024   this->implicit_variable_current = old_implicit_variable_current;
  1091   if (NULL == this->current_operand_type) ERROR;
  1025   this->implicit_variable_result  = old_implicit_variable_result;
  1092 
  1026 
  1093   symbol->il_expr_operator->accept(*this);
  1027   symbol->il_expr_operator->accept(*this);
  1094 
  1028 
  1095   this->current_operand = NULL;
  1029   this->current_operand = NULL;
  1096   this->current_operand_type = NULL;
  1030   this->implicit_variable_result_back.datatype = NULL;
  1097   this->default_variable_back_name.current_type = NULL;
  1031   return NULL;
  1098   return NULL;
  1032 }
  1099 }
  1033 
  1100 
  1034 
  1101 /*  il_jump_operator label */
  1035 /*  il_jump_operator label */
  1102 // SYM_REF2(il_jump_operation_c, il_jump_operator, label)
  1036 // SYM_REF2(il_jump_operation_c, il_jump_operator, label)
  1103 void *visit(il_jump_operation_c *symbol) {
  1037 void *visit(il_jump_operation_c *symbol) {
  1104  /* Pass the symbol->label to the il_jump_operation visitor
  1038  /* Pass the symbol->label to the il_jump_operation visitor using the jump_label parameter... */
  1105   * using the jump_label parameter...
       
  1106   */
       
  1107   this->jump_label = symbol->label;
  1039   this->jump_label = symbol->label;
  1108   symbol->il_jump_operator->accept(*this);
  1040   symbol->il_jump_operator->accept(*this);
  1109   this->jump_label = NULL;
  1041   this->jump_label = NULL;
  1110 
  1042   return NULL;
  1111   return NULL;
  1043 }
  1112 }
  1044 
  1113 
  1045 
  1114 /*   il_call_operator prev_declared_fb_name
  1046 /*   il_call_operator prev_declared_fb_name
  1115  * | il_call_operator prev_declared_fb_name '(' ')'
  1047  * | il_call_operator prev_declared_fb_name '(' ')'
  1116  * | il_call_operator prev_declared_fb_name '(' eol_list ')'
  1048  * | il_call_operator prev_declared_fb_name '(' eol_list ')'
  1117  * | il_call_operator prev_declared_fb_name '(' il_operand_list ')'
  1049  * | il_call_operator prev_declared_fb_name '(' il_operand_list ')'
  1233   symbol_c* function_type_prefix = NULL;
  1165   symbol_c* function_type_prefix = NULL;
  1234   symbol_c* function_name = NULL;
  1166   symbol_c* function_name = NULL;
  1235   symbol_c* function_type_suffix = NULL;
  1167   symbol_c* function_type_suffix = NULL;
  1236   DECLARE_PARAM_LIST()
  1168   DECLARE_PARAM_LIST()
  1237 
  1169 
  1238   symbol_c *return_data_type = NULL;
       
  1239 
       
  1240   function_call_param_iterator_c function_call_param_iterator(symbol);
  1170   function_call_param_iterator_c function_call_param_iterator(symbol);
  1241 
  1171 
  1242   function_declaration_c *f_decl = (function_declaration_c *)symbol->called_function_declaration;
  1172   function_declaration_c *f_decl = (function_declaration_c *)symbol->called_function_declaration;
  1243   if (f_decl == NULL) ERROR;
  1173   if (f_decl == NULL) ERROR;
  1244         
  1174         
  1245   /* determine the base data type returned by the function being called... */
       
  1246   search_base_type_c search_base_type;
       
  1247   return_data_type = (symbol_c *)f_decl->type_name->accept(search_base_type);
       
  1248   if (NULL == return_data_type) ERROR;
       
  1249   
       
  1250   function_name = symbol->function_name;
  1175   function_name = symbol->function_name;
  1251 
  1176 
  1252   /* loop through each function parameter, find the value we should pass
  1177   /* loop through each function parameter, find the value we should pass
  1253    * to it, and then output the c equivalent...
  1178    * to it, and then output the c equivalent...
  1254    */
  1179    */
  1355   if (fdecl_mutiplicity == 0) ERROR;
  1280   if (fdecl_mutiplicity == 0) ERROR;
  1356   if (fdecl_mutiplicity == 1) 
  1281   if (fdecl_mutiplicity == 1) 
  1357     /* function being called is NOT overloaded! */
  1282     /* function being called is NOT overloaded! */
  1358     f_decl = NULL; 
  1283     f_decl = NULL; 
  1359 
  1284 
  1360   default_variable_name.current_type = return_data_type;
  1285   this->implicit_variable_result.accept(*this);
  1361   this->default_variable_name.accept(*this);
       
  1362   s4o.print(" = ");
  1286   s4o.print(" = ");
  1363   
  1287   
  1364   if (function_type_prefix != NULL) {
  1288   if (function_type_prefix != NULL) {
  1365     s4o.print("(");
  1289     s4o.print("(");
  1366     default_literal_type(function_type_prefix)->accept(*this);
  1290     default_literal_type(function_type_prefix)->accept(*this);
  1449     s4o.print(FB_FUNCTION_PARAM);
  1373     s4o.print(FB_FUNCTION_PARAM);
  1450   }
  1374   }
  1451 
  1375 
  1452   // symbol->parameter_assignment->accept(*this);
  1376   // symbol->parameter_assignment->accept(*this);
  1453   s4o.print(")");
  1377   s4o.print(")");
  1454   /* the data type returned by the function, and stored in the il default variable... */
       
  1455 
  1378 
  1456   CLEAR_PARAM_LIST()
  1379   CLEAR_PARAM_LIST()
  1457 
  1380 
  1458   return NULL;
  1381   return NULL;
  1459 }
  1382 }
  1465 
  1388 
  1466 
  1389 
  1467 /* | simple_instr_list il_simple_instruction */
  1390 /* | simple_instr_list il_simple_instruction */
  1468 // SYM_LIST(simple_instr_list_c)
  1391 // SYM_LIST(simple_instr_list_c)
  1469 void *visit(simple_instr_list_c *symbol) {
  1392 void *visit(simple_instr_list_c *symbol) {
  1470   /* A simple_instr_list_c is used to store a list of il operations
  1393   /* A simple_instr_list_c is used to store a list of il operations being done within parenthesis...
  1471    * being done within parenthesis...
       
  1472    *
  1394    *
  1473    * e.g.:
  1395    * e.g.:
  1474    *         LD var1
  1396    *         LD var1
  1475    *         AND ( var2
  1397    *         AND ( var2
  1476    *         OR var3
  1398    *         OR var3
  1477    *         OR var4
  1399    *         OR var4
  1478    *         )
  1400    *         )
  1479    *
  1401    *
       
  1402    * NOTE 1:
  1480    * This will be converted to C++ by defining a new scope
  1403    * This will be converted to C++ by defining a new scope
  1481    * with a new il default variable, and executing the il operands
  1404    * with a new il implicit variable, and executing the il operands
  1482    * within this new scope.
  1405    * within this new scope.
  1483    * At the end of the scope the result, i.e. the value currently stored
  1406    * At the end of the scope the result, i.e. the value currently stored
  1484    * in the il default variable is copied to the variable used to take this
  1407    * in the il implicit variable is copied to the variable used to take this
  1485    * value to the outside scope...
  1408    * value to the outside scope...
  1486    *
  1409    *
  1487    * The above example will result in the following C++ code:
  1410    * The above example will result in the following C++ code:
  1488    * {__IL_DEFVAR_T __IL_DEFVAR_BACK;
  1411    * {__IL_DEFVAR_T __IL_DEFVAR_BACK;
  1489    *  __IL_DEFVAR_T __IL_DEFVAR;
  1412    *  __IL_DEFVAR_T __IL_DEFVAR;
  1500    *  }
  1423    *  }
  1501    *  __IL_DEFVAR.INTvar &= __IL_DEFVAR_BACK.INTvar;
  1424    *  __IL_DEFVAR.INTvar &= __IL_DEFVAR_BACK.INTvar;
  1502    *
  1425    *
  1503    * }
  1426    * }
  1504    *
  1427    *
  1505    *  The intial value of the il default variable (in the above
  1428    * NOTE 2:
  1506    * example 'var2') is passed to this simple_instr_list_c visitor
  1429    *  If the intial value of the il implicit variable (in the above
  1507    * using the il_default_variable_init_value parameter.
  1430    * example 'var2') exists, then the il_expression_c will insert an equivalent
  1508    * Since it is possible to have parenthesis inside other parenthesis
  1431    * LD operation into the parenthesized instruction list- This means we do not
  1509    * recursively, we reset the il_default_variable_init_value to NULL
  1432    * need to do anything here to handle this special situation!
  1510    * as soon as we no longer require it, as it may be used once again
       
  1511    * in the line
       
  1512    *  print_list(symbol, s4o.indent_spaces, ";\n" + s4o.indent_spaces, ";\n");
       
  1513    *
       
  1514    */
  1433    */
  1515 
  1434 
  1516   /* Declare the default variable, that will store the result of the IL operations... */
  1435   /* Declare the IL implicit variable, that will store the result of the IL operations... */
  1517   s4o.print("{\n");
  1436   s4o.print("{\n");
  1518   s4o.indent_right();
  1437   s4o.indent_right();
  1519 
  1438   declare_implicit_variable();
  1520   s4o.print(s4o.indent_spaces);
  1439     
  1521   s4o.print(IL_DEFVAR_T);
       
  1522   s4o.print(" ");
       
  1523   this->default_variable_name.accept(*this);
       
  1524   s4o.print(";\n\n");
       
  1525 
       
  1526   /* Check whether we should initiliase the il default variable... */
       
  1527   if (NULL != this->il_default_variable_init_value) {
       
  1528     /* Yes, we must... */
       
  1529     /* We will do it by instatiating a LD operator, and having this
       
  1530      * same generate_c_il_c class visiting it!
       
  1531      */
       
  1532     LD_operator_c ld_oper;
       
  1533     il_simple_operation_c il_simple_oper(&ld_oper, this->il_default_variable_init_value);
       
  1534 
       
  1535     s4o.print(s4o.indent_spaces);
       
  1536     il_simple_oper.accept(*this);
       
  1537     s4o.print(";\n");
       
  1538   }
       
  1539 
       
  1540   /* this parameter no longer required... */
       
  1541   this->il_default_variable_init_value = NULL;
       
  1542 
       
  1543   print_list(symbol, s4o.indent_spaces, ";\n" + s4o.indent_spaces, ";\n");
  1440   print_list(symbol, s4o.indent_spaces, ";\n" + s4o.indent_spaces, ";\n");
  1544 
  1441 
  1545   /* copy the result in the default variable to the variable
  1442   /* copy the result in the IL implicit variable to the variable
  1546    * used to pass the data out to the scope enclosing
  1443    * used to pass the data out to the scope enclosing the current scope!
  1547    * the current scope!
       
  1548    *
       
  1549    * We also need to update the data type currently stored within
       
  1550    * the variable used to pass the data to the outside scope...
       
  1551    */
  1444    */
  1552   this->default_variable_back_name.current_type = this->default_variable_name.current_type;
  1445   this->implicit_variable_result_back.datatype = symbol->datatype;
       
  1446   this->implicit_variable_result     .datatype = symbol->datatype;
       
  1447 
  1553   s4o.print("\n");
  1448   s4o.print("\n");
  1554   s4o.print(s4o.indent_spaces);
  1449   s4o.print(s4o.indent_spaces);
  1555   this->default_variable_back_name.accept(*this);
  1450   this->implicit_variable_result_back.accept(*this);
  1556   s4o.print(" = ");
  1451   s4o.print(" = ");
  1557   this->default_variable_name.accept(*this);
  1452   this->implicit_variable_result.accept(*this);
  1558   s4o.print(";\n");
  1453   s4o.print(";\n");
  1559 
  1454 
  1560   s4o.indent_left();
  1455   s4o.indent_left();
  1561   s4o.print(s4o.indent_spaces);
  1456   s4o.print(s4o.indent_spaces);
  1562   s4o.print("}\n");
  1457   s4o.print("}\n");
  1563   s4o.print(s4o.indent_spaces);
  1458   s4o.print(s4o.indent_spaces);
  1564   return NULL;
  1459   return NULL;
  1565 }
  1460 }
  1566 
  1461 
       
  1462 
  1567 // SYM_REF1(il_simple_instruction_c, il_simple_instruction, symbol_c *prev_il_instruction;)
  1463 // SYM_REF1(il_simple_instruction_c, il_simple_instruction, symbol_c *prev_il_instruction;)
  1568 void *visit(il_simple_instruction_c *symbol)	{
  1464 void *visit(il_simple_instruction_c *symbol)    {return symbol->il_simple_instruction->accept(*this);}
  1569   return symbol->il_simple_instruction->accept(*this);
       
  1570 }
       
  1571 
       
  1572 
  1465 
  1573 /* | il_initial_param_list il_param_instruction */
  1466 /* | il_initial_param_list il_param_instruction */
  1574 // SYM_LIST(il_param_list_c)
  1467 // SYM_LIST(il_param_list_c)
  1575 void *visit(il_param_list_c *symbol) {ERROR; return NULL;} // should never get called!
  1468 void *visit(il_param_list_c *symbol)            {ERROR; return NULL;} // should never get called!
  1576 
  1469 
  1577 /*  il_assign_operator il_operand
  1470 /*  il_assign_operator il_operand
  1578  * | il_assign_operator '(' eol_list simple_instr_list ')'
  1471  * | il_assign_operator '(' eol_list simple_instr_list ')'
  1579  */
  1472  */
  1580 // SYM_REF4(il_param_assignment_c, il_assign_operator, il_operand, simple_instr_list, unused)
  1473 // SYM_REF4(il_param_assignment_c, il_assign_operator, il_operand, simple_instr_list, unused)
  1581 void *visit(il_param_assignment_c *symbol) {ERROR; return NULL;} // should never get called!
  1474 void *visit(il_param_assignment_c *symbol)      {ERROR; return NULL;} // should never get called!
  1582 
  1475 
  1583 /*  il_assign_out_operator variable */
  1476 /*  il_assign_out_operator variable */
  1584 // SYM_REF2(il_param_out_assignment_c, il_assign_out_operator, variable);
  1477 // SYM_REF2(il_param_out_assignment_c, il_assign_out_operator, variable);
  1585 void *visit(il_param_out_assignment_c *symbol) {ERROR; return NULL;} // should never get called!
  1478 void *visit(il_param_out_assignment_c *symbol)  {ERROR; return NULL;} // should never get called!
       
  1479 
  1586 
  1480 
  1587 /*******************/
  1481 /*******************/
  1588 /* B 2.2 Operators */
  1482 /* B 2.2 Operators */
  1589 /*******************/
  1483 /*******************/
  1590 
  1484 
  1591 void *visit(LD_operator_c *symbol)	{
  1485 void *visit(LD_operator_c *symbol) {
  1592   if (wanted_variablegeneration != expression_vg) {
  1486   if (wanted_variablegeneration != expression_vg) {
  1593     s4o.print("LD");
  1487     s4o.print("LD");
  1594     return NULL;
  1488     return NULL;
  1595   }
  1489   }
  1596 
  1490   XXX_operator(&(this->implicit_variable_result), " = ", this->current_operand);
  1597   /* the data type resulting from this operation... */
  1491   return NULL;
  1598   this->default_variable_name.current_type = this->current_operand_type;
  1492 }
  1599   XXX_operator(&(this->default_variable_name), " = ", this->current_operand);
  1493 
  1600   return NULL;
  1494 
  1601 }
  1495 void *visit(LDN_operator_c *symbol) {
  1602 
  1496   XXX_operator(&(this->implicit_variable_result), get_datatype_info_c::is_BOOL_compatible(this->current_operand->datatype)?" = !":" = ~", this->current_operand);
  1603 void *visit(LDN_operator_c *symbol)	{
  1497   return NULL;
  1604   /* the data type resulting from this operation... */
  1498 }
  1605   this->default_variable_name.current_type = this->current_operand_type;
  1499 
  1606   XXX_operator(&(this->default_variable_name),
  1500 
  1607                get_datatype_info_c::is_BOOL_compatible(this->current_operand_type)?" = !":" = ~",
  1501 void *visit(ST_operator_c *symbol) {
  1608                this->current_operand);
       
  1609   return NULL;
       
  1610 }
       
  1611 
       
  1612 void *visit(ST_operator_c *symbol)	{
       
  1613   symbol_c *operand_type = search_varfb_instance_type->get_type_id(this->current_operand);
       
  1614   if (get_datatype_info_c::is_ANY_INT_literal(this->default_variable_name.current_type) ||
       
  1615   	  get_datatype_info_c::is_ANY_REAL_literal(this->default_variable_name.current_type))
       
  1616       this->default_variable_name.current_type = this->current_operand_type;
       
  1617   if (this->is_variable_prefix_null()) {
  1502   if (this->is_variable_prefix_null()) {
  1618     this->current_operand->accept(*this);
  1503     this->current_operand->accept(*this);
  1619     s4o.print(" = ");
  1504     s4o.print(" = ");
  1620     print_check_function(operand_type, (symbol_c*)&(this->default_variable_name));
  1505     print_check_function(this->current_operand->datatype, (symbol_c*)&(this->implicit_variable_current));
  1621   }
  1506   }
  1622   else {
  1507   else {
  1623 	print_setter(this->current_operand, operand_type, (symbol_c*)&(this->default_variable_name));
  1508     print_setter(this->current_operand, this->current_operand->datatype, (symbol_c*)&(this->implicit_variable_current));
  1624   }
  1509   }
  1625   /* the data type resulting from this operation is unchanged. */
  1510   return NULL;
  1626   return NULL;
  1511 }
  1627 }
  1512 
  1628 
  1513 
  1629 void *visit(STN_operator_c *symbol)	{
  1514 void *visit(STN_operator_c *symbol) {
  1630   symbol_c *operand_type = search_varfb_instance_type->get_type_id(this->current_operand);
       
  1631   if (get_datatype_info_c::is_ANY_INT_literal(this->default_variable_name.current_type))
       
  1632 	this->default_variable_name.current_type = this->current_operand_type;
       
  1633   
       
  1634   if (this->is_variable_prefix_null()) {
  1515   if (this->is_variable_prefix_null()) {
  1635     this->current_operand->accept(*this);
  1516     this->current_operand->accept(*this);
  1636     s4o.print(" = ");
  1517     s4o.print(" = ");
  1637     if (get_datatype_info_c::is_BOOL_compatible(this->current_operand_type))
  1518     if (get_datatype_info_c::is_BOOL_compatible(this->current_operand->datatype))
  1638       s4o.print("!");
  1519       s4o.print("!");
  1639     else
  1520     else
  1640 	  s4o.print("~");
  1521       s4o.print("~");
  1641     this->default_variable_name.accept(*this);
  1522     this->implicit_variable_current.accept(*this);
  1642   }
  1523   }
  1643   else {
  1524   else {
  1644 	print_setter(this->current_operand, operand_type, (symbol_c*)&(this->default_variable_name), NULL, NULL, true);
  1525     print_setter(this->current_operand, this->current_operand->datatype, (symbol_c*)&(this->implicit_variable_current), NULL, NULL, true);
  1645   }
  1526   }
  1646   /* the data type resulting from this operation is unchanged. */
  1527   return NULL;
  1647   return NULL;
  1528 }
  1648 }
  1529 
  1649 
  1530 
  1650 void *visit(NOT_operator_c *symbol)	{
  1531 void *visit(NOT_operator_c *symbol) {
  1651   /* NOTE: the standard allows syntax in which the NOT operator is followed by an optional <il_operand>
  1532   /* NOTE: the standard allows syntax in which the NOT operator is followed by an optional <il_operand>
  1652    *              NOT [<il_operand>]
  1533    *              NOT [<il_operand>]
  1653    *       However, it does not define the semantic of the NOT operation when the <il_operand> is specified.
  1534    *       However, it does not define the semantic of the NOT operation when the <il_operand> is specified.
  1654    *       We therefore consider it an error if an il_operand is specified!
  1535    *       We therefore consider it an error if an il_operand is specified!
  1655    *       The error is caught in stage 3!
  1536    *       The error is caught in stage 3!
  1656    */  
  1537    */  
  1657   if ((NULL != this->current_operand) || (NULL != this->current_operand_type)) ERROR;
  1538   if (NULL != this->current_operand) ERROR;
  1658   XXX_operator(&(this->default_variable_name),
  1539   XXX_operator(&(this->implicit_variable_result), get_datatype_info_c::is_BOOL_compatible(symbol->datatype)?" = !":" = ~", &(this->implicit_variable_current));
  1659                get_datatype_info_c::is_BOOL_compatible(this->default_variable_name.current_type)?" = !":" = ~",
  1540   return NULL;
  1660                &(this->default_variable_name));
  1541 }
  1661   /* the data type resulting from this operation is unchanged. */
  1542 
  1662   return NULL;
       
  1663 }
       
  1664 
  1543 
  1665 void *visit(S_operator_c *symbol)	{
  1544 void *visit(S_operator_c *symbol)	{
  1666   if (wanted_variablegeneration != expression_vg) {
  1545   if (wanted_variablegeneration != expression_vg) {
  1667     s4o.print("LD");
  1546     s4o.print("LD");
  1668     return NULL;
  1547     return NULL;
  1669   }
  1548   }
  1670 
  1549 
  1671   if ((NULL == this->current_operand) || (NULL == this->current_operand_type)) ERROR;
  1550   if ((NULL == this->current_operand) || (NULL == this->current_operand->datatype)) ERROR;
  1672 
  1551 
  1673   C_modifier();
  1552   C_modifier();
  1674   this->current_operand->accept(*this);
  1553   this->current_operand->accept(*this);
  1675   s4o.print(" = __");
  1554   s4o.print(" = __");
  1676   if (get_datatype_info_c::is_BOOL_compatible(this->current_operand_type))
  1555   if        (get_datatype_info_c::is_BOOL_compatible(this->current_operand->datatype)) {
  1677     s4o.print("BOOL_LITERAL(TRUE)");
  1556     s4o.print("BOOL_LITERAL(TRUE)");
  1678   else if (get_datatype_info_c::is_ANY_INT_compatible(this->current_operand_type)) {
  1557   } else if (get_datatype_info_c::is_ANY_INT_compatible(this->current_operand->datatype)) {
  1679     this->current_operand_type->accept(*this);
  1558     this->current_operand->datatype->accept(*this);
  1680     s4o.print("_LITERAL(1)");
  1559     s4o.print("_LITERAL(1)");
  1681   }
  1560   } else
  1682   else
       
  1683     ERROR;
  1561     ERROR;
  1684   /* the data type resulting from this operation is unchanged! */
  1562   return NULL;
  1685   return NULL;
  1563 }
  1686 }
  1564 
  1687 
  1565 
  1688 void *visit(R_operator_c *symbol)	{
  1566 void *visit(R_operator_c *symbol)	{
  1689   if (wanted_variablegeneration != expression_vg) {
  1567   if (wanted_variablegeneration != expression_vg) {
  1690     s4o.print("LD");
  1568     s4o.print("LD");
  1691     return NULL;
  1569     return NULL;
  1692   }
  1570   }
  1693 
  1571 
  1694   if ((NULL == this->current_operand) || (NULL == this->current_operand_type)) ERROR;
  1572   if ((NULL == this->current_operand) || (NULL == this->current_operand->datatype)) ERROR;
  1695 
  1573 
  1696   C_modifier();
  1574   C_modifier();
  1697   this->current_operand->accept(*this);
  1575   this->current_operand->accept(*this);
  1698   s4o.print(" = __");
  1576   s4o.print(" = __");
  1699   if (get_datatype_info_c::is_BOOL_compatible(this->current_operand_type))
  1577   if        (get_datatype_info_c::is_BOOL_compatible(this->current_operand->datatype)) {
  1700     s4o.print("BOOL_LITERAL(FALSE)");
  1578     s4o.print("BOOL_LITERAL(FALSE)");
  1701   else if (get_datatype_info_c::is_ANY_INT_compatible(this->current_operand_type)) {
  1579   } else if (get_datatype_info_c::is_ANY_INT_compatible(this->current_operand->datatype)) {
  1702     this->current_operand_type->accept(*this);
  1580     this->current_operand->datatype->accept(*this);
  1703     s4o.print("_LITERAL(0)");
  1581     s4o.print("_LITERAL(0)");
  1704   }
  1582   } else
  1705   else
       
  1706     ERROR;
  1583     ERROR;
  1707   /* the data type resulting from this operation is unchanged! */
  1584   /* the data type resulting from this operation is unchanged! */
  1708   return NULL;
  1585   return NULL;
  1709 }
  1586 }
  1710 
  1587 
  1711 void *visit(S1_operator_c *symbol)	{return XXX_CAL_operator("S1", this->current_operand);}
  1588 
  1712 void *visit(R1_operator_c *symbol)	{return XXX_CAL_operator("R1", this->current_operand);}
  1589 void *visit( S1_operator_c *symbol)	{return XXX_CAL_operator( "S1", this->current_operand);}
       
  1590 void *visit( R1_operator_c *symbol)	{return XXX_CAL_operator( "R1", this->current_operand);}
  1713 void *visit(CLK_operator_c *symbol)	{return XXX_CAL_operator("CLK", this->current_operand);}
  1591 void *visit(CLK_operator_c *symbol)	{return XXX_CAL_operator("CLK", this->current_operand);}
  1714 void *visit(CU_operator_c *symbol)	{return XXX_CAL_operator("CU", this->current_operand);}
  1592 void *visit( CU_operator_c *symbol)	{return XXX_CAL_operator( "CU", this->current_operand);}
  1715 void *visit(CD_operator_c *symbol)	{return XXX_CAL_operator("CD", this->current_operand);}
  1593 void *visit( CD_operator_c *symbol)	{return XXX_CAL_operator( "CD", this->current_operand);}
  1716 void *visit(PV_operator_c *symbol)	{return XXX_CAL_operator("PV", this->current_operand);}
  1594 void *visit( PV_operator_c *symbol)	{return XXX_CAL_operator( "PV", this->current_operand);}
  1717 void *visit(IN_operator_c *symbol)	{return XXX_CAL_operator("IN", this->current_operand);}
  1595 void *visit( IN_operator_c *symbol)	{return XXX_CAL_operator( "IN", this->current_operand);}
  1718 void *visit(PT_operator_c *symbol)	{return XXX_CAL_operator("PT", this->current_operand);}
  1596 void *visit( PT_operator_c *symbol)	{return XXX_CAL_operator( "PT", this->current_operand);}
  1719 
  1597 
  1720 void *visit(AND_operator_c *symbol)	{
  1598 void *visit(AND_operator_c *symbol)	{
  1721   if (get_datatype_info_c::is_ANY_BIT_compatible(this->default_variable_name.current_type)) {
  1599   if (!get_datatype_info_c::is_ANY_BIT_compatible(symbol->datatype)) ERROR;
  1722 	BYTE_operator_result_type();
  1600   XXX_operator(&(this->implicit_variable_result), " &= ", this->current_operand);
  1723 	XXX_operator(&(this->default_variable_name), " &= ", this->current_operand);
       
  1724     /* the data type resulting from this operation... */
       
  1725     this->default_variable_name.current_type = this->current_operand_type;
       
  1726   }
       
  1727   else {ERROR;}
       
  1728   return NULL;
  1601   return NULL;
  1729 }
  1602 }
  1730 
  1603 
  1731 void *visit(OR_operator_c *symbol)	{
  1604 void *visit(OR_operator_c *symbol)	{
  1732   if (get_datatype_info_c::is_ANY_BIT_compatible(this->default_variable_name.current_type)) {
  1605   if (!get_datatype_info_c::is_ANY_BIT_compatible(symbol->datatype)) ERROR;
  1733 	BYTE_operator_result_type();
  1606   XXX_operator(&(this->implicit_variable_result), " |= ", this->current_operand);
  1734 	XXX_operator(&(this->default_variable_name), " |= ", this->current_operand);
       
  1735     /* the data type resulting from this operation... */
       
  1736     this->default_variable_name.current_type = this->current_operand_type;
       
  1737   }
       
  1738   else {ERROR;}
       
  1739   return NULL;
  1607   return NULL;
  1740 }
  1608 }
  1741 
  1609 
  1742 void *visit(XOR_operator_c *symbol)	{
  1610 void *visit(XOR_operator_c *symbol)	{
  1743   if (get_datatype_info_c::is_ANY_BIT_compatible(this->default_variable_name.current_type)) {
  1611   if (!get_datatype_info_c::is_ANY_BIT_compatible(symbol->datatype)) ERROR;
  1744 	BYTE_operator_result_type();
  1612   // '^' is a bit by bit exclusive OR !! Also seems to work with boolean types!
  1745 	// '^' is a bit by bit exclusive OR !! Also seems to work with boolean types!
  1613   XXX_operator(&(this->implicit_variable_result), " ^= ", this->current_operand);
  1746     XXX_operator(&(this->default_variable_name), " ^= ", this->current_operand);
       
  1747     /* the data type resulting from this operation... */
       
  1748     this->default_variable_name.current_type = this->current_operand_type;
       
  1749   }
       
  1750   else {ERROR;}
       
  1751   return NULL;
  1614   return NULL;
  1752 }
  1615 }
  1753 
  1616 
  1754 void *visit(ANDN_operator_c *symbol)	{
  1617 void *visit(ANDN_operator_c *symbol)	{
  1755   if (get_datatype_info_c::is_ANY_BIT_compatible(this->default_variable_name.current_type)) {
  1618   if (!get_datatype_info_c::is_ANY_BIT_compatible(symbol->datatype)) ERROR;
  1756 	BYTE_operator_result_type();
  1619   XXX_operator(&(this->implicit_variable_result), get_datatype_info_c::is_BOOL_compatible(this->current_operand->datatype)?" &= !":" &= ~", this->current_operand);
  1757 	XXX_operator(&(this->default_variable_name),
       
  1758                  get_datatype_info_c::is_BOOL_compatible(this->current_operand_type)?" &= !":" &= ~",
       
  1759                  this->current_operand);
       
  1760     /* the data type resulting from this operation... */
       
  1761     this->default_variable_name.current_type = this->current_operand_type;
       
  1762   }
       
  1763   else {ERROR;}
       
  1764   return NULL;
  1620   return NULL;
  1765 }
  1621 }
  1766 
  1622 
  1767 void *visit(ORN_operator_c *symbol)	{
  1623 void *visit(ORN_operator_c *symbol)	{
  1768   if (get_datatype_info_c::is_ANY_BIT_compatible(this->default_variable_name.current_type)) {
  1624   if (!get_datatype_info_c::is_ANY_BIT_compatible(symbol->datatype)) ERROR;
  1769 	BYTE_operator_result_type();
  1625   XXX_operator(&(this->implicit_variable_result), get_datatype_info_c::is_BOOL_compatible(this->current_operand->datatype)?" |= !":" |= ~", this->current_operand);
  1770 	XXX_operator(&(this->default_variable_name),
       
  1771                  get_datatype_info_c::is_BOOL_compatible(this->current_operand_type)?" |= !":" |= ~",
       
  1772                  this->current_operand);
       
  1773     /* the data type resulting from this operation... */
       
  1774     this->default_variable_name.current_type = this->current_operand_type;
       
  1775   }
       
  1776   else {ERROR;}
       
  1777   return NULL;
  1626   return NULL;
  1778 }
  1627 }
  1779 
  1628 
  1780 void *visit(XORN_operator_c *symbol)	{
  1629 void *visit(XORN_operator_c *symbol)	{
  1781   if (get_datatype_info_c::is_ANY_BIT_compatible(this->default_variable_name.current_type)) {
  1630   if (!get_datatype_info_c::is_ANY_BIT_compatible(symbol->datatype)) ERROR;
  1782 	BYTE_operator_result_type();
  1631   // bit by bit exclusive OR !! Also seems to work with boolean types!
  1783 	XXX_operator(&(this->default_variable_name),
  1632   XXX_operator(&(this->implicit_variable_result), get_datatype_info_c::is_BOOL_compatible(this->current_operand->datatype)?" ^= !":" ^= ~", this->current_operand);
  1784                  // bit by bit exclusive OR !! Also seems to work with boolean types!
  1633   return NULL;
  1785                  get_datatype_info_c::is_BOOL_compatible(this->current_operand_type)?" ^= !":" ^= ~",
  1634 }
  1786                  this->current_operand);
       
  1787     /* the data type resulting from this operation... */
       
  1788     this->default_variable_name.current_type = this->current_operand_type;
       
  1789   }
       
  1790   else {ERROR;}
       
  1791   return NULL;
       
  1792 }
       
  1793 
       
  1794 
  1635 
  1795 void *visit(ADD_operator_c *symbol)	{
  1636 void *visit(ADD_operator_c *symbol)	{
  1796   if (get_datatype_info_c::is_TIME_compatible      (symbol->datatype) ||
  1637   if (get_datatype_info_c::is_TIME_compatible(symbol->datatype) || get_datatype_info_c::is_ANY_DATE_compatible  (symbol->datatype)) 
  1797       get_datatype_info_c::is_ANY_DATE_compatible  (symbol->datatype)) {
  1638         XXX_function(&(this->implicit_variable_result), "__time_add", &(this->implicit_variable_current), this->current_operand);
  1798     XXX_function("__time_add", &(this->default_variable_name), this->current_operand);
  1639   else  XXX_operator(&(this->implicit_variable_result), " += ", this->current_operand);
  1799     /* the data type resulting from this operation... */
       
  1800     this->default_variable_name.current_type = this->current_operand_type;
       
  1801   } else {
       
  1802     NUM_operator_result_type();
       
  1803     XXX_operator(&(this->default_variable_name), " += ", this->current_operand);
       
  1804     /* the data type resulting from this operation... */
       
  1805     this->default_variable_name.current_type = this->current_operand_type;
       
  1806   }
       
  1807   return NULL;
  1640   return NULL;
  1808 }
  1641 }
  1809 
  1642 
  1810 void *visit(SUB_operator_c *symbol)	{
  1643 void *visit(SUB_operator_c *symbol)	{
  1811   if (get_datatype_info_c::is_TIME_compatible      (symbol->datatype) ||
  1644   if (get_datatype_info_c::is_TIME_compatible(symbol->datatype) || get_datatype_info_c::is_ANY_DATE_compatible  (symbol->datatype))
  1812       get_datatype_info_c::is_ANY_DATE_compatible  (symbol->datatype)) {
  1645         XXX_function(&(this->implicit_variable_result), "__time_sub", &(this->implicit_variable_current), this->current_operand);
  1813     XXX_function("__time_sub", &(this->default_variable_name), this->current_operand);
  1646   else  XXX_operator(&(this->implicit_variable_result), " -= ", this->current_operand);
  1814     /* the data type resulting from this operation... */
       
  1815     this->default_variable_name.current_type = this->current_operand_type;
       
  1816   } else  {
       
  1817     NUM_operator_result_type();
       
  1818     XXX_operator(&(this->default_variable_name), " -= ", this->current_operand);
       
  1819     /* the data type resulting from this operation... */
       
  1820     this->default_variable_name.current_type = this->current_operand_type;
       
  1821   }
       
  1822   return NULL;
  1647   return NULL;
  1823 }
  1648 }
  1824 
  1649 
  1825 void *visit(MUL_operator_c *symbol)	{
  1650 void *visit(MUL_operator_c *symbol)	{
  1826   if (get_datatype_info_c::is_TIME_compatible      (symbol->datatype)) {
  1651   if (get_datatype_info_c::is_TIME_compatible(symbol->datatype))
  1827     XXX_function("__time_mul", &(this->default_variable_name), this->current_operand);
  1652         XXX_function(&(this->implicit_variable_result), "__time_mul", &(this->implicit_variable_current), this->current_operand);
  1828     /* the data type resulting from this operation is unchanged! */
  1653   else  XXX_operator(&(this->implicit_variable_result), " *= ", this->current_operand);
  1829   } else {
       
  1830     NUM_operator_result_type();
       
  1831     XXX_operator(&(this->default_variable_name), " *= ", this->current_operand);
       
  1832     /* the data type resulting from this operation... */
       
  1833     this->default_variable_name.current_type = this->current_operand_type;
       
  1834   }
       
  1835   return NULL;
  1654   return NULL;
  1836 }
  1655 }
  1837 
  1656 
  1838 void *visit(DIV_operator_c *symbol)	{
  1657 void *visit(DIV_operator_c *symbol)	{
  1839   if (get_datatype_info_c::is_TIME_compatible      (symbol->datatype)) {
  1658   if (get_datatype_info_c::is_TIME_compatible(symbol->datatype))
  1840     XXX_function("__time_div", &(this->default_variable_name), this->current_operand);
  1659         XXX_function(&(this->implicit_variable_result), "__time_div", &(this->implicit_variable_current), this->current_operand);
  1841     /* the data type resulting from this operation is unchanged! */
  1660   else  XXX_operator(&(this->implicit_variable_result), " /= ", this->current_operand);
  1842   } else {
  1661   return NULL;
  1843     NUM_operator_result_type();
  1662 }
  1844     XXX_operator(&(this->default_variable_name), " /= ", this->current_operand);
  1663 
  1845     /* the data type resulting from this operation... */
  1664 void *visit(MOD_operator_c *symbol)	{XXX_operator(&(this->implicit_variable_result), " %= ", this->current_operand); return NULL;}
  1846     this->default_variable_name.current_type = this->current_operand_type;
       
  1847     return NULL;
       
  1848   }
       
  1849   return NULL;
       
  1850 }
       
  1851 
       
  1852 void *visit(MOD_operator_c *symbol)	{
       
  1853   NUM_operator_result_type();
       
  1854   XXX_operator(&(this->default_variable_name), " %= ", this->current_operand);
       
  1855   /* the data type resulting from this operation... */
       
  1856   this->default_variable_name.current_type = this->current_operand_type;
       
  1857   return NULL;
       
  1858 }
       
  1859 
  1665 
  1860 void *visit(GT_operator_c *symbol)	{CMP_operator(this->current_operand, "GT_"); return NULL;}
  1666 void *visit(GT_operator_c *symbol)	{CMP_operator(this->current_operand, "GT_"); return NULL;}
  1861 void *visit(GE_operator_c *symbol)	{CMP_operator(this->current_operand, "GE_"); return NULL;}
  1667 void *visit(GE_operator_c *symbol)	{CMP_operator(this->current_operand, "GE_"); return NULL;}
  1862 void *visit(EQ_operator_c *symbol)	{CMP_operator(this->current_operand, "EQ_"); return NULL;}
  1668 void *visit(EQ_operator_c *symbol)	{CMP_operator(this->current_operand, "EQ_"); return NULL;}
  1863 void *visit(LT_operator_c *symbol)	{CMP_operator(this->current_operand, "LT_"); return NULL;}
  1669 void *visit(LT_operator_c *symbol)	{CMP_operator(this->current_operand, "LT_"); return NULL;}
  1909 }
  1715 }
  1910 
  1716 
  1911 //SYM_REF0(JMP_operator_c)
  1717 //SYM_REF0(JMP_operator_c)
  1912 void *visit(JMP_operator_c *symbol)	{
  1718 void *visit(JMP_operator_c *symbol)	{
  1913   if (NULL == this->jump_label) ERROR;
  1719   if (NULL == this->jump_label) ERROR;
  1914 
       
  1915   s4o.print("goto ");
  1720   s4o.print("goto ");
  1916   this->jump_label->accept(*this);
  1721   this->jump_label->accept(*this);
  1917   /* the data type resulting from this operation is unchanged! */
       
  1918   return NULL;
  1722   return NULL;
  1919 }
  1723 }
  1920 
  1724 
  1921 // SYM_REF0(JMPC_operator_c)
  1725 // SYM_REF0(JMPC_operator_c)
  1922 void *visit(JMPC_operator_c *symbol)	{
  1726 void *visit(JMPC_operator_c *symbol)	{
  1923   if (NULL == this->jump_label) ERROR;
  1727   if (NULL == this->jump_label) ERROR;
  1924 
       
  1925   C_modifier();
  1728   C_modifier();
  1926   s4o.print("goto ");
  1729   s4o.print("goto ");
  1927   this->jump_label->accept(*this);
  1730   this->jump_label->accept(*this);
  1928   /* the data type resulting from this operation is unchanged! */
       
  1929   return NULL;
  1731   return NULL;
  1930 }
  1732 }
  1931 
  1733 
  1932 // SYM_REF0(JMPCN_operator_c)
  1734 // SYM_REF0(JMPCN_operator_c)
  1933 void *visit(JMPCN_operator_c *symbol)	{
  1735 void *visit(JMPCN_operator_c *symbol)	{
  1934   if (NULL == this->jump_label) ERROR;
  1736   if (NULL == this->jump_label) ERROR;
  1935 
       
  1936   CN_modifier();
  1737   CN_modifier();
  1937   s4o.print("goto ");
  1738   s4o.print("goto ");
  1938   this->jump_label->accept(*this);
  1739   this->jump_label->accept(*this);
  1939   /* the data type resulting from this operation is unchanged! */
       
  1940   return NULL;
  1740   return NULL;
  1941 }
  1741 }
  1942 
  1742 
  1943 #if 0
  1743 #if 0
  1944 /*| [NOT] any_identifier SENDTO */
  1744 /*| [NOT] any_identifier SENDTO */
  2000   /* Note: current_type may start off with NULL */
  1800   /* Note: current_type may start off with NULL */
  2001 
  1801 
  2002   this->var_name = new identifier_c(var_name_str);
  1802   this->var_name = new identifier_c(var_name_str);
  2003   if (NULL == this->var_name) ERROR;
  1803   if (NULL == this->var_name) ERROR;
  2004 
  1804 
  2005   this->current_type = current_type;
  1805   this->datatype = current_type;
  2006 }
  1806 }