stage4/generate_c/generate_c_inlinefcall.cc
changeset 337 9a2262fb7994
parent 336 229eb3e29216
child 345 894c0e6d951c
equal deleted inserted replaced
336:229eb3e29216 337:9a2262fb7994
    35       complextype_suffix_vg
    35       complextype_suffix_vg
    36     } variablegeneration_t;
    36     } variablegeneration_t;
    37 
    37 
    38   private:
    38   private:
    39 
    39 
       
    40     /* The initial value that should be given to the IL default variable
       
    41 	 * imediately after a parenthesis is opened.
       
    42 	 * This variable is only used to pass data from the
       
    43 	 * il_expression_c visitor to the simple_instr_list_c visitor.
       
    44 	 *
       
    45 	 * e.g.:
       
    46 	 *         LD var1
       
    47 	 *         AND ( var2
       
    48 	 *         OR var3
       
    49 	 *         )
       
    50 	 *
       
    51 	 * In the above code sample, the line 'AND ( var2' constitutes
       
    52 	 * an il_expression_c, where var2 should be loaded into the
       
    53 	 * il default variable before continuing with the expression
       
    54 	 * inside the parenthesis.
       
    55 	 * Unfortunately, only the simple_instr_list_c may do the
       
    56 	 * initial laoding of the var2 bariable following the parenthesis,
       
    57 	 * so the il_expression_c visitor will have to pass 'var2' as a
       
    58 	 * parameter to the simple_instr_list_c visitor.
       
    59 	 * Ergo, the existance of the following parameter...!
       
    60 	 */
       
    61 	symbol_c *il_default_variable_init_value;
       
    62 
       
    63     /* Operand to the IL operation currently being processed... */
       
    64 	/* These variables are used to pass data from the
       
    65 	 * il_simple_operation_c and il_expression_c visitors
       
    66 	 * to the il operator visitors (i.e. LD_operator_c,
       
    67 	 * LDN_operator_c, ST_operator_c, STN_operator_c, ...)
       
    68 	 */
       
    69 	symbol_c *current_operand;
       
    70 	symbol_c *current_operand_type;
       
    71 
       
    72 	 /* The result of the comparison IL operations (GT, EQ, LT, ...)
       
    73 	 * is a boolean variable.
       
    74 	 * This class keeps track of the current data type stored in the
       
    75 	 * il default variable. This is usually done by keeping a reference
       
    76 	 * to the data type of the last operand. Nevertheless, in the case of
       
    77 	 * the comparison IL operators, the data type of the result (a boolean)
       
    78 	 * is not the data type of the operand. We therefore need an object
       
    79 	 * of the boolean data type to keep as a reference of the current
       
    80 	 * data type.
       
    81 	 * The following object is it...
       
    82 	 */
       
    83 	bool_type_name_c bool_type;
       
    84 	lint_type_name_c lint_type;
       
    85 	lword_type_name_c lword_type;
       
    86 	lreal_type_name_c lreal_type;
       
    87 
    40     /* The name of the IL default variable... */
    88     /* The name of the IL default variable... */
    41 	#define IL_DEFVAR   VAR_LEADER "IL_DEFVAR"
    89 	#define IL_DEFVAR   VAR_LEADER "IL_DEFVAR"
       
    90 
    42 	/* The name of the variable used to pass the result of a
    91 	/* The name of the variable used to pass the result of a
    43 	 * parenthesised instruction list to the immediately preceding
    92 	 * parenthesised instruction list to the immediately preceding
    44 	 * scope ...
    93 	 * scope ...
    45 	 */
    94 	 */
    46 	il_default_variable_c default_variable_name;
    95     #define IL_DEFVAR_BACK   VAR_LEADER "IL_DEFVAR_BACK"
       
    96     il_default_variable_c default_variable_name;
       
    97 	il_default_variable_c default_variable_back_name;
    47 
    98 
    48 	symbol_c* current_array_type;
    99 	symbol_c* current_array_type;
    49 
   100 
    50 	int fcall_number;
   101 	int fcall_number;
    51 	symbol_c *fbname;
   102 	symbol_c *fbname;
    59     variablegeneration_t wanted_variablegeneration;
   110     variablegeneration_t wanted_variablegeneration;
    60 
   111 
    61   public:
   112   public:
    62     generate_c_inlinefcall_c(stage4out_c *s4o_ptr, symbol_c *name, symbol_c *scope, const char *variable_prefix = NULL)
   113     generate_c_inlinefcall_c(stage4out_c *s4o_ptr, symbol_c *name, symbol_c *scope, const char *variable_prefix = NULL)
    63     : generate_c_typedecl_c(s4o_ptr),
   114     : generate_c_typedecl_c(s4o_ptr),
    64       default_variable_name(IL_DEFVAR, NULL)
   115       default_variable_name(IL_DEFVAR, NULL),
       
   116       default_variable_back_name(IL_DEFVAR_BACK, NULL)
    65     {
   117     {
    66       search_expression_type = new search_expression_type_c(scope);
   118       search_expression_type = new search_expression_type_c(scope);
    67       search_varfb_instance_type = new search_varfb_instance_type_c(scope);
   119       search_varfb_instance_type = new search_varfb_instance_type_c(scope);
    68       this->set_variable_prefix(variable_prefix);
   120       this->set_variable_prefix(variable_prefix);
    69       fcall_number = 0;
   121       fcall_number = 0;
   189       s4o.indent_left();
   241       s4o.indent_left();
   190       s4o.print(s4o.indent_spaces + "}\n\n");
   242       s4o.print(s4o.indent_spaces + "}\n\n");
   191     }
   243     }
   192 
   244 
   193   private:
   245   private:
       
   246 
       
   247     /* A helper function... */
       
   248 	void *CMP_operator_result_type() {
       
   249 	  /* the data type resulting from this operation... */
       
   250 	  this->default_variable_name.current_type = &(this->bool_type);
       
   251 	  return NULL;
       
   252 	}
       
   253 
       
   254 	/* A helper function... */
       
   255     void *BYTE_operator_result_type(void) {
       
   256 	  if (search_expression_type->is_literal_integer_type(this->default_variable_name.current_type)) {
       
   257 		if (search_expression_type->is_literal_integer_type(this->current_operand_type))
       
   258 		  this->default_variable_name.current_type = &(this->lword_type);
       
   259 		else
       
   260 		  this->default_variable_name.current_type = this->current_operand_type;
       
   261 	  }
       
   262 	  else if (search_expression_type->is_literal_integer_type(this->current_operand_type))
       
   263 		  this->current_operand_type = this->default_variable_name.current_type;
       
   264 	  return NULL;
       
   265 	}
       
   266 
       
   267     /* A helper function... */
       
   268     void *NUM_operator_result_type(void) {
       
   269 	  if (search_expression_type->is_literal_real_type(this->default_variable_name.current_type)) {
       
   270 		if (search_expression_type->is_literal_integer_type(this->current_operand_type) ||
       
   271 			search_expression_type->is_literal_real_type(this->current_operand_type))
       
   272 		  this->default_variable_name.current_type = &(this->lreal_type);
       
   273 		else
       
   274 		  this->default_variable_name.current_type = this->current_operand_type;
       
   275 	  }
       
   276 	  else if (search_expression_type->is_literal_integer_type(this->default_variable_name.current_type)) {
       
   277 		if (search_expression_type->is_literal_integer_type(this->current_operand_type))
       
   278 		  this->default_variable_name.current_type = &(this->lint_type);
       
   279 		else if (search_expression_type->is_literal_real_type(this->current_operand_type))
       
   280 		  this->default_variable_name.current_type = &(this->lreal_type);
       
   281 		else
       
   282 		  this->default_variable_name.current_type = this->current_operand_type;
       
   283 	  }
       
   284 	  else if (search_expression_type->is_literal_integer_type(this->current_operand_type) ||
       
   285 			   search_expression_type->is_literal_real_type(this->current_operand_type))
       
   286 		this->current_operand_type = this->default_variable_name.current_type;
       
   287 	  return NULL;
       
   288 	}
   194 
   289 
   195     void *print_getter(symbol_c *symbol) {
   290     void *print_getter(symbol_c *symbol) {
   196       unsigned int vartype = search_varfb_instance_type->get_vartype(symbol);
   291       unsigned int vartype = search_varfb_instance_type->get_vartype(symbol);
   197       if (vartype == search_var_instance_decl_c::external_vt)
   292       if (vartype == search_var_instance_decl_c::external_vt)
   198     	s4o.print(GET_EXTERNAL);
   293     	s4o.print(GET_EXTERNAL);
   338 
   433 
   339     /***********************************/
   434     /***********************************/
   340     /* B 2.1 Instructions and Operands */
   435     /* B 2.1 Instructions and Operands */
   341     /***********************************/
   436     /***********************************/
   342 
   437 
       
   438     /* | label ':' [il_incomplete_instruction] eol_list */
       
   439     // SYM_REF2(il_instruction_c, label, il_instruction)
       
   440     void *visit(il_instruction_c *symbol) {
       
   441       if (NULL != symbol->il_instruction) {
       
   442         symbol->il_instruction->accept(*this);
       
   443       }
       
   444       return NULL;
       
   445     }
       
   446     /* | il_simple_operator [il_operand] */
       
   447     //SYM_REF2(il_simple_operation_c, il_simple_operator, il_operand)
       
   448     void *visit(il_simple_operation_c *symbol) {
       
   449       this->current_operand = symbol->il_operand;
       
   450       if (NULL == this->current_operand) {
       
   451         this->current_operand_type = NULL;
       
   452       } else {
       
   453         this->current_operand_type = search_expression_type->get_type(this->current_operand);
       
   454         if (NULL == this->current_operand_type) ERROR;
       
   455       }
       
   456 
       
   457       symbol->il_simple_operator->accept(*this);
       
   458 
       
   459       this->current_operand = NULL;
       
   460       this->current_operand_type = NULL;
       
   461       return NULL;
       
   462     }
       
   463 
   343     void *visit(il_function_call_c *symbol) {
   464     void *visit(il_function_call_c *symbol) {
   344       symbol_c* function_type_prefix = NULL;
   465       symbol_c* function_type_prefix = NULL;
   345       symbol_c* function_name = NULL;
   466       symbol_c* function_name = NULL;
   346       symbol_c* function_type_suffix = NULL;
   467       symbol_c* function_type_suffix = NULL;
   347       DECLARE_PARAM_LIST()
   468       DECLARE_PARAM_LIST()
   445       if (has_output_params)
   566       if (has_output_params)
   446         generate_inline(function_name, function_type_prefix, function_type_suffix, param_list);
   567         generate_inline(function_name, function_type_prefix, function_type_suffix, param_list);
   447 
   568 
   448       CLEAR_PARAM_LIST()
   569       CLEAR_PARAM_LIST()
   449 
   570 
       
   571       /* the data type resulting from this operation... */
       
   572       default_variable_name.current_type = function_type_prefix;
       
   573       return NULL;
       
   574     }
       
   575 
       
   576     /* | il_expr_operator '(' [il_operand] eol_list [simple_instr_list] ')' */
       
   577     //SYM_REF4(il_expression_c, il_expr_operator, il_operand, simple_instr_list, unused)
       
   578     void *visit(il_expression_c *symbol) {
       
   579       /* We will be recursevely interpreting an instruction list,
       
   580        * so we store a backup of the data type of the value currently stored
       
   581        * in the default variable, and set the current data type to NULL
       
   582        */
       
   583       symbol_c *old_current_default_variable_data_type = this->default_variable_name.current_type;
       
   584       this->default_variable_name.current_type = NULL;
       
   585 
       
   586      /* Pass the symbol->il_operand to the simple_instr_list visitor
       
   587       * using the il_default_variable_init_value parameter...
       
   588       * Note that the simple_instr_list_c visitor will set this parameter
       
   589       * to NULL as soon as it does not require it any longer,
       
   590       * so we don't do it here again after the
       
   591       *   symbol->simple_instr_list->accept(*this);
       
   592       * returns...
       
   593       */
       
   594       this->il_default_variable_init_value = symbol->il_operand;
       
   595 
       
   596       /* Now do the parenthesised instructions... */
       
   597       /* NOTE: the following code line will get the variable
       
   598        * this->default_variable_name.current_type updated!
       
   599        */
       
   600       symbol->simple_instr_list->accept(*this);
       
   601 
       
   602       /* Now do the operation, using the previous result! */
       
   603       /* NOTE: The result of the previous instruction list will be stored
       
   604        * in a variable named IL_DEFVAR_BACK. This is done in the visitor
       
   605        * to instruction_list_c objects...
       
   606        */
       
   607       this->current_operand = &(this->default_variable_back_name);
       
   608       this->current_operand_type = this->default_variable_back_name.current_type;
       
   609 
       
   610       this->default_variable_name.current_type = old_current_default_variable_data_type;
       
   611       if (NULL == this->current_operand_type) ERROR;
       
   612 
       
   613       symbol->il_expr_operator->accept(*this);
       
   614 
       
   615       this->current_operand = NULL;
       
   616       this->current_operand_type = NULL;
       
   617       this->default_variable_back_name.current_type = NULL;
   450       return NULL;
   618       return NULL;
   451     }
   619     }
   452 
   620 
   453     /* | function_name '(' eol_list [il_param_list] ')' */
   621     /* | function_name '(' eol_list [il_param_list] ')' */
   454     // SYM_REF2(il_formal_funct_call_c, function_name, il_param_list)
   622     // SYM_REF2(il_formal_funct_call_c, function_name, il_param_list)
   555       if (has_output_params)
   723       if (has_output_params)
   556         generate_inline(function_name, function_type_prefix, function_type_suffix, param_list);
   724         generate_inline(function_name, function_type_prefix, function_type_suffix, param_list);
   557 
   725 
   558       CLEAR_PARAM_LIST()
   726       CLEAR_PARAM_LIST()
   559 
   727 
       
   728       /* the data type resulting from this operation... */
       
   729       default_variable_name.current_type = function_type_prefix;
       
   730       return NULL;
       
   731     }
       
   732 
       
   733     /* | simple_instr_list il_simple_instruction */
       
   734     // SYM_LIST(simple_instr_list_c)
       
   735     void *visit(simple_instr_list_c *symbol) {
       
   736       /* Check whether we should initiliase the il default variable... */
       
   737       if (NULL != this->il_default_variable_init_value) {
       
   738         /* Yes, we must... */
       
   739         /* We will do it by instatiating a LD operator, and having this
       
   740          * same generate_c_il_c class visiting it!
       
   741          */
       
   742         LD_operator_c ld_oper;
       
   743         il_simple_operation_c il_simple_oper(&ld_oper, this->il_default_variable_init_value);
       
   744 
       
   745         il_simple_oper.accept(*this);
       
   746       }
       
   747 
       
   748       /* this parameter no longer required... */
       
   749       this->il_default_variable_init_value = NULL;
       
   750 
       
   751       iterator_visitor_c::visit(symbol);
       
   752 
       
   753       /* copy the result in the default variable to the variable
       
   754 	   * used to pass the data out to the scope enclosing
       
   755 	   * the current scope!
       
   756 	   *
       
   757 	   * We also need to update the data type currently stored within
       
   758 	   * the variable used to pass the data to the outside scope...
       
   759 	   */
       
   760 	  this->default_variable_back_name.current_type = this->default_variable_name.current_type;
       
   761 	  return NULL;
       
   762     }
       
   763 
       
   764     void *visit(LD_operator_c *symbol)	{
       
   765       /* the data type resulting from this operation... */
       
   766       this->default_variable_name.current_type = this->current_operand_type;
       
   767       return NULL;
       
   768     }
       
   769 
       
   770     void *visit(LDN_operator_c *symbol)	{
       
   771       /* the data type resulting from this operation... */
       
   772       this->default_variable_name.current_type = this->current_operand_type;
       
   773       return NULL;
       
   774     }
       
   775 
       
   776     void *visit(ADD_operator_c *symbol)	{
       
   777       if (search_expression_type->is_time_type(this->default_variable_name.current_type) &&
       
   778           search_expression_type->is_time_type(this->current_operand_type)) {
       
   779         /* the data type resulting from this operation... */
       
   780         this->default_variable_name.current_type = this->current_operand_type;
       
   781         return NULL;
       
   782       }
       
   783       if (search_expression_type->is_num_type(this->default_variable_name.current_type) &&
       
   784           search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) {
       
   785         return NUM_operator_result_type();
       
   786       }
       
   787       ERROR;
       
   788       return NULL;
       
   789     }
       
   790 
       
   791     void *visit(SUB_operator_c *symbol)	{
       
   792       if (search_expression_type->is_time_type(this->default_variable_name.current_type) &&
       
   793           search_expression_type->is_time_type(this->current_operand_type)) {
       
   794         /* the data type resulting from this operation... */
       
   795         this->default_variable_name.current_type = this->current_operand_type;
       
   796         return NULL;
       
   797       }
       
   798       if (search_expression_type->is_num_type(this->default_variable_name.current_type) &&
       
   799           search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) {
       
   800     	return NUM_operator_result_type();
       
   801       }
       
   802       ERROR;
       
   803       return NULL;
       
   804     }
       
   805 
       
   806     void *visit(MUL_operator_c *symbol)	{
       
   807       if (search_expression_type->is_time_type(this->default_variable_name.current_type) &&
       
   808           search_expression_type->is_integer_type(this->current_operand_type)) {
       
   809         return NULL;
       
   810       }
       
   811       if (search_expression_type->is_num_type(this->default_variable_name.current_type) &&
       
   812           search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) {
       
   813     	return NUM_operator_result_type();
       
   814       }
       
   815       ERROR;
       
   816       return NULL;
       
   817     }
       
   818 
       
   819     void *visit(DIV_operator_c *symbol)	{
       
   820       if (search_expression_type->is_time_type(this->default_variable_name.current_type) &&
       
   821           search_expression_type->is_integer_type(this->current_operand_type)) {
       
   822         return NULL;
       
   823       }
       
   824       if (search_expression_type->is_num_type(this->default_variable_name.current_type) &&
       
   825           search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) {
       
   826         return NUM_operator_result_type();
       
   827       }
       
   828       ERROR;
       
   829       return NULL;
       
   830     }
       
   831 
       
   832     void *visit(MOD_operator_c *symbol)	{
       
   833       if (search_expression_type->is_num_type(this->default_variable_name.current_type) &&
       
   834           search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) {
       
   835         return NUM_operator_result_type();
       
   836       }
       
   837       ERROR;
       
   838       return NULL;
       
   839     }
       
   840 
       
   841     void *visit(GT_operator_c *symbol)	{
       
   842       if (!search_base_type.type_is_enumerated(this->default_variable_name.current_type) &&
       
   843           search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type))
       
   844         return CMP_operator_result_type();
       
   845       ERROR;
       
   846       return NULL;
       
   847     }
       
   848 
       
   849     void *visit(GE_operator_c *symbol)	{
       
   850       if (!search_base_type.type_is_enumerated(this->default_variable_name.current_type) &&
       
   851           search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type))
       
   852         return CMP_operator_result_type();
       
   853       ERROR;
       
   854       return NULL;
       
   855     }
       
   856 
       
   857     void *visit(EQ_operator_c *symbol)	{
       
   858       if (search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type))
       
   859         return CMP_operator_result_type();
       
   860       ERROR;
       
   861       return NULL;
       
   862     }
       
   863 
       
   864     void *visit(LT_operator_c *symbol)	{
       
   865       if (!search_base_type.type_is_enumerated(this->default_variable_name.current_type) &&
       
   866           search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type))
       
   867         return CMP_operator_result_type();
       
   868       return NULL;
       
   869     }
       
   870 
       
   871     void *visit(LE_operator_c *symbol)	{
       
   872       if (!search_base_type.type_is_enumerated(this->default_variable_name.current_type) &&
       
   873           search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type))
       
   874         return CMP_operator_result_type();
       
   875       ERROR;
       
   876       return NULL;
       
   877     }
       
   878 
       
   879     void *visit(NE_operator_c *symbol)	{
       
   880       if (search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type))
       
   881         return CMP_operator_result_type();
       
   882       ERROR;
   560       return NULL;
   883       return NULL;
   561     }
   884     }
   562 
   885 
   563     /***************************************/
   886     /***************************************/
   564     /* B.3 - Language ST (Structured Text) */
   887     /* B.3 - Language ST (Structured Text) */
   565     /***************************************/
   888     /***************************************/
   566     /***********************/
   889     /***********************/
   567     /* B 3.1 - Expressions */
   890     /* B 3.1 - Expressions */
   568     /***********************/
   891     /***********************/
       
   892 
       
   893     void *visit(statement_list_c *symbol) {
       
   894 	  function_call_iterator_c fc_iterator(symbol);
       
   895 	  symbol_c* function_call;
       
   896 	  while ((function_call = fc_iterator.next()) != NULL) {
       
   897 		function_call->accept(*this);
       
   898 	  }
       
   899 	  return NULL;
       
   900 	}
   569 
   901 
   570     void *visit(function_invocation_c *symbol) {
   902     void *visit(function_invocation_c *symbol) {
   571       symbol_c* function_type_prefix = NULL;
   903       symbol_c* function_type_prefix = NULL;
   572       symbol_c* function_name = NULL;
   904       symbol_c* function_name = NULL;
   573       symbol_c* function_type_suffix = NULL;
   905       symbol_c* function_type_suffix = NULL;
   665       if (has_output_params)
   997       if (has_output_params)
   666         generate_inline(function_name, function_type_prefix, function_type_suffix, param_list);
   998         generate_inline(function_name, function_type_prefix, function_type_suffix, param_list);
   667 
   999 
   668       CLEAR_PARAM_LIST()
  1000       CLEAR_PARAM_LIST()
   669 
  1001 
   670 	  return NULL;
  1002       return NULL;
   671     }
  1003     }
   672 
  1004 
   673 };  /* generate_c_inlinefcall_c */
  1005 };  /* generate_c_inlinefcall_c */
   674 
  1006 
   675 
  1007