stage4/generate_c/generate_c_st.cc
changeset 258 d7d92b2f87e9
parent 257 90782e241346
parent 240 f78fa87bb4cb
child 279 c0453b7f99df
child 281 686fa44e3832
equal deleted inserted replaced
257:90782e241346 258:d7d92b2f87e9
    38 /***********************************************************************/
    38 /***********************************************************************/
    39 
    39 
    40 
    40 
    41 class generate_c_st_c: public generate_c_typedecl_c {
    41 class generate_c_st_c: public generate_c_typedecl_c {
    42 
    42 
       
    43   public:
       
    44     typedef enum {
       
    45       expression_vg,
       
    46       assignment_vg,
       
    47       complextype_base_vg,
       
    48       complextype_suffix_vg,
       
    49       fparam_output_vg
       
    50     } variablegeneration_t;
       
    51 
    43   private:
    52   private:
    44     /* When calling a function block, we must first find it's type,
    53     /* When calling a function block, we must first find it's type,
    45      * by searching through the declarations of the variables currently
    54      * by searching through the declarations of the variables currently
    46      * in scope.
    55      * in scope.
    47      * This class does just that...
    56      * This class does just that...
    69     search_varfb_instance_type_c *search_varfb_instance_type;
    78     search_varfb_instance_type_c *search_varfb_instance_type;
    70 
    79 
    71     search_base_type_c search_base_type;
    80     search_base_type_c search_base_type;
    72 
    81 
    73     symbol_c* current_array_type;
    82     symbol_c* current_array_type;
    74 
    83     symbol_c* current_param_type;
    75     bool current_param_is_pointer;
    84 
       
    85     int fcall_number;
       
    86     symbol_c *fbname;
       
    87 
       
    88     variablegeneration_t wanted_variablegeneration;
    76 
    89 
    77   public:
    90   public:
    78     generate_c_st_c(stage4out_c *s4o_ptr, symbol_c *scope, const char *variable_prefix = NULL)
    91     generate_c_st_c(stage4out_c *s4o_ptr, symbol_c *name, symbol_c *scope, const char *variable_prefix = NULL)
    79     : generate_c_typedecl_c(s4o_ptr) {
    92     : generate_c_typedecl_c(s4o_ptr) {
    80       search_fb_instance_decl = new search_fb_instance_decl_c(scope);
    93       search_fb_instance_decl = new search_fb_instance_decl_c(scope);
    81       search_expression_type = new search_expression_type_c(scope);
    94       search_expression_type = new search_expression_type_c(scope);
    82       search_varfb_instance_type = new search_varfb_instance_type_c(scope);
    95       search_varfb_instance_type = new search_varfb_instance_type_c(scope);
    83       this->set_variable_prefix(variable_prefix);
    96       this->set_variable_prefix(variable_prefix);
    84       current_array_type = NULL;
    97       current_array_type = NULL;
    85       current_param_is_pointer = false;
    98       current_param_type = NULL;
       
    99       fcall_number = 0;
       
   100       fbname = name;
       
   101       wanted_variablegeneration = expression_vg;
    86     }
   102     }
    87 
   103 
    88     virtual ~generate_c_st_c(void) {
   104     virtual ~generate_c_st_c(void) {
    89       delete search_fb_instance_decl;
   105       delete search_fb_instance_decl;
    90       delete search_expression_type;
   106       delete search_expression_type;
    97       stl->accept(*this);
   113       stl->accept(*this);
    98     }
   114     }
    99 
   115 
   100   private:
   116   private:
   101 
   117 
       
   118 void *print_getter(symbol_c *symbol) {
       
   119   unsigned int vartype = search_varfb_instance_type->get_vartype(symbol);
       
   120   if (wanted_variablegeneration == fparam_output_vg) {
       
   121   	if (vartype == search_var_instance_decl_c::external_vt)
       
   122       s4o.print(GET_EXTERNAL_BY_REF);
       
   123     else if (vartype == search_var_instance_decl_c::located_vt)
       
   124       s4o.print(GET_LOCATED_BY_REF);
       
   125     else
       
   126       s4o.print(GET_VAR_BY_REF);
       
   127   }
       
   128   else {
       
   129 	if (vartype == search_var_instance_decl_c::external_vt)
       
   130 	  s4o.print(GET_EXTERNAL);
       
   131 	else if (vartype == search_var_instance_decl_c::located_vt)
       
   132 	  s4o.print(GET_LOCATED);
       
   133 	else
       
   134 	  s4o.print(GET_VAR);
       
   135   }
       
   136   s4o.print("(");
       
   137 
       
   138   variablegeneration_t old_wanted_variablegeneration = wanted_variablegeneration;
       
   139   wanted_variablegeneration = complextype_base_vg;
       
   140   symbol->accept(*this);
       
   141   if (search_varfb_instance_type->type_is_complex())
       
   142     s4o.print(",");
       
   143   wanted_variablegeneration = complextype_suffix_vg;
       
   144   symbol->accept(*this);
       
   145   s4o.print(")");
       
   146   wanted_variablegeneration = old_wanted_variablegeneration;
       
   147   return NULL;
       
   148 }
       
   149 
       
   150 void *print_setter(symbol_c* symbol,
       
   151 		symbol_c* type,
       
   152 		symbol_c* value,
       
   153 		symbol_c* fb_symbol = NULL,
       
   154 		symbol_c* fb_value = NULL) {
       
   155   unsigned int vartype = search_varfb_instance_type->get_vartype(symbol);
       
   156   if (vartype == search_var_instance_decl_c::external_vt) {
       
   157     symbolic_variable_c *variable = dynamic_cast<symbolic_variable_c *>(symbol);
       
   158     /* TODO Find a solution for forcing global complex variables */
       
   159     if (variable != NULL) {
       
   160       s4o.print(SET_EXTERNAL);
       
   161       s4o.print("(");
       
   162       variable->var_name->accept(*this);
       
   163       s4o.print(",");
       
   164     }
       
   165     else {
       
   166       s4o.print(SET_COMPLEX_EXTERNAL);
       
   167       s4o.print("(");
       
   168     }
       
   169   }
       
   170   else {
       
   171     if (vartype == search_var_instance_decl_c::located_vt)
       
   172       s4o.print(SET_LOCATED);
       
   173     else
       
   174       s4o.print(SET_VAR);
       
   175     s4o.print("(");
       
   176   }
       
   177 
       
   178   if (fb_symbol != NULL) {
       
   179     print_variable_prefix();
       
   180     fb_symbol->accept(*this);
       
   181     s4o.print(".");
       
   182   }
       
   183   else
       
   184     wanted_variablegeneration = complextype_base_vg;
       
   185   symbol->accept(*this);
       
   186   s4o.print(",");
       
   187   wanted_variablegeneration = expression_vg;
       
   188   print_check_function(type, value, fb_value);
       
   189   if (search_varfb_instance_type->type_is_complex()) {
       
   190     s4o.print(",");
       
   191     wanted_variablegeneration = complextype_suffix_vg;
       
   192     symbol->accept(*this);
       
   193   }
       
   194   s4o.print(")");
       
   195   wanted_variablegeneration = expression_vg;
       
   196   return NULL;
       
   197 }
   102 
   198 
   103 /*********************/
   199 /*********************/
   104 /* B 1.4 - Variables */
   200 /* B 1.4 - Variables */
   105 /*********************/
   201 /*********************/
   106 void *visit(symbolic_variable_c *symbol) {
   202 void *visit(symbolic_variable_c *symbol) {
   107   unsigned int vartype = search_varfb_instance_type->get_vartype(symbol);
   203   unsigned int vartype;
   108   if (!current_param_is_pointer && (vartype == search_var_instance_decl_c::external_vt || vartype == search_var_instance_decl_c::located_vt)) {
   204   if (wanted_variablegeneration == complextype_base_vg)
   109     s4o.print("*(");
   205 	generate_c_base_c::visit(symbol);
   110     generate_c_base_c::visit(symbol);
   206   else if (wanted_variablegeneration == complextype_suffix_vg)
   111     s4o.print(")");
   207 	return NULL;
   112   }
   208   else if (this->is_variable_prefix_null()) {
   113   else if (current_param_is_pointer && vartype != search_var_instance_decl_c::external_vt && vartype != search_var_instance_decl_c::located_vt) {
   209 	vartype = search_varfb_instance_type->get_vartype(symbol);
   114     s4o.print("&(");
   210 	if (wanted_variablegeneration == fparam_output_vg) {
   115     generate_c_base_c::visit(symbol);
   211 	  s4o.print("&(");
   116     s4o.print(")");
   212       generate_c_base_c::visit(symbol);
   117   }
   213       s4o.print(")");
   118   else {
   214     }
   119     generate_c_base_c::visit(symbol);
   215     else {
   120   }
   216       generate_c_base_c::visit(symbol);
       
   217     }
       
   218   }
       
   219   else
       
   220 	print_getter(symbol);
   121   return NULL;
   221   return NULL;
   122 }
   222 }
   123 
   223 
   124 /********************************************/
   224 /********************************************/
   125 /* B.1.4.1   Directly Represented Variables */
   225 /* B.1.4.1   Directly Represented Variables */
   127 // direct_variable: direct_variable_token   {$$ = new direct_variable_c($1);};
   227 // direct_variable: direct_variable_token   {$$ = new direct_variable_c($1);};
   128 void *visit(direct_variable_c *symbol) {
   228 void *visit(direct_variable_c *symbol) {
   129   TRACE("direct_variable_c");
   229   TRACE("direct_variable_c");
   130   /* Do not use print_token() as it will change everything into uppercase */
   230   /* Do not use print_token() as it will change everything into uppercase */
   131   if (strlen(symbol->value) == 0) ERROR;
   231   if (strlen(symbol->value) == 0) ERROR;
   132   if (!current_param_is_pointer) {
   232   if (this->is_variable_prefix_null()) {
   133     s4o.print("*(");
   233     if (wanted_variablegeneration != fparam_output_vg)
       
   234 	  s4o.print("*(");
       
   235   }
       
   236   else {
       
   237     switch (wanted_variablegeneration) {
       
   238       case expression_vg:
       
   239   	    s4o.print(GET_LOCATED);
       
   240   	    s4o.print("(");
       
   241   	    break;
       
   242       case fparam_output_vg:
       
   243         s4o.print(GET_LOCATED_BY_REF);
       
   244         s4o.print("(");
       
   245         break;
       
   246       default:
       
   247         break;
       
   248     }
   134   }
   249   }
   135   this->print_variable_prefix();
   250   this->print_variable_prefix();
   136   s4o.printlocation(symbol->value + 1);
   251   s4o.printlocation(symbol->value + 1);
   137   if (!current_param_is_pointer) {
   252   if ((this->is_variable_prefix_null() && wanted_variablegeneration != fparam_output_vg) ||
       
   253 	  wanted_variablegeneration != assignment_vg)
   138     s4o.print(")");
   254     s4o.print(")");
   139   }
       
   140   return NULL;
   255   return NULL;
   141 }
   256 }
   142 
   257 
   143 /*************************************/
   258 /*************************************/
   144 /* B.1.4.2   Multi-element Variables */
   259 /* B.1.4.2   Multi-element Variables */
   145 /*************************************/
   260 /*************************************/
   146 
   261 
       
   262 // SYM_REF2(structured_variable_c, record_variable, field_selector)
       
   263 void *visit(structured_variable_c *symbol) {
       
   264   TRACE("structured_variable_c");
       
   265   switch (wanted_variablegeneration) {
       
   266     case complextype_base_vg:
       
   267       symbol->record_variable->accept(*this);
       
   268       break;
       
   269     case complextype_suffix_vg:
       
   270       symbol->record_variable->accept(*this);
       
   271       s4o.print(".");
       
   272       symbol->field_selector->accept(*this);
       
   273       break;
       
   274     default:
       
   275       if (this->is_variable_prefix_null()) {
       
   276     	symbol->record_variable->accept(*this);
       
   277     	s4o.print(".");
       
   278     	symbol->field_selector->accept(*this);
       
   279       }
       
   280       else
       
   281     	print_getter(symbol);
       
   282       break;
       
   283   }
       
   284   return NULL;
       
   285 }
       
   286 
   147 /*  subscripted_variable '[' subscript_list ']' */
   287 /*  subscripted_variable '[' subscript_list ']' */
   148 //SYM_REF2(array_variable_c, subscripted_variable, subscript_list)
   288 //SYM_REF2(array_variable_c, subscripted_variable, subscript_list)
   149 void *visit(array_variable_c *symbol) {
   289 void *visit(array_variable_c *symbol) {
   150   current_array_type = search_varfb_instance_type->get_type(symbol->subscripted_variable, false);
   290   switch (wanted_variablegeneration) {
   151   symbol->subscripted_variable->accept(*this);
   291     case complextype_base_vg:
   152   if (current_array_type != NULL) {
   292       symbol->subscripted_variable->accept(*this);
   153     symbol->subscript_list->accept(*this);
   293       break;
   154     current_array_type = NULL;
   294     case complextype_suffix_vg:
       
   295       symbol->subscripted_variable->accept(*this);
       
   296 
       
   297       current_array_type = search_varfb_instance_type->get_rawtype(symbol->subscripted_variable);
       
   298       if (current_array_type == NULL) ERROR;
       
   299 
       
   300       s4o.print(".table");
       
   301       symbol->subscript_list->accept(*this);
       
   302 
       
   303       current_array_type = NULL;
       
   304       break;
       
   305     default:
       
   306       if (this->is_variable_prefix_null()) {
       
   307     	symbol->subscripted_variable->accept(*this);
       
   308 
       
   309     	current_array_type = search_varfb_instance_type->get_rawtype(symbol->subscripted_variable);
       
   310     	if (current_array_type == NULL) ERROR;
       
   311 
       
   312     	s4o.print(".table");
       
   313         symbol->subscript_list->accept(*this);
       
   314 
       
   315         current_array_type = NULL;
       
   316       }
       
   317       else
       
   318     	print_getter(symbol);
       
   319       break;
   155   }
   320   }
   156   return NULL;
   321   return NULL;
   157 }
   322 }
   158 
   323 
   159 /* subscript_list ',' subscript */
   324 /* subscript_list ',' subscript */
   168     s4o.print(")]");
   333     s4o.print(")]");
   169   }
   334   }
   170   return NULL;
   335   return NULL;
   171 }
   336 }
   172 
   337 
       
   338 /******************************************/
       
   339 /* B 1.4.3 - Declaration & Initialisation */
       
   340 /******************************************/
       
   341 
       
   342 /* helper symbol for structure_initialization */
       
   343 /* structure_element_initialization_list ',' structure_element_initialization */
       
   344 void *visit(structure_element_initialization_list_c *symbol) {
       
   345   generate_c_structure_initialization_c *structure_initialization = new generate_c_structure_initialization_c(&s4o);
       
   346   structure_initialization->init_structure_default(this->current_param_type);
       
   347   structure_initialization->init_structure_values(symbol);
       
   348   delete structure_initialization;
       
   349   return NULL;
       
   350 }
       
   351 
       
   352 /* helper symbol for array_initialization */
       
   353 /* array_initial_elements_list ',' array_initial_elements */
       
   354 void *visit(array_initial_elements_list_c *symbol) {
       
   355   generate_c_array_initialization_c *array_initialization = new generate_c_array_initialization_c(&s4o);
       
   356   array_initialization->init_array_size(this->current_param_type);
       
   357   array_initialization->init_array_values(symbol);
       
   358   delete array_initialization;
       
   359   return NULL;
       
   360 }
   173 
   361 
   174 /***************************************/
   362 /***************************************/
   175 /* B.3 - Language ST (Structured Text) */
   363 /* B.3 - Language ST (Structured Text) */
   176 /***************************************/
   364 /***************************************/
   177 /***********************/
   365 /***********************/
   402 
   590 
   403 void *visit(function_invocation_c *symbol) {
   591 void *visit(function_invocation_c *symbol) {
   404   symbol_c* function_type_prefix = NULL;
   592   symbol_c* function_type_prefix = NULL;
   405   symbol_c* function_name = NULL;
   593   symbol_c* function_name = NULL;
   406   symbol_c* function_type_suffix = NULL;
   594   symbol_c* function_type_suffix = NULL;
   407   std::list<FUNCTION_PARAM> param_list;
   595   DECLARE_PARAM_LIST()
   408   FUNCTION_PARAM *param;
       
   409 
   596 
   410   symbol_c *parameter_assignment_list = NULL;
   597   symbol_c *parameter_assignment_list = NULL;
   411   if (NULL != symbol->   formal_param_list) parameter_assignment_list = symbol->   formal_param_list;
   598   if (NULL != symbol->   formal_param_list) parameter_assignment_list = symbol->   formal_param_list;
   412   if (NULL != symbol->nonformal_param_list) parameter_assignment_list = symbol->nonformal_param_list;
   599   if (NULL != symbol->nonformal_param_list) parameter_assignment_list = symbol->nonformal_param_list;
   413   if (NULL == parameter_assignment_list) ERROR;
   600   if (NULL == parameter_assignment_list) ERROR;
   414 
   601 
       
   602   function_call_param_iterator_c function_call_param_iterator(symbol);
       
   603 
   415   function_declaration_c *f_decl = function_symtable.find_value(symbol->function_name);
   604   function_declaration_c *f_decl = function_symtable.find_value(symbol->function_name);
   416   if (f_decl == function_symtable.end_value()) {
   605   if (f_decl == function_symtable.end_value()) {
   417     /* The function called is not in the symtable, so we test if it is a
   606     /* The function called is not in the symtable, so we test if it is a
   418      * standard function defined in standard */
   607      * standard function defined in standard */
   419 
   608 
   420     function_type_t current_function_type = get_function_type((identifier_c *)symbol->function_name);
   609     function_type_t current_function_type = get_function_type((identifier_c *)symbol->function_name);
   421     if (current_function_type == function_none) ERROR;
   610     if (current_function_type == function_none) ERROR;
   422 
   611 
   423     symbol_c *function_return_type = search_expression_type->get_type(symbol);
   612     symbol_c *function_return_type = search_expression_type->get_type(symbol);
   424 
   613 
   425     function_call_param_iterator_c function_call_param_iterator(symbol);
       
   426 
       
   427     int nb_param = ((list_c *)parameter_assignment_list)->n;
   614     int nb_param = ((list_c *)parameter_assignment_list)->n;
   428 
   615 
   429     identifier_c en_param_name("EN");
   616     symbol_c *en_param_name = (symbol_c *)(new identifier_c("EN"));
   430     /* Get the value from EN param */
   617     /* Get the value from EN param */
   431     symbol_c *EN_param_value = function_call_param_iterator.search_f(&en_param_name);
   618     symbol_c *EN_param_value = function_call_param_iterator.search_f(en_param_name);
   432     if (EN_param_value == NULL)
   619     if (EN_param_value == NULL)
   433       EN_param_value = (symbol_c*)(new boolean_literal_c((symbol_c*)(new bool_type_name_c()), new boolean_true_c()));
   620       EN_param_value = (symbol_c*)(new boolean_literal_c((symbol_c*)(new bool_type_name_c()), new boolean_true_c()));
   434     else
   621     else
   435       nb_param --;
   622       nb_param --;
   436     ADD_PARAM_LIST(EN_param_value, (symbol_c*)(new bool_type_name_c()), function_param_iterator_c::direction_in)
   623     ADD_PARAM_LIST(en_param_name, EN_param_value, (symbol_c*)(new bool_type_name_c()), function_param_iterator_c::direction_in)
   437 
   624 
   438     identifier_c eno_param_name("ENO");
   625     symbol_c *eno_param_name = (symbol_c *)(new identifier_c("ENO"));
   439     /* Get the value from ENO param */
   626     /* Get the value from ENO param */
   440     symbol_c *ENO_param_value = function_call_param_iterator.search_f(&eno_param_name);
   627     symbol_c *ENO_param_value = function_call_param_iterator.search_f(eno_param_name);
   441     if (ENO_param_value != NULL)
   628     if (ENO_param_value != NULL)
   442       nb_param --;
   629       nb_param --;
   443     ADD_PARAM_LIST(ENO_param_value, (symbol_c*)(new bool_type_name_c()), function_param_iterator_c::direction_out)
   630     ADD_PARAM_LIST(eno_param_name, ENO_param_value, (symbol_c*)(new bool_type_name_c()), function_param_iterator_c::direction_out)
   444 
   631 
   445     #define search(x) search_f(x)
       
   446     #define next() next_nf()
       
   447 //     #define search_constant_type_c::constant_int_type_name  search_expression_type_c::integer
       
   448     #define constant_int_type_name  integer
       
   449     #include "st_code_gen.c"
   632     #include "st_code_gen.c"
   450     #undef constant_int_type_name
       
   451 //     #undef search_constant_type_c::constant_int_type_name
       
   452     #undef next
       
   453     #undef  search
       
   454 
   633 
   455   }
   634   }
   456   else {
   635   else {
   457     /* loop through each function parameter, find the value we should pass
   636 	function_name = symbol->function_name;
       
   637 
       
   638 	/* loop through each function parameter, find the value we should pass
   458      * to it, and then output the c equivalent...
   639      * to it, and then output the c equivalent...
   459      */
   640      */
   460     function_param_iterator_c fp_iterator(f_decl);
   641     function_param_iterator_c fp_iterator(f_decl);
   461   
       
   462     function_name = symbol->function_name;
       
   463   
       
   464     identifier_c *param_name;
   642     identifier_c *param_name;
   465     function_call_param_iterator_c function_call_param_iterator(symbol);
       
   466     for(int i = 1; (param_name = fp_iterator.next()) != NULL; i++) {
   643     for(int i = 1; (param_name = fp_iterator.next()) != NULL; i++) {
   467       
   644       
       
   645       symbol_c *param_type = fp_iterator.param_type();
       
   646       if (param_type == NULL) ERROR;
       
   647 
   468       function_param_iterator_c::param_direction_t param_direction = fp_iterator.param_direction();
   648       function_param_iterator_c::param_direction_t param_direction = fp_iterator.param_direction();
   469       
   649       
   470       /* Get the value from a foo(<param_name> = <param_value>) style call */
   650       /* Get the value from a foo(<param_name> = <param_value>) style call */
   471       symbol_c *param_value = function_call_param_iterator.search_f(param_name);
   651       symbol_c *param_value = function_call_param_iterator.search_f(param_name);
   472   
   652   
   473       /* Get the value from a foo(<param_value>) style call */
   653       /* Get the value from a foo(<param_value>) style call */
   474       if (param_value == NULL)
   654       if (param_value == NULL) {
   475         param_value = function_call_param_iterator.next_nf();
   655         param_value = function_call_param_iterator.next_nf();
       
   656         if (param_value != NULL && fp_iterator.is_en_eno_param_implicit()) ERROR;
       
   657       }
   476       
   658       
   477       if (param_value == NULL && param_direction == function_param_iterator_c::direction_in) {
   659       if (param_value == NULL && param_direction == function_param_iterator_c::direction_in) {
   478         /* No value given for parameter, so we must use the default... */
   660         /* No value given for parameter, so we must use the default... */
   479         /* First check whether default value specified in function declaration...*/
   661         /* First check whether default value specified in function declaration...*/
   480         param_value = fp_iterator.default_value();
   662         param_value = fp_iterator.default_value();
   481       }
   663       }
   482       
   664       
   483       symbol_c *param_type = fp_iterator.param_type();
   665       ADD_PARAM_LIST(param_name, param_value, param_type, param_direction)
   484       if (param_type == NULL) ERROR;
       
   485       
       
   486       ADD_PARAM_LIST(param_value, param_type, param_direction)
       
   487     } /* for(...) */
   666     } /* for(...) */
   488     // symbol->parameter_assignment->accept(*this);
   667     // symbol->parameter_assignment->accept(*this);
   489   }
   668   }
   490   
   669   
       
   670   if (function_call_param_iterator.next_nf() != NULL) ERROR;
       
   671 
       
   672   bool has_output_params = false;
       
   673 
       
   674   if (!this->is_variable_prefix_null()) {
       
   675     PARAM_LIST_ITERATOR() {
       
   676 	  if ((PARAM_DIRECTION == function_param_iterator_c::direction_out ||
       
   677 		   PARAM_DIRECTION == function_param_iterator_c::direction_inout) &&
       
   678 		  PARAM_VALUE != NULL) {
       
   679 	    if (!has_output_params) {
       
   680 		  has_output_params = true;
       
   681 		}
       
   682 	  }
       
   683     }
       
   684   }
       
   685 
   491   if (function_type_prefix != NULL) {
   686   if (function_type_prefix != NULL) {
   492     s4o.print("(");
   687     s4o.print("(");
   493     function_type_prefix->accept(*this);
   688     function_type_prefix->accept(*this);
   494     s4o.print(")");
   689     s4o.print(")");
   495   }
   690   }
   496   if (function_name != NULL)
   691   if (has_output_params) {
       
   692 	fcall_number++;
       
   693 	s4o.print("__");
       
   694     fbname->accept(*this);
       
   695     s4o.print("_");
   497     function_name->accept(*this);
   696     function_name->accept(*this);
   498   if (function_type_suffix != NULL)
   697     if (function_type_suffix != NULL)
   499     function_type_suffix->accept(*this);
   698       function_type_suffix->accept(*this);
       
   699     s4o.print_integer(fcall_number);
       
   700   }
       
   701   else {
       
   702     function_name->accept(*this);
       
   703     if (function_type_suffix != NULL)
       
   704       function_type_suffix->accept(*this);
       
   705   }
   500   s4o.print("(");
   706   s4o.print("(");
   501   s4o.indent_right();
   707   s4o.indent_right();
   502   
   708   
   503   std::list<FUNCTION_PARAM>::iterator pt;
   709   int nb_param = 0;
   504   for(pt = param_list.begin(); pt != param_list.end(); pt++) {
   710   PARAM_LIST_ITERATOR() {
   505     if (pt != param_list.begin())
   711     symbol_c *param_value = PARAM_VALUE;
   506       s4o.print(",\n"+s4o.indent_spaces);
   712     current_param_type = PARAM_TYPE;
   507     symbol_c *param_value = pt->param_value;
       
   508     symbol_c *param_type = pt->param_type;
       
   509           
   713           
   510     switch (pt->param_direction) {
   714     switch (PARAM_DIRECTION) {
   511       case function_param_iterator_c::direction_in:
   715       case function_param_iterator_c::direction_in:
   512         if (param_value == NULL) {
   716     	if (nb_param > 0)
       
   717     	  s4o.print(",\n"+s4o.indent_spaces);
       
   718     	if (param_value == NULL) {
   513           /* If not, get the default value of this variable's type */
   719           /* If not, get the default value of this variable's type */
   514           param_value = (symbol_c *)param_type->accept(*type_initial_value_c::instance());
   720           param_value = (symbol_c *)current_param_type->accept(*type_initial_value_c::instance());
   515         }
   721         }
   516         if (param_value == NULL) ERROR;
   722         if (param_value == NULL) ERROR;
   517         if (search_base_type.type_is_subrange(param_type)) {
   723         s4o.print("(");
   518           s4o.print("__CHECK_");
   724         if (search_expression_type->is_literal_integer_type(current_param_type))
   519           param_type->accept(*this);
   725           search_expression_type->lint_type_name.accept(*this);
   520           s4o.print("(");
   726         else if (search_expression_type->is_literal_real_type(current_param_type))
   521         }
   727           search_expression_type->lreal_type_name.accept(*this);
   522         param_value->accept(*this);
   728         else
   523         if (search_base_type.type_is_subrange(param_type))
   729           current_param_type->accept(*this);
   524           s4o.print(")");
   730         s4o.print(")");
       
   731         print_check_function(current_param_type, param_value);
       
   732         nb_param++;
   525         break;
   733         break;
   526       case function_param_iterator_c::direction_out:
   734       case function_param_iterator_c::direction_out:
   527       case function_param_iterator_c::direction_inout:
   735       case function_param_iterator_c::direction_inout:
   528         current_param_is_pointer = true;
   736     	if (!has_output_params) {
   529         if (param_value == NULL) {
   737           if (nb_param > 0)
   530           s4o.print("NULL");
   738         	s4o.print(",\n"+s4o.indent_spaces);
   531         } else {
   739     	  if (param_value == NULL)
   532           param_value->accept(*this);
   740             s4o.print("NULL");
   533         }
   741           else {
   534         current_param_is_pointer = false;
   742             wanted_variablegeneration = fparam_output_vg;
       
   743             param_value->accept(*this);
       
   744             wanted_variablegeneration = expression_vg;
       
   745           }
       
   746     	  nb_param++;
       
   747     	}
   535         break;
   748         break;
   536       case function_param_iterator_c::direction_extref:
   749       case function_param_iterator_c::direction_extref:
   537         /* TODO! */
   750         /* TODO! */
   538         ERROR;
   751         ERROR;
   539         break;
   752         break;
   540     } /* switch */
   753     } /* switch */
   541   }  
   754   }
   542   
   755   if (has_output_params) {
       
   756     if (nb_param > 0)
       
   757       s4o.print(",\n"+s4o.indent_spaces);
       
   758     s4o.print(FB_FUNCTION_PARAM);
       
   759   }
   543   s4o.print(")");
   760   s4o.print(")");
   544   s4o.indent_left();
   761   s4o.indent_left();
       
   762 
       
   763   CLEAR_PARAM_LIST()
   545 
   764 
   546   return NULL;
   765   return NULL;
   547 }
   766 }
   548 
   767 
   549 /********************/
   768 /********************/
   555 
   774 
   556 /*********************************/
   775 /*********************************/
   557 /* B 3.2.1 Assignment Statements */
   776 /* B 3.2.1 Assignment Statements */
   558 /*********************************/
   777 /*********************************/
   559 void *visit(assignment_statement_c *symbol) {
   778 void *visit(assignment_statement_c *symbol) {
   560   symbol_c *left_type = search_varfb_instance_type->get_type(symbol->l_exp, false);
   779   symbol_c *left_type = search_varfb_instance_type->get_rawtype(symbol->l_exp);
   561   
   780   
   562   symbol->l_exp->accept(*this);
   781   if (this->is_variable_prefix_null()) {
   563   s4o.print(" = ");
   782     symbol->l_exp->accept(*this);
   564   if (search_base_type.type_is_subrange(left_type)) {
   783     s4o.print(" = ");
   565     s4o.print("__CHECK_");
   784     print_check_function(left_type, symbol->r_exp);
   566     left_type->accept(*this);
   785   }
   567     s4o.print("(");
   786   else {
   568   }
   787 	print_setter(symbol->l_exp, left_type, symbol->r_exp);
   569   symbol->r_exp->accept(*this);
   788   }
   570   if (search_base_type.type_is_subrange(left_type))
       
   571     s4o.print(")");
       
   572   return NULL;
   789   return NULL;
   573 }
   790 }
   574 
   791 
   575 /*****************************************/
   792 /*****************************************/
   576 /* B 3.2.2 Subprogram Control Statements */
   793 /* B 3.2.2 Subprogram Control Statements */
   614     
   831     
   615     /* now output the value assignment */
   832     /* now output the value assignment */
   616     if (param_value != NULL)
   833     if (param_value != NULL)
   617       if ((param_direction == function_param_iterator_c::direction_in) ||
   834       if ((param_direction == function_param_iterator_c::direction_in) ||
   618           (param_direction == function_param_iterator_c::direction_inout)) {
   835           (param_direction == function_param_iterator_c::direction_inout)) {
   619         print_variable_prefix();
   836         if (this->is_variable_prefix_null()) {
   620         symbol->fb_name->accept(*this);
   837           symbol->fb_name->accept(*this);
   621         s4o.print(".");
   838           s4o.print(".");
   622         param_name->accept(*this);
   839           param_name->accept(*this);
   623         s4o.print(" = ");
   840           s4o.print(" = ");
   624         if (search_base_type.type_is_subrange(param_type)) {
   841           print_check_function(param_type, param_value);
   625           s4o.print("__CHECK_");
       
   626           param_type->accept(*this);
       
   627           s4o.print("(");
       
   628         }
   842         }
   629         param_value->accept(*this);
   843         else {
   630         if (search_base_type.type_is_subrange(param_type))
   844           print_setter(param_name, param_type, param_value, symbol->fb_name);
   631           s4o.print(")");
   845         }
   632         s4o.print(";\n" + s4o.indent_spaces);
   846         s4o.print(";\n" + s4o.indent_spaces);
   633       }
   847       }
   634   } /* for(...) */
   848   } /* for(...) */
   635 
   849 
   636   /* now call the function... */
   850   /* now call the function... */
   658 
   872 
   659     /* now output the value assignment */
   873     /* now output the value assignment */
   660     if (param_value != NULL)
   874     if (param_value != NULL)
   661       if ((param_direction == function_param_iterator_c::direction_out) ||
   875       if ((param_direction == function_param_iterator_c::direction_out) ||
   662           (param_direction == function_param_iterator_c::direction_inout)) {
   876           (param_direction == function_param_iterator_c::direction_inout)) {
   663         symbol_c *param_type = search_varfb_instance_type->get_type(param_value, false);
   877         symbol_c *param_type = search_varfb_instance_type->get_rawtype(param_value);
   664         
   878         s4o.print(";\n" + s4o.indent_spaces);
   665         s4o.print(";\n"+ s4o.indent_spaces);
   879         if (this->is_variable_prefix_null()) {
   666         param_value->accept(*this);
   880           param_value->accept(*this);
   667         s4o.print(" = ");
   881           s4o.print(" = ");
   668         if (search_base_type.type_is_subrange(param_type)) {
   882           print_check_function(param_type, param_name, symbol->fb_name);
   669           s4o.print("__CHECK_");
       
   670           param_type->accept(*this);
       
   671           s4o.print("(");
       
   672         }
   883         }
   673         print_variable_prefix();
   884         else {
   674         symbol->fb_name->accept(*this);
   885           print_setter(param_value, param_type, param_name, NULL, symbol->fb_name);
   675         s4o.print(".");
   886         }
   676         param_name->accept(*this);
       
   677         if (search_base_type.type_is_subrange(param_type))
       
   678           s4o.print(")");
       
   679       }
   887       }
   680   } /* for(...) */
   888   } /* for(...) */
   681 
   889 
   682   return NULL;
   890   return NULL;
   683 }
   891 }