stage4/generate_c/generate_c_il.cc
changeset 202 da1a8186f86f
parent 201 e657008f43d0
child 208 c72748a12ae3
equal deleted inserted replaced
201:e657008f43d0 202:da1a8186f86f
    51  *
    51  *
    52  * The class constructor must be given the search scope
    52  * The class constructor must be given the search scope
    53  * (function, function block or program within which
    53  * (function, function block or program within which
    54  * the possible il_operand variable instance was declared).
    54  * the possible il_operand variable instance was declared).
    55  */
    55  */
    56 
       
    57 #include "../../absyntax_utils/search_il_operand_type.hh"
       
    58 
       
    59 
       
    60 
    56 
    61 /***********************************************************************/
    57 /***********************************************************************/
    62 /***********************************************************************/
    58 /***********************************************************************/
    63 /***********************************************************************/
    59 /***********************************************************************/
    64 /***********************************************************************/
    60 /***********************************************************************/
   150      * or function currently being processed.
   146      * or function currently being processed.
   151      * The following object does just that...
   147      * The following object does just that...
   152      * This object instance will then later be called while the
   148      * This object instance will then later be called while the
   153      * remaining il code is being handled.
   149      * remaining il code is being handled.
   154      */
   150      */
   155     //search_il_operand_type_c *search_il_operand_type;
       
   156     search_expression_type_c *search_expression_type;
   151     search_expression_type_c *search_expression_type;
   157 
   152 
   158     /* The initial value that should be given to the IL default variable
   153     /* The initial value that should be given to the IL default variable
   159      * imediately after a parenthesis is opened.
   154      * imediately after a parenthesis is opened.
   160      * This variable is only used to pass data from the
   155      * This variable is only used to pass data from the
   218      */
   213      */
   219     #define IL_DEFVAR_BACK   VAR_LEADER "IL_DEFVAR_BACK"
   214     #define IL_DEFVAR_BACK   VAR_LEADER "IL_DEFVAR_BACK"
   220     il_default_variable_c default_variable_name;
   215     il_default_variable_c default_variable_name;
   221     il_default_variable_c default_variable_back_name;
   216     il_default_variable_c default_variable_back_name;
   222 
   217 
   223     /* Some function calls in the body of functions or function blocks
       
   224      * may leave some parameters to their default values, and
       
   225      * ignore some output parameters of the function being called.
       
   226      * Our conversion of ST functions to C++ does not contemplate that,
       
   227      * i.e. each called function must get all it's input and output
       
   228      * parameters set correctly.
       
   229      * For input parameters we merely need to call the function with
       
   230      * the apropriate default value, but for output parameters
       
   231      * we must create temporary variables to hold the output value.
       
   232      *
       
   233      * We declare all the temporary output variables at the begining of
       
   234      * the body of each function or function block, and use them as
       
   235      * in function calls later on as they become necessary...
       
   236      * Note that we cannot create these variables just before a function
       
   237      * call, as the function call itself may be integrated within an
       
   238      * expression, or another function call!
       
   239      *
       
   240      * The variables are declared in the exact same order in which they
       
   241      * will be used later on during the function calls, which allows us
       
   242      * to simply re-create the name that was used for the temporary variable
       
   243      * instead of keeping it in some list.
       
   244      * The names are recreated by the temp_var_name_factory, after reset()
       
   245      * has been called!
       
   246      *
       
   247      * This function will genertae code similar to...
       
   248      *
       
   249      *     INT __TMP_0 = 23;
       
   250      *     REAL __TMP_1 = 45.5;
       
   251      *     ...
       
   252      */
       
   253     temp_var_name_c temp_var_name_factory;
       
   254 
       
   255     /* When calling a function block, we must first find it's type,
   218     /* When calling a function block, we must first find it's type,
   256      * by searching through the declarations of the variables currently
   219      * by searching through the declarations of the variables currently
   257      * in scope.
   220      * in scope.
   258      * This class does just that...
   221      * This class does just that...
   259      * A new class is instantiated whenever we begin generating the code
   222      * A new class is instantiated whenever we begin generating the code
   277     generate_c_il_c(stage4out_c *s4o_ptr, symbol_c *scope, const char *variable_prefix = NULL)
   240     generate_c_il_c(stage4out_c *s4o_ptr, symbol_c *scope, const char *variable_prefix = NULL)
   278     : generate_c_typedecl_c(s4o_ptr),
   241     : generate_c_typedecl_c(s4o_ptr),
   279       default_variable_name(IL_DEFVAR, NULL),
   242       default_variable_name(IL_DEFVAR, NULL),
   280       default_variable_back_name(IL_DEFVAR_BACK, NULL)
   243       default_variable_back_name(IL_DEFVAR_BACK, NULL)
   281     {
   244     {
   282       //search_il_operand_type  = new search_il_operand_type_c(scope);
       
   283       search_expression_type = new search_expression_type_c(scope);
   245       search_expression_type = new search_expression_type_c(scope);
   284       search_fb_instance_decl = new search_fb_instance_decl_c(scope);
   246       search_fb_instance_decl = new search_fb_instance_decl_c(scope);
   285       search_varfb_instance_type = new search_varfb_instance_type_c(scope);
   247       search_varfb_instance_type = new search_varfb_instance_type_c(scope);
   286       current_operand = NULL;
   248       current_operand = NULL;
   287       current_operand_type = NULL;
   249       current_operand_type = NULL;
   290       this->set_variable_prefix(variable_prefix);
   252       this->set_variable_prefix(variable_prefix);
   291     }
   253     }
   292 
   254 
   293     virtual ~generate_c_il_c(void) {
   255     virtual ~generate_c_il_c(void) {
   294       delete search_fb_instance_decl;
   256       delete search_fb_instance_decl;
   295       //delete search_il_operand_type;
       
   296       delete search_expression_type;
   257       delete search_expression_type;
   297       delete search_varfb_instance_type;
   258       delete search_varfb_instance_type;
   298     }
   259     }
   299 
   260 
   300     void generate(instruction_list_c *il) {
   261     void generate(instruction_list_c *il) {
   301       generate_c_tempvardecl_c generate_c_tempvardecl(&s4o);
       
   302       generate_c_tempvardecl.generate(il, &temp_var_name_factory);
       
   303       il->accept(*this);
   262       il->accept(*this);
   304     }
   263     }
   305 
   264 
   306     /* Declare the backup to the default variable, that will store the result
   265     /* Declare the backup to the default variable, that will store the result
   307      * of the IL operations executed inside a parenthesis...
   266      * of the IL operations executed inside a parenthesis...
   358       if (NULL == fb_name) ERROR;
   317       if (NULL == fb_name) ERROR;
   359       symbolic_variable_c *sv = dynamic_cast<symbolic_variable_c *>(fb_name);
   318       symbolic_variable_c *sv = dynamic_cast<symbolic_variable_c *>(fb_name);
   360       if (NULL == sv) ERROR;
   319       if (NULL == sv) ERROR;
   361       identifier_c *id = dynamic_cast<identifier_c *>(sv->var_name);
   320       identifier_c *id = dynamic_cast<identifier_c *>(sv->var_name);
   362       if (NULL == id) ERROR;
   321       if (NULL == id) ERROR;
   363 
   322       
   364       identifier_c param(param_name);
   323       identifier_c param(param_name);
   365 
   324 
   366       //SYM_REF3(il_param_assignment_c, il_assign_operator, il_operand, simple_instr_list)
   325       //SYM_REF3(il_param_assignment_c, il_assign_operator, il_operand, simple_instr_list)
   367       il_param_assignment_c il_param_assignment(&param, &this->default_variable_name, NULL);
   326       il_assign_operator_c il_assign_operator(&param);
       
   327       il_param_assignment_c il_param_assignment(&il_assign_operator, &this->default_variable_name, NULL);
   368       // SYM_LIST(il_param_list_c)
   328       // SYM_LIST(il_param_list_c)
   369       il_param_list_c il_param_list;
   329       il_param_list_c il_param_list;   
   370       il_param_list.add_element(&il_param_assignment);
   330       il_param_list.add_element(&il_param_assignment);
   371       CAL_operator_c CAL_operator;
   331       CAL_operator_c CAL_operator;
   372       // SYM_REF4(il_fb_call_c, il_call_operator, fb_name, il_operand_list, il_param_list)
   332       // SYM_REF4(il_fb_call_c, il_call_operator, fb_name, il_operand_list, il_param_list)
   373       il_fb_call_c il_fb_call(&CAL_operator, id, NULL, &il_param_list);
   333       il_fb_call_c il_fb_call(&CAL_operator, id, NULL, &il_param_list);
   374 
   334 
   435 }
   395 }
   436 
   396 
   437 
   397 
   438 private:
   398 private:
   439 
   399 
       
   400 #if 0
       
   401 I NEED TO FIX THIS!!!
       
   402 TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO
   440 void *visit(eno_param_c *symbol) {
   403 void *visit(eno_param_c *symbol) {
   441   if (this->is_variable_prefix_null()) {
   404   if (this->is_variable_prefix_null()) {
   442     s4o.print("*");
   405     s4o.print("*");
   443   }
   406   }
   444   else {
   407   else {
   445     this->print_variable_prefix();
   408     this->print_variable_prefix();
   446   }
   409   }
   447   s4o.print("ENO");
   410   s4o.print("ENO");
   448   return NULL;
   411   return NULL;
   449 }
   412 }
       
   413 TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO
       
   414 #endif
       
   415 
   450 
   416 
   451 /*********************/
   417 /*********************/
   452 /* B 1.4 - Variables */
   418 /* B 1.4 - Variables */
   453 /*********************/
   419 /*********************/
   454 void *visit(symbolic_variable_c *symbol) {
   420 void *visit(symbolic_variable_c *symbol) {
   606     
   572     
   607     int nb_param = 1;
   573     int nb_param = 1;
   608     if (symbol->il_operand_list != NULL)
   574     if (symbol->il_operand_list != NULL)
   609       nb_param += ((list_c *)symbol->il_operand_list)->n;
   575       nb_param += ((list_c *)symbol->il_operand_list)->n;
   610 
   576 
       
   577     #define search(x) search_f(x)
       
   578     #define next() next_nf()
       
   579 //     #define search_constant_type_c::constant_int_type_name  search_expression_type_c::integer
       
   580     #define constant_int_type_name  integer
   611     #include "il_code_gen.c"
   581     #include "il_code_gen.c"
       
   582     #undef constant_int_type_name
       
   583 //     #undef search_constant_type_c::constant_int_type_name
       
   584     #undef next
       
   585     #undef  search
   612 
   586 
   613   }
   587   }
   614   else {
   588   else {
   615     /* determine the base data type returned by the function being called... */
   589     /* determine the base data type returned by the function being called... */
   616     search_base_type_c search_base_type;
   590     search_base_type_c search_base_type;
   647        * We leave it in in case we later decide to merge this part of the code together
   621        * We leave it in in case we later decide to merge this part of the code together
   648        * with the function calling code in generate_c_st_c, which does require
   622        * with the function calling code in generate_c_st_c, which does require
   649        * the following line...
   623        * the following line...
   650        */
   624        */
   651       if (param_value == NULL)
   625       if (param_value == NULL)
   652         param_value = function_call_param_iterator.search(param_name);
   626         param_value = function_call_param_iterator.search_f(param_name);
   653   
   627   
   654       /* Get the value from a foo(<param_value>) style call */
   628       /* Get the value from a foo(<param_value>) style call */
   655       if (param_value == NULL)
   629       if (param_value == NULL)
   656         param_value = function_call_param_iterator.next();
   630         param_value = function_call_param_iterator.next_nf();
   657       
   631       
   658       if (param_value == NULL && param_direction == function_param_iterator_c::direction_in) {
   632       if (param_value == NULL && param_direction == function_param_iterator_c::direction_in) {
   659         /* No value given for parameter, so we must use the default... */
   633         /* No value given for parameter, so we must use the default... */
   660         /* First check whether default value specified in function declaration...*/
   634         /* First check whether default value specified in function declaration...*/
   661         param_value = fp_iterator.default_value();
   635         param_value = fp_iterator.default_value();
   818   function_call_param_iterator_c function_call_param_iterator(symbol);
   792   function_call_param_iterator_c function_call_param_iterator(symbol);
   819   for(int i = 1; (param_name = fp_iterator.next()) != NULL; i++) {
   793   for(int i = 1; (param_name = fp_iterator.next()) != NULL; i++) {
   820     function_param_iterator_c::param_direction_t param_direction = fp_iterator.param_direction();
   794     function_param_iterator_c::param_direction_t param_direction = fp_iterator.param_direction();
   821 
   795 
   822     /* Get the value from a foo(<param_name> = <param_value>) style call */
   796     /* Get the value from a foo(<param_name> = <param_value>) style call */
   823     symbol_c *param_value = function_call_param_iterator.search(param_name);
   797     symbol_c *param_value = function_call_param_iterator.search_f(param_name);
   824 
   798 
   825     /* Get the value from a foo(<param_value>) style call */
   799     /* Get the value from a foo(<param_value>) style call */
   826     if (param_value == NULL)
   800     if (param_value == NULL)
   827       param_value = function_call_param_iterator.next();
   801       param_value = function_call_param_iterator.next_nf();
   828 
   802 
   829     symbol_c *param_type = fp_iterator.param_type();
   803     symbol_c *param_type = fp_iterator.param_type();
   830     if (param_type == NULL) ERROR;
   804     if (param_type == NULL) ERROR;
   831     
   805     
   832         /* now output the value assignment */
   806         /* now output the value assignment */
   863   function_call_param_iterator.reset();
   837   function_call_param_iterator.reset();
   864   for(int i = 1; (param_name = fp_iterator.next()) != NULL; i++) {
   838   for(int i = 1; (param_name = fp_iterator.next()) != NULL; i++) {
   865     function_param_iterator_c::param_direction_t param_direction = fp_iterator.param_direction();
   839     function_param_iterator_c::param_direction_t param_direction = fp_iterator.param_direction();
   866 
   840 
   867     /* Get the value from a foo(<param_name> = <param_value>) style call */
   841     /* Get the value from a foo(<param_name> = <param_value>) style call */
   868     symbol_c *param_value = function_call_param_iterator.search(param_name);
   842     symbol_c *param_value = function_call_param_iterator.search_f(param_name);
   869 
   843 
   870     /* Get the value from a foo(<param_value>) style call */
   844     /* Get the value from a foo(<param_value>) style call */
   871     if (param_value == NULL)
   845     if (param_value == NULL)
   872       param_value = function_call_param_iterator.next();
   846       param_value = function_call_param_iterator.next_nf();
   873 
   847 
   874     /* now output the value assignment */
   848     /* now output the value assignment */
   875     if (param_value != NULL)
   849     if (param_value != NULL)
   876       if ((param_direction == function_param_iterator_c::direction_out) ||
   850       if ((param_direction == function_param_iterator_c::direction_out) ||
   877           (param_direction == function_param_iterator_c::direction_inout)) {
   851           (param_direction == function_param_iterator_c::direction_inout)) {
   878         symbol_c *param_type = search_varfb_instance_type->get_type(param_value, false);
   852         symbol_c *param_type = search_varfb_instance_type->get_type(param_value, false);
   879         
   853 
   880         s4o.print(";\n"+ s4o.indent_spaces);
   854         s4o.print(";\n"+ s4o.indent_spaces);
   881         param_value->accept(*this);
   855         param_value->accept(*this);
   882         s4o.print(" = ");
   856         s4o.print(" = ");
   883         if (search_base_type.type_is_subrange(param_type)) {
   857         if (search_base_type.type_is_subrange(param_type)) {
   884           s4o.print("__CHECK_");
   858           s4o.print("__CHECK_");
   929     if (symbol->il_param_list != NULL)
   903     if (symbol->il_param_list != NULL)
   930       nb_param += ((list_c *)symbol->il_param_list)->n;
   904       nb_param += ((list_c *)symbol->il_param_list)->n;
   931     
   905     
   932     identifier_c en_param_name("EN");
   906     identifier_c en_param_name("EN");
   933     /* Get the value from EN param */
   907     /* Get the value from EN param */
   934     symbol_c *EN_param_value = function_call_param_iterator.search(&en_param_name);
   908     symbol_c *EN_param_value = function_call_param_iterator.search_f(&en_param_name);
   935     if (EN_param_value == NULL)
   909     if (EN_param_value == NULL)
   936       EN_param_value = (symbol_c*)(new boolean_literal_c((symbol_c*)(new bool_type_name_c()), new boolean_true_c()));
   910       EN_param_value = (symbol_c*)(new boolean_literal_c((symbol_c*)(new bool_type_name_c()), new boolean_true_c()));
   937     else
   911     else
   938       nb_param --;
   912       nb_param --;
   939     ADD_PARAM_LIST(EN_param_value, (symbol_c*)(new bool_type_name_c()), function_param_iterator_c::direction_in)
   913     ADD_PARAM_LIST(EN_param_value, (symbol_c*)(new bool_type_name_c()), function_param_iterator_c::direction_in)
   940     
   914     
   941     identifier_c eno_param_name("EN0");
   915     identifier_c eno_param_name("EN0");
   942     /* Get the value from ENO param */
   916     /* Get the value from ENO param */
   943     symbol_c *ENO_param_value = function_call_param_iterator.search(&eno_param_name);
   917     symbol_c *ENO_param_value = function_call_param_iterator.search_f(&eno_param_name);
   944     if (ENO_param_value != NULL)
   918     if (ENO_param_value != NULL)
   945       nb_param --;
   919       nb_param --;
   946     ADD_PARAM_LIST(ENO_param_value, (symbol_c*)(new bool_type_name_c()), function_param_iterator_c::direction_out)
   920     ADD_PARAM_LIST(ENO_param_value, (symbol_c*)(new bool_type_name_c()), function_param_iterator_c::direction_out)
   947     
   921     
       
   922     #define search(x) search_f(x)
       
   923     #define next() next_nf()
       
   924 //     #define search_constant_type_c::constant_int_type_name  search_expression_type_c::integer
       
   925     #define constant_int_type_name  integer
   948     #include "st_code_gen.c"
   926     #include "st_code_gen.c"
       
   927     #undef constant_int_type_name
       
   928 //     #undef search_constant_type_c::constant_int_type_name
       
   929     #undef next
       
   930     #undef  search
   949     
   931     
   950   }
   932   }
   951   else {
   933   else {
   952     /* determine the base data type returned by the function being called... */
   934     /* determine the base data type returned by the function being called... */
   953     search_base_type_c search_base_type;
   935     search_base_type_c search_base_type;
   972   
   954   
   973       symbol_c *param_value = NULL;
   955       symbol_c *param_value = NULL;
   974   
   956   
   975       /* Get the value from a foo(<param_name> = <param_value>) style call */
   957       /* Get the value from a foo(<param_name> = <param_value>) style call */
   976       if (param_value == NULL)
   958       if (param_value == NULL)
   977         param_value = function_call_param_iterator.search(param_name);
   959         param_value = function_call_param_iterator.search_f(param_name);
   978   
   960   
   979       /* Get the value from a foo(<param_value>) style call */
   961       /* Get the value from a foo(<param_value>) style call */
   980       /* NOTE: the following line of code is not required in this case, but it doesn't
   962       /* NOTE: the following line of code is not required in this case, but it doesn't
   981        * harm to leave it in, as in the case of a formal syntax function call,
   963        * harm to leave it in, as in the case of a formal syntax function call,
   982        * it will always return NULL.
   964        * it will always return NULL.
   983        * We leave it in in case we later decide to merge this part of the code together
   965        * We leave it in in case we later decide to merge this part of the code together
   984        * with the function calling code in generate_c_st_c, which does require
   966        * with the function calling code in generate_c_st_c, which does require
   985        * the following line...
   967        * the following line...
   986        */
   968        */
   987       if (param_value == NULL)
   969       if (param_value == NULL)
   988         param_value = function_call_param_iterator.next();
   970         param_value = function_call_param_iterator.next_nf();
   989       
   971       
   990       if (param_value == NULL) {
   972       if (param_value == NULL) {
   991         /* No value given for parameter, so we must use the default... */
   973         /* No value given for parameter, so we must use the default... */
   992         /* First check whether default value specified in function declaration...*/
   974         /* First check whether default value specified in function declaration...*/
   993         param_value = fp_iterator.default_value();
   975         param_value = fp_iterator.default_value();