stage4/generate_c/generate_c_inlinefcall.cc
changeset 355 30db860bd3bd
parent 350 2c3c4dc34979
parent 346 620fd98a021d
child 380 b78e59ed4269
equal deleted inserted replaced
354:0f24db96b519 355:30db860bd3bd
    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;
   201       s4o.indent_left();
   253       s4o.indent_left();
   202       s4o.print(s4o.indent_spaces + "}\n\n");
   254       s4o.print(s4o.indent_spaces + "}\n\n");
   203     }
   255     }
   204 
   256 
   205   private:
   257   private:
       
   258 
       
   259     /* A helper function... */
       
   260 	void CMP_operator_result_type() {
       
   261 	  /* the data type resulting from this operation... */
       
   262 	  this->default_variable_name.current_type = &(this->bool_type);
       
   263 	}
       
   264 
       
   265 	/* A helper function... */
       
   266     void BYTE_operator_result_type(void) {
       
   267 	  if (search_expression_type->is_literal_integer_type(this->default_variable_name.current_type)) {
       
   268 		if (search_expression_type->is_literal_integer_type(this->current_operand_type))
       
   269 		  this->default_variable_name.current_type = &(this->lword_type);
       
   270 		else
       
   271 		  this->default_variable_name.current_type = this->current_operand_type;
       
   272 	  }
       
   273 	  else if (search_expression_type->is_literal_integer_type(this->current_operand_type))
       
   274 		  this->current_operand_type = this->default_variable_name.current_type;
       
   275 	}
       
   276 
       
   277     /* A helper function... */
       
   278     void NUM_operator_result_type(void) {
       
   279 	  if (search_expression_type->is_literal_real_type(this->default_variable_name.current_type)) {
       
   280 		if (search_expression_type->is_literal_integer_type(this->current_operand_type) ||
       
   281 			search_expression_type->is_literal_real_type(this->current_operand_type))
       
   282 		  this->default_variable_name.current_type = &(this->lreal_type);
       
   283 		else
       
   284 		  this->default_variable_name.current_type = this->current_operand_type;
       
   285 	  }
       
   286 	  else if (search_expression_type->is_literal_integer_type(this->default_variable_name.current_type)) {
       
   287 		if (search_expression_type->is_literal_integer_type(this->current_operand_type))
       
   288 		  this->default_variable_name.current_type = &(this->lint_type);
       
   289 		else if (search_expression_type->is_literal_real_type(this->current_operand_type))
       
   290 		  this->default_variable_name.current_type = &(this->lreal_type);
       
   291 		else
       
   292 		  this->default_variable_name.current_type = this->current_operand_type;
       
   293 	  }
       
   294 	  else if (search_expression_type->is_literal_integer_type(this->current_operand_type) ||
       
   295 			   search_expression_type->is_literal_real_type(this->current_operand_type))
       
   296 		this->current_operand_type = this->default_variable_name.current_type;
       
   297 	}
   206 
   298 
   207     void *print_getter(symbol_c *symbol) {
   299     void *print_getter(symbol_c *symbol) {
   208       unsigned int vartype = search_varfb_instance_type->get_vartype(symbol);
   300       unsigned int vartype = search_varfb_instance_type->get_vartype(symbol);
   209       if (vartype == search_var_instance_decl_c::external_vt)
   301       if (vartype == search_var_instance_decl_c::external_vt)
   210     	s4o.print(GET_EXTERNAL);
   302     	s4o.print(GET_EXTERNAL);
   349     /****************************************/
   441     /****************************************/
   350 
   442 
   351     /***********************************/
   443     /***********************************/
   352     /* B 2.1 Instructions and Operands */
   444     /* B 2.1 Instructions and Operands */
   353     /***********************************/
   445     /***********************************/
       
   446 
       
   447     /* | label ':' [il_incomplete_instruction] eol_list */
       
   448     // SYM_REF2(il_instruction_c, label, il_instruction)
       
   449     void *visit(il_instruction_c *symbol) {
       
   450       if (NULL != symbol->il_instruction) {
       
   451         symbol->il_instruction->accept(*this);
       
   452       }
       
   453       return NULL;
       
   454     }
       
   455     /* | il_simple_operator [il_operand] */
       
   456     //SYM_REF2(il_simple_operation_c, il_simple_operator, il_operand)
       
   457     void *visit(il_simple_operation_c *symbol) {
       
   458       this->current_operand = symbol->il_operand;
       
   459       if (NULL == this->current_operand) {
       
   460         this->current_operand_type = NULL;
       
   461       } else {
       
   462         this->current_operand_type = search_expression_type->get_type(this->current_operand);
       
   463         if (NULL == this->current_operand_type) ERROR;
       
   464       }
       
   465 
       
   466       symbol->il_simple_operator->accept(*this);
       
   467 
       
   468       this->current_operand = NULL;
       
   469       this->current_operand_type = NULL;
       
   470       return NULL;
       
   471     }
   354 
   472 
   355     void *visit(il_function_call_c *symbol) {
   473     void *visit(il_function_call_c *symbol) {
   356       symbol_c* function_type_prefix = NULL;
   474       symbol_c* function_type_prefix = NULL;
   357       symbol_c* function_name = NULL;     
   475       symbol_c* function_name = NULL;     
   358       symbol_c* function_type_suffix = NULL;
   476       symbol_c* function_type_suffix = NULL;
   483       if (has_output_params)
   601       if (has_output_params)
   484         generate_inline(function_name, function_type_prefix, function_type_suffix, param_list, f_decl);
   602         generate_inline(function_name, function_type_prefix, function_type_suffix, param_list, f_decl);
   485 
   603 
   486       CLEAR_PARAM_LIST()
   604       CLEAR_PARAM_LIST()
   487 
   605 
       
   606       /* the data type resulting from this operation... */
       
   607       default_variable_name.current_type = function_type_prefix;
       
   608       return NULL;
       
   609     }
       
   610 
       
   611     /* | il_expr_operator '(' [il_operand] eol_list [simple_instr_list] ')' */
       
   612     //SYM_REF4(il_expression_c, il_expr_operator, il_operand, simple_instr_list, unused)
       
   613     void *visit(il_expression_c *symbol) {
       
   614       /* We will be recursevely interpreting an instruction list,
       
   615        * so we store a backup of the data type of the value currently stored
       
   616        * in the default variable, and set the current data type to NULL
       
   617        */
       
   618       symbol_c *old_current_default_variable_data_type = this->default_variable_name.current_type;
       
   619       this->default_variable_name.current_type = NULL;
       
   620 
       
   621      /* Pass the symbol->il_operand to the simple_instr_list visitor
       
   622       * using the il_default_variable_init_value parameter...
       
   623       * Note that the simple_instr_list_c visitor will set this parameter
       
   624       * to NULL as soon as it does not require it any longer,
       
   625       * so we don't do it here again after the
       
   626       *   symbol->simple_instr_list->accept(*this);
       
   627       * returns...
       
   628       */
       
   629       this->il_default_variable_init_value = symbol->il_operand;
       
   630 
       
   631       /* Now do the parenthesised instructions... */
       
   632       /* NOTE: the following code line will get the variable
       
   633        * this->default_variable_name.current_type updated!
       
   634        */
       
   635       symbol->simple_instr_list->accept(*this);
       
   636 
       
   637       /* Now do the operation, using the previous result! */
       
   638       /* NOTE: The result of the previous instruction list will be stored
       
   639        * in a variable named IL_DEFVAR_BACK. This is done in the visitor
       
   640        * to instruction_list_c objects...
       
   641        */
       
   642       this->current_operand = &(this->default_variable_back_name);
       
   643       this->current_operand_type = this->default_variable_back_name.current_type;
       
   644 
       
   645       this->default_variable_name.current_type = old_current_default_variable_data_type;
       
   646       if (NULL == this->current_operand_type) ERROR;
       
   647 
       
   648       symbol->il_expr_operator->accept(*this);
       
   649 
       
   650       this->current_operand = NULL;
       
   651       this->current_operand_type = NULL;
       
   652       this->default_variable_back_name.current_type = NULL;
   488       return NULL;
   653       return NULL;
   489     }
   654     }
   490 
   655 
   491     /* | function_name '(' eol_list [il_param_list] ')' */
   656     /* | function_name '(' eol_list [il_param_list] ')' */
   492     // SYM_REF2(il_formal_funct_call_c, function_name, il_param_list)
   657     // SYM_REF2(il_formal_funct_call_c, function_name, il_param_list)
   617       if (has_output_params)
   782       if (has_output_params)
   618         generate_inline(function_name, function_type_prefix, function_type_suffix, param_list, f_decl);
   783         generate_inline(function_name, function_type_prefix, function_type_suffix, param_list, f_decl);
   619 
   784 
   620       CLEAR_PARAM_LIST()
   785       CLEAR_PARAM_LIST()
   621 
   786 
       
   787       /* the data type resulting from this operation... */
       
   788       default_variable_name.current_type = function_type_prefix;
       
   789       return NULL;
       
   790     }
       
   791 
       
   792     /* | simple_instr_list il_simple_instruction */
       
   793     // SYM_LIST(simple_instr_list_c)
       
   794     void *visit(simple_instr_list_c *symbol) {
       
   795       /* Check whether we should initiliase the il default variable... */
       
   796       if (NULL != this->il_default_variable_init_value) {
       
   797         /* Yes, we must... */
       
   798         /* We will do it by instatiating a LD operator, and having this
       
   799          * same generate_c_il_c class visiting it!
       
   800          */
       
   801         LD_operator_c ld_oper;
       
   802         il_simple_operation_c il_simple_oper(&ld_oper, this->il_default_variable_init_value);
       
   803 
       
   804         il_simple_oper.accept(*this);
       
   805       }
       
   806 
       
   807       /* this parameter no longer required... */
       
   808       this->il_default_variable_init_value = NULL;
       
   809 
       
   810       iterator_visitor_c::visit(symbol);
       
   811 
       
   812       /* copy the result in the default variable to the variable
       
   813 	   * used to pass the data out to the scope enclosing
       
   814 	   * the current scope!
       
   815 	   *
       
   816 	   * We also need to update the data type currently stored within
       
   817 	   * the variable used to pass the data to the outside scope...
       
   818 	   */
       
   819 	  this->default_variable_back_name.current_type = this->default_variable_name.current_type;
       
   820 	  return NULL;
       
   821     }
       
   822 
       
   823     void *visit(LD_operator_c *symbol)	{
       
   824       /* the data type resulting from this operation... */
       
   825       this->default_variable_name.current_type = this->current_operand_type;
       
   826       return NULL;
       
   827     }
       
   828 
       
   829     void *visit(LDN_operator_c *symbol)	{
       
   830       /* the data type resulting from this operation... */
       
   831       this->default_variable_name.current_type = this->current_operand_type;
       
   832       return NULL;
       
   833     }
       
   834 
       
   835     void *visit(AND_operator_c *symbol)	{
       
   836       if (search_expression_type->is_binary_type(this->default_variable_name.current_type) &&
       
   837           search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) {
       
   838     	BYTE_operator_result_type();
       
   839       }
       
   840       else {ERROR;}
       
   841       return NULL;
       
   842     }
       
   843 
       
   844     void *visit(OR_operator_c *symbol)	{
       
   845       if (search_expression_type->is_binary_type(this->default_variable_name.current_type) &&
       
   846           search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) {
       
   847     	BYTE_operator_result_type();
       
   848       }
       
   849       else {ERROR;}
       
   850       return NULL;
       
   851     }
       
   852 
       
   853     void *visit(XOR_operator_c *symbol)	{
       
   854       if (search_expression_type->is_binary_type(this->default_variable_name.current_type) &&
       
   855           search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) {
       
   856     	BYTE_operator_result_type();
       
   857       }
       
   858       else {ERROR;}
       
   859       return NULL;
       
   860     }
       
   861 
       
   862     void *visit(ANDN_operator_c *symbol)	{
       
   863       if (search_expression_type->is_binary_type(this->default_variable_name.current_type) &&
       
   864           search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) {
       
   865     	BYTE_operator_result_type();
       
   866       }
       
   867       else {ERROR;}
       
   868       return NULL;
       
   869     }
       
   870 
       
   871     void *visit(ORN_operator_c *symbol)	{
       
   872       if (search_expression_type->is_binary_type(this->default_variable_name.current_type) &&
       
   873           search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) {
       
   874     	BYTE_operator_result_type();
       
   875       }
       
   876       else {ERROR;}
       
   877       return NULL;
       
   878     }
       
   879 
       
   880     void *visit(XORN_operator_c *symbol)	{
       
   881       if (search_expression_type->is_binary_type(this->default_variable_name.current_type) &&
       
   882           search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) {
       
   883     	BYTE_operator_result_type();
       
   884       }
       
   885       else {ERROR;}
       
   886       return NULL;
       
   887     }
       
   888 
       
   889     void *visit(ADD_operator_c *symbol)	{
       
   890       if (search_expression_type->is_time_type(this->default_variable_name.current_type) &&
       
   891           search_expression_type->is_time_type(this->current_operand_type)) {
       
   892         /* the data type resulting from this operation... */
       
   893         this->default_variable_name.current_type = this->current_operand_type;
       
   894       }
       
   895       else if (search_expression_type->is_num_type(this->default_variable_name.current_type) &&
       
   896           search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) {
       
   897         NUM_operator_result_type();
       
   898       }
       
   899       else {ERROR;}
       
   900       return NULL;
       
   901     }
       
   902 
       
   903     void *visit(SUB_operator_c *symbol)	{
       
   904       if (search_expression_type->is_time_type(this->default_variable_name.current_type) &&
       
   905           search_expression_type->is_time_type(this->current_operand_type)) {
       
   906         /* the data type resulting from this operation... */
       
   907         this->default_variable_name.current_type = this->current_operand_type;
       
   908       }
       
   909       else if (search_expression_type->is_num_type(this->default_variable_name.current_type) &&
       
   910           search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) {
       
   911     	NUM_operator_result_type();
       
   912       }
       
   913       else {ERROR;}
       
   914       return NULL;
       
   915     }
       
   916 
       
   917     void *visit(MUL_operator_c *symbol)	{
       
   918       if (search_expression_type->is_time_type(this->default_variable_name.current_type) &&
       
   919           search_expression_type->is_integer_type(this->current_operand_type)) {
       
   920         /* the data type resulting from this operation is unchanged! */
       
   921       }
       
   922       else if (search_expression_type->is_num_type(this->default_variable_name.current_type) &&
       
   923           search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) {
       
   924     	NUM_operator_result_type();
       
   925       }
       
   926       else {ERROR;}
       
   927       return NULL;
       
   928     }
       
   929 
       
   930     void *visit(DIV_operator_c *symbol)	{
       
   931       if (search_expression_type->is_time_type(this->default_variable_name.current_type) &&
       
   932           search_expression_type->is_integer_type(this->current_operand_type)) {
       
   933         /* the data type resulting from this operation is unchanged! */
       
   934       }
       
   935       else if (search_expression_type->is_num_type(this->default_variable_name.current_type) &&
       
   936           search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) {
       
   937         NUM_operator_result_type();
       
   938       }
       
   939       else {ERROR;}
       
   940       return NULL;
       
   941     }
       
   942 
       
   943     void *visit(MOD_operator_c *symbol)	{
       
   944       if (search_expression_type->is_num_type(this->default_variable_name.current_type) &&
       
   945           search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) {
       
   946         NUM_operator_result_type();
       
   947       }
       
   948       else {ERROR;}
       
   949       return NULL;
       
   950     }
       
   951 
       
   952     void *visit(GT_operator_c *symbol)	{
       
   953       if (!search_base_type.type_is_enumerated(this->default_variable_name.current_type) &&
       
   954           search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) {
       
   955         CMP_operator_result_type();
       
   956       }
       
   957       else {ERROR;}
       
   958       return NULL;
       
   959     }
       
   960 
       
   961     void *visit(GE_operator_c *symbol)	{
       
   962       if (!search_base_type.type_is_enumerated(this->default_variable_name.current_type) &&
       
   963           search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) {
       
   964         CMP_operator_result_type();
       
   965       }
       
   966       else {ERROR;}
       
   967       return NULL;
       
   968     }
       
   969 
       
   970     void *visit(EQ_operator_c *symbol)	{
       
   971       if (search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) {
       
   972         CMP_operator_result_type();
       
   973       }
       
   974       else {ERROR;}
       
   975       return NULL;
       
   976     }
       
   977 
       
   978     void *visit(LT_operator_c *symbol)	{
       
   979       if (!search_base_type.type_is_enumerated(this->default_variable_name.current_type) &&
       
   980           search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) {
       
   981         CMP_operator_result_type();
       
   982       }
       
   983       else {ERROR;}
       
   984       return NULL;
       
   985     }
       
   986 
       
   987     void *visit(LE_operator_c *symbol)	{
       
   988       if (!search_base_type.type_is_enumerated(this->default_variable_name.current_type) &&
       
   989           search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) {
       
   990         CMP_operator_result_type();
       
   991       }
       
   992       else {ERROR;}
       
   993       return NULL;
       
   994     }
       
   995 
       
   996     void *visit(NE_operator_c *symbol)	{
       
   997       if (search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) {
       
   998         CMP_operator_result_type();
       
   999       }
       
  1000       else {ERROR;}
   622       return NULL;
  1001       return NULL;
   623     }
  1002     }
   624 
  1003 
   625     /***************************************/
  1004     /***************************************/
   626     /* B.3 - Language ST (Structured Text) */
  1005     /* B.3 - Language ST (Structured Text) */
   627     /***************************************/
  1006     /***************************************/
   628     /***********************/
  1007     /***********************/
   629     /* B 3.1 - Expressions */
  1008     /* B 3.1 - Expressions */
   630     /***********************/
  1009     /***********************/
       
  1010 
       
  1011     void *visit(statement_list_c *symbol) {
       
  1012 	  function_call_iterator_c fc_iterator(symbol);
       
  1013 	  symbol_c* function_call;
       
  1014 	  while ((function_call = fc_iterator.next()) != NULL) {
       
  1015 		function_call->accept(*this);
       
  1016 	  }
       
  1017 	  return NULL;
       
  1018 	}
   631 
  1019 
   632     void *visit(function_invocation_c *symbol) {
  1020     void *visit(function_invocation_c *symbol) {
   633       symbol_c* function_type_prefix = NULL;
  1021       symbol_c* function_type_prefix = NULL;
   634       symbol_c* function_name = NULL;
  1022       symbol_c* function_name = NULL;
   635       symbol_c* function_type_suffix = NULL;
  1023       symbol_c* function_type_suffix = NULL;