stage4/generate_c/generate_c_st.cc
changeset 202 da1a8186f86f
parent 169 bea932bc60b0
child 208 c72748a12ae3
child 257 90782e241346
equal deleted inserted replaced
201:e657008f43d0 202:da1a8186f86f
    90       delete search_expression_type;
    90       delete search_expression_type;
    91       delete search_varfb_instance_type;
    91       delete search_varfb_instance_type;
    92     }
    92     }
    93 
    93 
    94 
    94 
    95   private:
       
    96     /* Some function calls in the body of functions or function blocks
       
    97      * may leave some parameters to their default values, and
       
    98      * ignore some output parameters of the function being called.
       
    99      * Our conversion of ST functions to C++ does not contemplate that,
       
   100      * i.e. each called function must get all it's input and output
       
   101      * parameters set correctly.
       
   102      * For input parameters we merely need to call the function with
       
   103      * the apropriate default value, but for output parameters
       
   104      * we must create temporary variables to hold the output value.
       
   105      *
       
   106      * We declare all the temporary output variables at the begining of
       
   107      * the body of each function or function block, and use them as
       
   108      * in function calls later on as they become necessary...
       
   109      * Note that we cannot create these variables just before a function
       
   110      * call, as the function call itself may be integrated within an
       
   111      * expression, or another function call!
       
   112      *
       
   113      * The variables are declared in the exact same order in which they
       
   114      * will be used later on during the function calls, which allows us
       
   115      * to simply re-create the name that was used for the temporary variable
       
   116      * instead of keeping it in some list.
       
   117      * The names are recreated by the temp_var_name_factory, after reset()
       
   118      * has been called!
       
   119      *
       
   120      * This function will genertae code similar to...
       
   121      *
       
   122      *     INT __TMP_0 = 23;
       
   123      *     REAL __TMP_1 = 45.5;
       
   124      *     ...
       
   125      */
       
   126     temp_var_name_c temp_var_name_factory;
       
   127 
       
   128   public:
    95   public:
   129     void generate(statement_list_c *stl) {
    96     void generate(statement_list_c *stl) {
   130       generate_c_tempvardecl_c generate_c_tempvardecl(&s4o);
       
   131       generate_c_tempvardecl.generate(stl, &temp_var_name_factory);
       
   132       stl->accept(*this);
    97       stl->accept(*this);
   133     }
    98     }
   134 
    99 
   135   private:
   100   private:
   136 
   101 
   137 void *visit(eno_param_c *symbol) {
       
   138   if (this->is_variable_prefix_null()) {
       
   139     s4o.print("*");
       
   140   }
       
   141   else {
       
   142     this->print_variable_prefix();
       
   143   }
       
   144   s4o.print("ENO");
       
   145   return NULL;
       
   146 }
       
   147 
   102 
   148 /*********************/
   103 /*********************/
   149 /* B 1.4 - Variables */
   104 /* B 1.4 - Variables */
   150 /*********************/
   105 /*********************/
   151 void *visit(symbolic_variable_c *symbol) {
   106 void *visit(symbolic_variable_c *symbol) {
   444   ERROR;
   399   ERROR;
   445   return NULL;
   400   return NULL;
   446 }
   401 }
   447 
   402 
   448 void *visit(function_invocation_c *symbol) {
   403 void *visit(function_invocation_c *symbol) {
   449   function_declaration_c *f_decl = function_symtable.find_value(symbol->function_name);
       
   450   
       
   451   symbol_c* function_type_prefix = NULL;
   404   symbol_c* function_type_prefix = NULL;
   452   symbol_c* function_name = NULL;
   405   symbol_c* function_name = NULL;
   453   symbol_c* function_type_suffix = NULL;
   406   symbol_c* function_type_suffix = NULL;
   454   std::list<FUNCTION_PARAM> param_list;
   407   std::list<FUNCTION_PARAM> param_list;
   455   FUNCTION_PARAM *param;
   408   FUNCTION_PARAM *param;
   456   
   409 
       
   410   symbol_c *parameter_assignment_list = NULL;
       
   411   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;
       
   413   if (NULL == parameter_assignment_list) ERROR;
       
   414 
       
   415   function_declaration_c *f_decl = function_symtable.find_value(symbol->function_name);
   457   if (f_decl == function_symtable.end_value()) {
   416   if (f_decl == function_symtable.end_value()) {
   458     /* The function called is not in the symtable, so we test if it is a
   417     /* The function called is not in the symtable, so we test if it is a
   459      * standard function defined in standard */
   418      * standard function defined in standard */
   460     
   419 
   461     function_type_t current_function_type = get_function_type((identifier_c *)symbol->function_name);
   420     function_type_t current_function_type = get_function_type((identifier_c *)symbol->function_name);
   462     if (current_function_type == function_none) ERROR;
   421     if (current_function_type == function_none) ERROR;
   463     
   422 
   464     symbol_c *function_return_type = search_expression_type->get_type(symbol);
   423     symbol_c *function_return_type = search_expression_type->get_type(symbol);
   465     
   424 
   466     function_call_param_iterator_c function_call_param_iterator(symbol);
   425     function_call_param_iterator_c function_call_param_iterator(symbol);
   467 
   426 
   468     int nb_param = ((list_c *)symbol->parameter_assignment_list)->n;
   427     int nb_param = ((list_c *)parameter_assignment_list)->n;
   469     
   428 
   470     identifier_c en_param_name("EN");
   429     identifier_c en_param_name("EN");
   471     /* Get the value from EN param */
   430     /* Get the value from EN param */
   472     symbol_c *EN_param_value = function_call_param_iterator.search(&en_param_name);
   431     symbol_c *EN_param_value = function_call_param_iterator.search_f(&en_param_name);
   473     if (EN_param_value == NULL)
   432     if (EN_param_value == NULL)
   474       EN_param_value = (symbol_c*)(new boolean_literal_c((symbol_c*)(new bool_type_name_c()), new boolean_true_c()));
   433       EN_param_value = (symbol_c*)(new boolean_literal_c((symbol_c*)(new bool_type_name_c()), new boolean_true_c()));
   475     else
   434     else
   476       nb_param --;
   435       nb_param --;
   477     ADD_PARAM_LIST(EN_param_value, (symbol_c*)(new bool_type_name_c()), function_param_iterator_c::direction_in)
   436     ADD_PARAM_LIST(EN_param_value, (symbol_c*)(new bool_type_name_c()), function_param_iterator_c::direction_in)
   478     
   437 
   479     identifier_c eno_param_name("ENO");
   438     identifier_c eno_param_name("ENO");
   480     /* Get the value from ENO param */
   439     /* Get the value from ENO param */
   481     symbol_c *ENO_param_value = function_call_param_iterator.search(&eno_param_name);
   440     symbol_c *ENO_param_value = function_call_param_iterator.search_f(&eno_param_name);
   482     if (ENO_param_value != NULL)
   441     if (ENO_param_value != NULL)
   483       nb_param --;
   442       nb_param --;
   484     ADD_PARAM_LIST(ENO_param_value, (symbol_c*)(new bool_type_name_c()), function_param_iterator_c::direction_out)
   443     ADD_PARAM_LIST(ENO_param_value, (symbol_c*)(new bool_type_name_c()), function_param_iterator_c::direction_out)
   485     
   444 
       
   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
   486     #include "st_code_gen.c"
   449     #include "st_code_gen.c"
   487     
   450     #undef constant_int_type_name
       
   451 //     #undef search_constant_type_c::constant_int_type_name
       
   452     #undef next
       
   453     #undef  search
       
   454 
   488   }
   455   }
   489   else {
   456   else {
   490     /* loop through each function parameter, find the value we should pass
   457     /* loop through each function parameter, find the value we should pass
   491      * to it, and then output the c equivalent...
   458      * to it, and then output the c equivalent...
   492      */
   459      */
   499     for(int i = 1; (param_name = fp_iterator.next()) != NULL; i++) {
   466     for(int i = 1; (param_name = fp_iterator.next()) != NULL; i++) {
   500       
   467       
   501       function_param_iterator_c::param_direction_t param_direction = fp_iterator.param_direction();
   468       function_param_iterator_c::param_direction_t param_direction = fp_iterator.param_direction();
   502       
   469       
   503       /* Get the value from a foo(<param_name> = <param_value>) style call */
   470       /* Get the value from a foo(<param_name> = <param_value>) style call */
   504       symbol_c *param_value = function_call_param_iterator.search(param_name);
   471       symbol_c *param_value = function_call_param_iterator.search_f(param_name);
   505   
   472   
   506       /* Get the value from a foo(<param_value>) style call */
   473       /* Get the value from a foo(<param_value>) style call */
   507       if (param_value == NULL)
   474       if (param_value == NULL)
   508         param_value = function_call_param_iterator.next();
   475         param_value = function_call_param_iterator.next_nf();
   509       
   476       
   510       if (param_value == NULL && param_direction == function_param_iterator_c::direction_in) {
   477       if (param_value == NULL && param_direction == function_param_iterator_c::direction_in) {
   511         /* No value given for parameter, so we must use the default... */
   478         /* No value given for parameter, so we must use the default... */
   512         /* First check whether default value specified in function declaration...*/
   479         /* First check whether default value specified in function declaration...*/
   513         param_value = fp_iterator.default_value();
   480         param_value = fp_iterator.default_value();
   634     function_param_iterator_c::param_direction_t param_direction = fp_iterator.param_direction();
   601     function_param_iterator_c::param_direction_t param_direction = fp_iterator.param_direction();
   635     
   602     
   636     /*fprintf(stderr, "param : %s\n", param_name->value);*/
   603     /*fprintf(stderr, "param : %s\n", param_name->value);*/
   637     
   604     
   638     /* Get the value from a foo(<param_name> = <param_value>) style call */
   605     /* Get the value from a foo(<param_name> = <param_value>) style call */
   639     symbol_c *param_value = function_call_param_iterator.search(param_name);
   606     symbol_c *param_value = function_call_param_iterator.search_f(param_name);
   640 
   607 
   641     /* Get the value from a foo(<param_value>) style call */
   608     /* Get the value from a foo(<param_value>) style call */
   642     if (param_value == NULL)
   609     if (param_value == NULL)
   643       param_value = function_call_param_iterator.next();
   610       param_value = function_call_param_iterator.next_nf();
   644 
   611 
   645     symbol_c *param_type = fp_iterator.param_type();
   612     symbol_c *param_type = fp_iterator.param_type();
   646     if (param_type == NULL) ERROR;
   613     if (param_type == NULL) ERROR;
   647     
   614     
   648     /* now output the value assignment */
   615     /* now output the value assignment */
   681   function_call_param_iterator.reset();
   648   function_call_param_iterator.reset();
   682   for(int i = 1; (param_name = fp_iterator.next()) != NULL; i++) {
   649   for(int i = 1; (param_name = fp_iterator.next()) != NULL; i++) {
   683     function_param_iterator_c::param_direction_t param_direction = fp_iterator.param_direction();
   650     function_param_iterator_c::param_direction_t param_direction = fp_iterator.param_direction();
   684 
   651 
   685     /* Get the value from a foo(<param_name> = <param_value>) style call */
   652     /* Get the value from a foo(<param_name> = <param_value>) style call */
   686     symbol_c *param_value = function_call_param_iterator.search(param_name);
   653     symbol_c *param_value = function_call_param_iterator.search_f(param_name);
   687 
   654 
   688     /* Get the value from a foo(<param_value>) style call */
   655     /* Get the value from a foo(<param_value>) style call */
   689     if (param_value == NULL)
   656     if (param_value == NULL)
   690       param_value = function_call_param_iterator.next();
   657       param_value = function_call_param_iterator.next_nf();
   691 
   658 
   692     /* now output the value assignment */
   659     /* now output the value assignment */
   693     if (param_value != NULL)
   660     if (param_value != NULL)
   694       if ((param_direction == function_param_iterator_c::direction_out) ||
   661       if ((param_direction == function_param_iterator_c::direction_out) ||
   695           (param_direction == function_param_iterator_c::direction_inout)) {
   662           (param_direction == function_param_iterator_c::direction_inout)) {