stage4/generate_c/generate_c.cc
changeset 258 d7d92b2f87e9
parent 257 90782e241346
parent 250 5d2927300e2c
child 262 197ba42d78b2
equal deleted inserted replaced
257:90782e241346 258:d7d92b2f87e9
   120 #define FB_FUNCTION_PARAM "data__"
   120 #define FB_FUNCTION_PARAM "data__"
   121 
   121 
   122 
   122 
   123 #define SFC_STEP_ACTION_PREFIX "__SFC_"
   123 #define SFC_STEP_ACTION_PREFIX "__SFC_"
   124 
   124 
   125 /***********************************************************************/
   125 
   126 /***********************************************************************/
   126 /* Variable declaration symbol for accessor macros */
   127 /***********************************************************************/
   127 #define DECLARE_VAR "__DECLARE_VAR"
   128 /***********************************************************************/
   128 #define DECLARE_GLOBAL "__DECLARE_GLOBAL"
   129 
   129 #define DECLARE_GLOBAL_LOCATION "__DECLARE_GLOBAL_LOCATION"
   130 #include "generate_c_base.cc"
   130 #define DECLARE_GLOBAL_LOCATED "__DECLARE_GLOBAL_LOCATED"
   131 #include "generate_c_typedecl.cc"
   131 #define DECLARE_EXTERNAL "__DECLARE_EXTERNAL"
   132 #include "generate_c_sfcdecl.cc"
   132 #define DECLARE_LOCATED "__DECLARE_LOCATED"
   133 #include "generate_c_vardecl.cc"
   133 
   134 #include "generate_c_configbody.cc"
   134 /* Variable declaration symbol for accessor macros */
   135 #include "generate_location_list.cc"
   135 #define INIT_VAR "__INIT_VAR"
   136 #include "generate_var_list.cc"
   136 #define INIT_GLOBAL "__INIT_GLOBAL"
   137 
   137 #define INIT_GLOBAL_LOCATED "__INIT_GLOBAL_LOCATED"
   138 /***********************************************************************/
   138 #define INIT_EXTERNAL "__INIT_EXTERNAL"
   139 /***********************************************************************/
   139 #define INIT_LOCATED "__INIT_LOCATED"
   140 /***********************************************************************/
   140 #define INIT_LOCATED_VALUE "__INIT_LOCATED_VALUE"
   141 /***********************************************************************/
   141 
       
   142 
       
   143 /* Variable getter symbol for accessor macros */
       
   144 #define GET_VAR "__GET_VAR"
       
   145 #define GET_EXTERNAL "__GET_EXTERNAL"
       
   146 #define GET_LOCATED "__GET_LOCATED"
       
   147 #define GET_VAR_BY_REF "__GET_VAR_BY_REF"
       
   148 #define GET_EXTERNAL_BY_REF "__GET_EXTERNAL_BY_REF"
       
   149 #define GET_LOCATED_BY_REF "__GET_LOCATED_BY_REF"
       
   150 
       
   151 /* Variable setter symbol for accessor macros */
       
   152 #define SET_VAR "__SET_VAR"
       
   153 #define SET_EXTERNAL "__SET_EXTERNAL"
       
   154 #define SET_COMPLEX_EXTERNAL "__SET_COMPLEX_EXTERNAL"
       
   155 #define SET_LOCATED "__SET_LOCATED"
       
   156 
   142 
   157 
   143 /* Generate a name for a temporary variable.
   158 /* Generate a name for a temporary variable.
   144  * Each new name generated is appended a different number,
   159  * Each new name generated is appended a different number,
   145  * starting off from 0.
   160  * starting off from 0.
   146  * After calling reset(), the names will start off again from 0.
   161  * After calling reset(), the names will start off again from 0.
   147  */
   162  */
   148 #define VAR_LEADER "__"
   163 #define VAR_LEADER "__"
   149 #define TEMP_VAR VAR_LEADER "TMP_"
   164 #define TEMP_VAR VAR_LEADER "TMP_"
   150 #define SOURCE_VAR VAR_LEADER "SRC_"
   165 #define SOURCE_VAR VAR_LEADER "SRC_"
   151 
   166 
       
   167 /***********************************************************************/
       
   168 /***********************************************************************/
       
   169 /***********************************************************************/
       
   170 /***********************************************************************/
       
   171 
       
   172 #include "generate_c_base.cc"
       
   173 #include "generate_c_typedecl.cc"
       
   174 #include "generate_c_sfcdecl.cc"
       
   175 #include "generate_c_vardecl.cc"
       
   176 #include "generate_c_configbody.cc"
       
   177 #include "generate_location_list.cc"
       
   178 #include "generate_var_list.cc"
       
   179 
       
   180 /***********************************************************************/
       
   181 /***********************************************************************/
       
   182 /***********************************************************************/
       
   183 /***********************************************************************/
       
   184 
   152 #include "generate_c_st.cc"
   185 #include "generate_c_st.cc"
   153 #include "generate_c_il.cc"
   186 #include "generate_c_il.cc"
       
   187 #include "generate_c_inlinefcall.cc"
   154 
   188 
   155 #include "generate_c.hh"
   189 #include "generate_c.hh"
   156 
   190 
   157 /***********************************************************************/
   191 /***********************************************************************/
   158 /***********************************************************************/
   192 /***********************************************************************/
   163 #define SECOND 1000 * MILLISECOND
   197 #define SECOND 1000 * MILLISECOND
   164 
   198 
   165 /* A helper class that knows how to generate code for both the IL and ST languages... */
   199 /* A helper class that knows how to generate code for both the IL and ST languages... */
   166 class calculate_time_c: public iterator_visitor_c {
   200 class calculate_time_c: public iterator_visitor_c {
   167   private:
   201   private:
   168     unsigned long time;
   202     unsigned long long time;
   169     float current_value;
   203     float current_value;
   170   
   204   
   171   public:
   205   public:
   172     calculate_time_c(void){time = 0;};
   206     calculate_time_c(void){time = 0;};
   173     
   207     
   174     unsigned long get_time(void) {return time;};
   208     unsigned long long get_time(void) {return time;};
   175 
   209 
   176     void *get_integer_value(token_c *token) {
   210     void *get_integer_value(token_c *token) {
   177       std::string str = "";
   211       std::string str = "";
   178       for (unsigned int i = 0; i < strlen(token->value); i++)
   212       for (unsigned int i = 0; i < strlen(token->value); i++)
   179         if (token->value[i] != '_')
   213         if (token->value[i] != '_')
   211     /* SYM_REF2(days_c, days, hours) */
   245     /* SYM_REF2(days_c, days, hours) */
   212     void *visit(days_c *symbol) {
   246     void *visit(days_c *symbol) {
   213       if (symbol->hours)
   247       if (symbol->hours)
   214         symbol->hours->accept(*this);
   248         symbol->hours->accept(*this);
   215       symbol->days->accept(*this);
   249       symbol->days->accept(*this);
   216       time += (unsigned long)(current_value * 24 * 3600 * SECOND);
   250       time += (unsigned long long)(current_value * 24 * 3600 * SECOND);
   217       return NULL;
   251       return NULL;
   218     }
   252     }
   219     
   253     
   220     /* SYM_REF2(hours_c, hours, minutes) */
   254     /* SYM_REF2(hours_c, hours, minutes) */
   221     void *visit(hours_c *symbol) {
   255     void *visit(hours_c *symbol) {
   222       if (symbol->minutes)
   256       if (symbol->minutes)
   223         symbol->minutes->accept(*this);
   257         symbol->minutes->accept(*this);
   224       symbol->hours->accept(*this);
   258       symbol->hours->accept(*this);
   225       time += (unsigned long)(current_value * 3600 * SECOND);
   259       time += (unsigned long long)(current_value * 3600 * SECOND);
   226       return NULL;
   260       return NULL;
   227     }
   261     }
   228     
   262     
   229     /* SYM_REF2(minutes_c, minutes, seconds) */
   263     /* SYM_REF2(minutes_c, minutes, seconds) */
   230     void *visit(minutes_c *symbol) {
   264     void *visit(minutes_c *symbol) {
   231       if (symbol->seconds)
   265       if (symbol->seconds)
   232         symbol->seconds->accept(*this);
   266         symbol->seconds->accept(*this);
   233       symbol->minutes->accept(*this);
   267       symbol->minutes->accept(*this);
   234       time += (unsigned long)(current_value * 60 * SECOND);
   268       time += (unsigned long long)(current_value * 60 * SECOND);
   235       return NULL;
   269       return NULL;
   236     }
   270     }
   237     
   271     
   238     /* SYM_REF2(seconds_c, seconds, milliseconds) */
   272     /* SYM_REF2(seconds_c, seconds, milliseconds) */
   239     void *visit(seconds_c *symbol) {
   273     void *visit(seconds_c *symbol) {
   240       if (symbol->milliseconds)
   274       if (symbol->milliseconds)
   241         symbol->milliseconds->accept(*this);
   275         symbol->milliseconds->accept(*this);
   242       symbol->seconds->accept(*this);
   276       symbol->seconds->accept(*this);
   243       time += (unsigned long)(current_value * SECOND);
   277       time += (unsigned long long)(current_value * SECOND);
   244       return NULL;
   278       return NULL;
   245     }
   279     }
   246     
   280     
   247     /* SYM_REF2(milliseconds_c, milliseconds, unused) */
   281     /* SYM_REF2(milliseconds_c, milliseconds, unused) */
   248     void *visit(milliseconds_c *symbol) {
   282     void *visit(milliseconds_c *symbol) {
   249       symbol->milliseconds->accept(*this);
   283       symbol->milliseconds->accept(*this);
   250       time += (unsigned long)(current_value * MILLISECOND);
   284       time += (unsigned long long)(current_value * MILLISECOND);
   251       return NULL;
   285       return NULL;
   252     }
   286     }
   253 };
   287 };
   254 
   288 
   255 /***********************************************************************/
   289 /***********************************************************************/
   257 /***********************************************************************/
   291 /***********************************************************************/
   258 /***********************************************************************/
   292 /***********************************************************************/
   259 
   293 
   260 class calculate_common_ticktime_c: public iterator_visitor_c {
   294 class calculate_common_ticktime_c: public iterator_visitor_c {
   261   private:
   295   private:
   262     unsigned long common_ticktime;
   296     unsigned long long common_ticktime;
       
   297     unsigned long long least_common_ticktime;
   263     
   298     
   264   public:
   299   public:
   265     calculate_common_ticktime_c(void){common_ticktime = 0;}
   300     calculate_common_ticktime_c(void){
   266     
   301       common_ticktime = 0;
   267     unsigned long euclide(unsigned long a, unsigned long b) {
   302       least_common_ticktime = 0;
   268       unsigned long c = a % b;
   303     }
       
   304     
       
   305     unsigned long long euclide(unsigned long long a, unsigned long long b) {
       
   306       unsigned long long c = a % b;
   269       if (c == 0)
   307       if (c == 0)
   270         return b;
   308         return b;
   271       else
   309       else
   272         return euclide(b, c);
   310         return euclide(b, c);
   273     }
   311     }
   274     
   312     
   275     void update_ticktime(unsigned long time) {
   313     void update_ticktime(unsigned long long time) {
   276       if (common_ticktime == 0)
   314       if (common_ticktime == 0)
   277         common_ticktime = time;
   315         common_ticktime = time;
   278       else if (time > common_ticktime)
   316       else if (time > common_ticktime)
   279         common_ticktime = euclide(time, common_ticktime);
   317         common_ticktime = euclide(time, common_ticktime);
   280       else
   318       else
   281         common_ticktime = euclide(common_ticktime, time);
   319         common_ticktime = euclide(common_ticktime, time);
   282     }
   320       if (least_common_ticktime == 0)
   283 
   321         least_common_ticktime = time;
   284     unsigned long get_ticktime(void) {
   322       else
       
   323         least_common_ticktime = (least_common_ticktime * time) / common_ticktime;
       
   324     }
       
   325 
       
   326     unsigned long long get_common_ticktime(void) {
   285       return common_ticktime;
   327       return common_ticktime;
       
   328     }
       
   329 
       
   330     unsigned long get_greatest_tick_count(void) {
       
   331       unsigned long long least_common_tick = least_common_ticktime / common_ticktime;
       
   332       if (least_common_tick >> 32)
       
   333         ERROR;
       
   334       return (unsigned long)(~(((unsigned long)-1) % (unsigned long)least_common_tick) + 1);
   286     }
   335     }
   287 
   336 
   288 /*  TASK task_name task_initialization */
   337 /*  TASK task_name task_initialization */
   289 //SYM_REF2(task_configuration_c, task_name, task_initialization)  
   338 //SYM_REF2(task_configuration_c, task_name, task_initialization)  
   290     void *visit(task_initialization_c *symbol) {
   339     void *visit(task_initialization_c *symbol) {
   291       calculate_time_c calculate_time;
   340       calculate_time_c calculate_time;
   292       unsigned long time = 0;
   341       unsigned long long time = 0;
   293       if (symbol->interval_data_source != NULL) {
   342       if (symbol->interval_data_source != NULL) {
   294         symbol->interval_data_source->accept(calculate_time);
   343         symbol->interval_data_source->accept(calculate_time);
   295         time = calculate_time.get_time();
   344         time = calculate_time.get_time();
   296       }
   345       }
   297       if (time > 0)
   346       if (time > 0)
   303 /***********************************************************************/
   352 /***********************************************************************/
   304 /***********************************************************************/
   353 /***********************************************************************/
   305 /***********************************************************************/
   354 /***********************************************************************/
   306 /***********************************************************************/
   355 /***********************************************************************/
   307 
   356 
   308 /* A helper class that knows how to generate code for both the IL and ST languages... */
   357 /* A helper class that knows how to generate code for the SFC, IL and ST languages... */
   309 class generate_c_SFC_IL_ST_c: public null_visitor_c {
   358 class generate_c_SFC_IL_ST_c: public null_visitor_c {
   310   private:
   359   private:
   311     stage4out_c *s4o_ptr;
   360     stage4out_c *s4o_ptr;
   312     symbol_c *scope;
   361     symbol_c *scope;
       
   362     symbol_c *fbname;
   313     const char *variable_prefix;
   363     const char *variable_prefix;
   314 
   364 
   315   public:
   365   public:
   316     generate_c_SFC_IL_ST_c(stage4out_c *s4o_ptr, symbol_c *scope, const char *variable_prefix = NULL);
   366     generate_c_SFC_IL_ST_c(stage4out_c *s4o_ptr, symbol_c *name, symbol_c *scope, const char *variable_prefix = NULL);
   317     /*********************************************/
   367     /*********************************************/
   318     /* B.1.6  Sequential function chart elements */
   368     /* B.1.6  Sequential function chart elements */
   319     /*********************************************/
   369     /*********************************************/
   320     
   370     
   321     /*| sequential_function_chart sfc_network*/
   371     /*| sequential_function_chart sfc_network*/
   349 /* Remainder implemented in generate_c_st_c... */
   399 /* Remainder implemented in generate_c_st_c... */
   350 };
   400 };
   351 
   401 
   352 #include "generate_c_sfc.cc"
   402 #include "generate_c_sfc.cc"
   353 
   403 
   354 generate_c_SFC_IL_ST_c::generate_c_SFC_IL_ST_c(stage4out_c *s4o_ptr, symbol_c *scope, const char *variable_prefix) {
   404 generate_c_SFC_IL_ST_c::generate_c_SFC_IL_ST_c(stage4out_c *s4o_ptr, symbol_c *name, symbol_c *scope, const char *variable_prefix) {
   355   if (NULL == scope) ERROR;
   405   if (NULL == scope) ERROR;
   356   this->s4o_ptr = s4o_ptr;
   406   this->s4o_ptr = s4o_ptr;
   357   this->scope = scope;
   407   this->scope = scope;
       
   408   this->fbname = name;
   358   this->variable_prefix = variable_prefix;
   409   this->variable_prefix = variable_prefix;
   359 }
   410 }
   360 
   411 
   361 void *generate_c_SFC_IL_ST_c::visit(sequential_function_chart_c * symbol) {
   412 void *generate_c_SFC_IL_ST_c::visit(sequential_function_chart_c * symbol) {
   362   generate_c_sfc_c generate_c_sfc(s4o_ptr, scope, variable_prefix);
   413   generate_c_sfc_c generate_c_sfc(s4o_ptr, fbname, scope, variable_prefix);
   363   generate_c_sfc.generate(symbol);
   414   generate_c_sfc.generate(symbol);
   364   return NULL;
   415   return NULL;
   365 }
   416 }
   366 
   417 
   367 void *generate_c_SFC_IL_ST_c::visit(instruction_list_c *symbol) {
   418 void *generate_c_SFC_IL_ST_c::visit(instruction_list_c *symbol) {
   368   generate_c_il_c generate_c_il(s4o_ptr, scope, variable_prefix);
   419   generate_c_il_c generate_c_il(s4o_ptr, fbname, scope, variable_prefix);
   369   generate_c_il.generate(symbol);
   420   generate_c_il.generate(symbol);
   370   return NULL;
   421   return NULL;
   371 }
   422 }
   372 
   423 
   373 void *generate_c_SFC_IL_ST_c::visit(statement_list_c *symbol) {
   424 void *generate_c_SFC_IL_ST_c::visit(statement_list_c *symbol) {
   374   generate_c_st_c generate_c_st(s4o_ptr, scope, variable_prefix);
   425   generate_c_st_c generate_c_st(s4o_ptr, fbname, scope, variable_prefix);
   375   generate_c_st.generate(symbol);
   426   generate_c_st.generate(symbol);
   376   return NULL;
   427   return NULL;
   377 }
   428 }
   378 
   429 
   379 
   430 
   550   s4o.print(";\n");
   601   s4o.print(";\n");
   551   s4o.indent_left();
   602   s4o.indent_left();
   552   s4o.print(s4o.indent_spaces + "}\n");
   603   s4o.print(s4o.indent_spaces + "}\n");
   553 
   604 
   554   /* (C) Function body */
   605   /* (C) Function body */
   555   generate_c_SFC_IL_ST_c generate_c_code(&s4o, symbol);
   606   generate_c_SFC_IL_ST_c generate_c_code(&s4o, symbol->derived_function_name, symbol);
   556   symbol->function_body->accept(generate_c_code);
   607   symbol->function_body->accept(generate_c_code);
   557   
   608   
   558   vardecl = new generate_c_vardecl_c(&s4o,
   609   vardecl = new generate_c_vardecl_c(&s4o,
   559                 generate_c_vardecl_c::foutputassign_vf,
   610                 generate_c_vardecl_c::foutputassign_vf,
   560                 generate_c_vardecl_c::output_vt   |
   611                 generate_c_vardecl_c::output_vt   |
   586 //SYM_REF4(function_block_declaration_c, fblock_name, var_declarations, fblock_body, unused)
   637 //SYM_REF4(function_block_declaration_c, fblock_name, var_declarations, fblock_body, unused)
   587 void *visit(function_block_declaration_c *symbol) {
   638 void *visit(function_block_declaration_c *symbol) {
   588   generate_c_vardecl_c *vardecl;
   639   generate_c_vardecl_c *vardecl;
   589   generate_c_sfcdecl_c *sfcdecl;
   640   generate_c_sfcdecl_c *sfcdecl;
   590   generate_c_typedecl_c *typedecl;
   641   generate_c_typedecl_c *typedecl;
       
   642   generate_c_inlinefcall_c *inlinedecl;
   591   TRACE("function_block_declaration_c");
   643   TRACE("function_block_declaration_c");
   592 
   644 
   593   /* (A) Function Block data structure declaration... */
   645   /* (A) Function Block data structure declaration... */
   594   typedecl = new generate_c_typedecl_c(&s4o_incl);
   646   typedecl = new generate_c_typedecl_c(&s4o_incl);
   595   /* (A.1) Data structure declaration */
   647   /* (A.1) Data structure declaration */
   620                                      generate_c_vardecl_c::external_vt);
   672                                      generate_c_vardecl_c::external_vt);
   621   vardecl->print(symbol->var_declarations);
   673   vardecl->print(symbol->var_declarations);
   622   delete vardecl;
   674   delete vardecl;
   623   
   675   
   624   /* (A.4) Generate private internal variables for SFC */
   676   /* (A.4) Generate private internal variables for SFC */
   625   sfcdecl = new generate_c_sfcdecl_c(&s4o_incl, generate_c_sfcdecl_c::sfcdecl_sd);
   677   sfcdecl = new generate_c_sfcdecl_c(&s4o_incl, symbol);
   626   sfcdecl->print(symbol->fblock_body);
   678   sfcdecl->generate(symbol->fblock_body, generate_c_sfcdecl_c::sfcdecl_sd);
   627   delete sfcdecl;
   679   delete sfcdecl;
   628   s4o_incl.print("\n");
   680   s4o_incl.print("\n");
   629   
   681 
   630   /* (A.5) Function Block data structure type name. */
   682   /* (A.5) Function Block data structure type name. */
   631   s4o_incl.indent_left();
   683   s4o_incl.indent_left();
   632   s4o_incl.print("} ");
   684   s4o_incl.print("} ");
   633   symbol->fblock_name->accept(*typedecl);
   685   symbol->fblock_name->accept(*typedecl);
   634   s4o_incl.print(";\n\n");
   686   s4o_incl.print(";\n\n");
   635   delete typedecl;
   687   delete typedecl;
   636 
   688 
       
   689   /* (A.6) Function Block inline function declaration for function invocation */
       
   690   inlinedecl = new generate_c_inlinefcall_c(&s4o, symbol->fblock_name, symbol, FB_FUNCTION_PARAM"->");
       
   691   inlinedecl->print(symbol->fblock_body);
       
   692   delete inlinedecl;
       
   693 
   637   /* (B) Constructor */
   694   /* (B) Constructor */
   638   /* (B.1) Constructor name... */
   695   /* (B.1) Constructor name... */
   639   s4o.print(s4o.indent_spaces + "void ");
   696   s4o.print(s4o.indent_spaces + "void ");
   640   symbol->fblock_name->accept(*this);
   697   symbol->fblock_name->accept(*this);
   641   s4o.print(FB_INIT_SUFFIX);
   698   s4o.print(FB_INIT_SUFFIX);
   643 
   700 
   644   /* first and only parameter is a pointer to the data */
   701   /* first and only parameter is a pointer to the data */
   645   symbol->fblock_name->accept(*this);
   702   symbol->fblock_name->accept(*this);
   646   s4o.print(" *");
   703   s4o.print(" *");
   647   s4o.print(FB_FUNCTION_PARAM);
   704   s4o.print(FB_FUNCTION_PARAM);
   648   s4o.print(") {\n");
   705   s4o.print(", BOOL retain) {\n");
   649   s4o.indent_right();
   706   s4o.indent_right();
   650 
   707 
   651   /* (B.2) Member initializations... */
   708   /* (B.2) Member initializations... */
   652   s4o.print(s4o.indent_spaces);
   709   s4o.print(s4o.indent_spaces);
   653   vardecl = new generate_c_vardecl_c(&s4o,
   710   vardecl = new generate_c_vardecl_c(&s4o,
   661                                      generate_c_vardecl_c::en_vt       |
   718                                      generate_c_vardecl_c::en_vt       |
   662                                      generate_c_vardecl_c::eno_vt);
   719                                      generate_c_vardecl_c::eno_vt);
   663   vardecl->print(symbol->var_declarations, NULL, FB_FUNCTION_PARAM"->");
   720   vardecl->print(symbol->var_declarations, NULL, FB_FUNCTION_PARAM"->");
   664   delete vardecl;
   721   delete vardecl;
   665   s4o.print("\n");
   722   s4o.print("\n");
       
   723 
       
   724   sfcdecl = new generate_c_sfcdecl_c(&s4o, symbol, FB_FUNCTION_PARAM"->");
       
   725 
   666   /* (B.3) Generate private internal variables for SFC */
   726   /* (B.3) Generate private internal variables for SFC */
   667   sfcdecl = new generate_c_sfcdecl_c(&s4o, generate_c_sfcdecl_c::sfcinit_sd);
   727   sfcdecl->generate(symbol->fblock_body, generate_c_sfcdecl_c::sfcinit_sd);
   668   sfcdecl->print(symbol->fblock_body, FB_FUNCTION_PARAM"->");
   728 
   669   delete sfcdecl;
       
   670   s4o.indent_left();
   729   s4o.indent_left();
   671   s4o.print(s4o.indent_spaces + "}\n\n");
   730   s4o.print(s4o.indent_spaces + "}\n\n");
   672 
   731 
   673   
   732   
   674   /* (C) Function with FB body */
   733   /* (C) Function with FB body */
   675   /* (C.1) Step definitions */
   734   /* (C.1) Step definitions */
   676   sfcdecl = new generate_c_sfcdecl_c(&s4o, generate_c_sfcdecl_c::stepdef_sd);
   735   sfcdecl->generate(symbol->fblock_body, generate_c_sfcdecl_c::stepdef_sd);
   677   sfcdecl->print(symbol->fblock_body);
       
   678   delete sfcdecl;
       
   679   
   736   
   680   /* (C.2) Action definitions */
   737   /* (C.2) Action definitions */
   681   sfcdecl = new generate_c_sfcdecl_c(&s4o, generate_c_sfcdecl_c::actiondef_sd);
   738   sfcdecl->generate(symbol->fblock_body, generate_c_sfcdecl_c::actiondef_sd);
   682   sfcdecl->print(symbol->fblock_body);
   739 
   683   delete sfcdecl;
       
   684   
       
   685   /* (C.3) Function declaration */
   740   /* (C.3) Function declaration */
   686   s4o.print("// Code part\n");
   741   s4o.print("// Code part\n");
   687   /* function interface */
   742   /* function interface */
   688   s4o.print("void ");
   743   s4o.print("void ");
   689   symbol->fblock_name->accept(*this);
   744   symbol->fblock_name->accept(*this);
   696   s4o.print(") {\n");
   751   s4o.print(") {\n");
   697   s4o.indent_right();
   752   s4o.indent_right();
   698 
   753 
   699   s4o.print(s4o.indent_spaces + "// Control execution\n");
   754   s4o.print(s4o.indent_spaces + "// Control execution\n");
   700   s4o.print(s4o.indent_spaces + "if (!");
   755   s4o.print(s4o.indent_spaces + "if (!");
       
   756   s4o.print(GET_VAR);
       
   757   s4o.print("(");
   701   s4o.print(FB_FUNCTION_PARAM);
   758   s4o.print(FB_FUNCTION_PARAM);
   702   s4o.print("->EN) {\n");
   759   s4o.print("->EN)) {\n");
   703   s4o.indent_right();
   760   s4o.indent_right();
   704   s4o.print(s4o.indent_spaces);
   761   s4o.print(s4o.indent_spaces);
       
   762   s4o.print(SET_VAR);
       
   763   s4o.print("(");
   705   s4o.print(FB_FUNCTION_PARAM);
   764   s4o.print(FB_FUNCTION_PARAM);
   706   s4o.print("->ENO = __BOOL_LITERAL(FALSE);\n");
   765   s4o.print("->ENO,__BOOL_LITERAL(FALSE));\n");
   707   s4o.print(s4o.indent_spaces + "return;\n");
   766   s4o.print(s4o.indent_spaces + "return;\n");
   708   s4o.indent_left();
   767   s4o.indent_left();
   709   s4o.print(s4o.indent_spaces + "}\n");
   768   s4o.print(s4o.indent_spaces + "}\n");
   710   s4o.print(s4o.indent_spaces + "else {\n");
   769   s4o.print(s4o.indent_spaces + "else {\n");
   711   s4o.indent_right();
   770   s4o.indent_right();
   712   s4o.print(s4o.indent_spaces);
   771   s4o.print(s4o.indent_spaces);
       
   772   s4o.print(SET_VAR);
       
   773   s4o.print("(");
   713   s4o.print(FB_FUNCTION_PARAM);
   774   s4o.print(FB_FUNCTION_PARAM);
   714   s4o.print("->ENO = __BOOL_LITERAL(TRUE);\n");
   775   s4o.print("->ENO,__BOOL_LITERAL(TRUE));\n");
   715   s4o.indent_left();
   776   s4o.indent_left();
   716   s4o.print(s4o.indent_spaces + "}\n");
   777   s4o.print(s4o.indent_spaces + "}\n");
   717 
   778 
   718   /* (C.4) Initialize TEMP variables */
   779   /* (C.4) Initialize TEMP variables */
   719   /* function body */
   780   /* function body */
   724   vardecl->print(symbol->var_declarations, NULL,  FB_FUNCTION_PARAM"->");
   785   vardecl->print(symbol->var_declarations, NULL,  FB_FUNCTION_PARAM"->");
   725   delete vardecl;
   786   delete vardecl;
   726   s4o.print("\n");
   787   s4o.print("\n");
   727 
   788 
   728   /* (C.5) Function code */
   789   /* (C.5) Function code */
   729   generate_c_SFC_IL_ST_c generate_c_code(&s4o, symbol, FB_FUNCTION_PARAM"->");
   790   generate_c_SFC_IL_ST_c generate_c_code(&s4o, symbol->fblock_name, symbol, FB_FUNCTION_PARAM"->");
   730   symbol->fblock_body->accept(generate_c_code);
   791   symbol->fblock_body->accept(generate_c_code);
   731   s4o.indent_left();
   792   s4o.indent_left();
   732   s4o.print(s4o.indent_spaces + "} // ");
   793   s4o.print(s4o.indent_spaces + "} // ");
   733   symbol->fblock_name->accept(*this);
   794   symbol->fblock_name->accept(*this);
   734   s4o.print(FB_FUNCTION_SUFFIX);
   795   s4o.print(FB_FUNCTION_SUFFIX);
   735   s4o.print(s4o.indent_spaces + "() \n\n");
   796   s4o.print(s4o.indent_spaces + "() \n\n");
   736 
   797 
   737   /* (C.6) Step undefinitions */
   798   /* (C.6) Step undefinitions */
   738   sfcdecl = new generate_c_sfcdecl_c(&s4o, generate_c_sfcdecl_c::stepundef_sd);
   799   sfcdecl->generate(symbol->fblock_body, generate_c_sfcdecl_c::stepundef_sd);
   739   sfcdecl->print(symbol->fblock_body);
   800 
   740   delete sfcdecl;
       
   741   
       
   742   /* (C.7) Action undefinitions */
   801   /* (C.7) Action undefinitions */
   743   sfcdecl = new generate_c_sfcdecl_c(&s4o, generate_c_sfcdecl_c::actionundef_sd);
   802   sfcdecl->generate(symbol->fblock_body, generate_c_sfcdecl_c::actionundef_sd);
   744   sfcdecl->print(symbol->fblock_body);
   803 
   745   delete sfcdecl;
   804   delete sfcdecl;
   746 
   805 
   747   s4o.indent_left();
   806   s4o.indent_left();
   748   s4o.print("\n\n\n\n");
   807   s4o.print("\n\n\n\n");
   749 
   808 
   767 //SYM_REF4(program_declaration_c, program_type_name, var_declarations, function_block_body, unused)
   826 //SYM_REF4(program_declaration_c, program_type_name, var_declarations, function_block_body, unused)
   768 void *visit(program_declaration_c *symbol) {
   827 void *visit(program_declaration_c *symbol) {
   769   generate_c_vardecl_c *vardecl;
   828   generate_c_vardecl_c *vardecl;
   770   generate_c_sfcdecl_c *sfcdecl;
   829   generate_c_sfcdecl_c *sfcdecl;
   771   generate_c_typedecl_c *typedecl;
   830   generate_c_typedecl_c *typedecl;
       
   831   generate_c_inlinefcall_c *inlinedecl;
   772   TRACE("program_declaration_c");
   832   TRACE("program_declaration_c");
   773 
   833 
   774   /* (A) Program data structure declaration... */
   834   /* (A) Program data structure declaration... */
   775   typedecl = new generate_c_typedecl_c(&s4o_incl);
   835   typedecl = new generate_c_typedecl_c(&s4o_incl);
   776   /* (A.1) Data structure declaration */
   836   /* (A.1) Data structure declaration */
   798                 generate_c_vardecl_c::private_vt |
   858                 generate_c_vardecl_c::private_vt |
   799                 generate_c_vardecl_c::located_vt |
   859                 generate_c_vardecl_c::located_vt |
   800                 generate_c_vardecl_c::external_vt);
   860                 generate_c_vardecl_c::external_vt);
   801   vardecl->print(symbol->var_declarations);
   861   vardecl->print(symbol->var_declarations);
   802   delete vardecl;
   862   delete vardecl;
       
   863 
   803   /* (A.4) Generate private internal variables for SFC */
   864   /* (A.4) Generate private internal variables for SFC */
   804   sfcdecl = new generate_c_sfcdecl_c(&s4o_incl, generate_c_sfcdecl_c::sfcdecl_sd);
   865   sfcdecl = new generate_c_sfcdecl_c(&s4o_incl, symbol);
   805   sfcdecl->print(symbol->function_block_body);
   866   sfcdecl->generate(symbol->function_block_body, generate_c_sfcdecl_c::sfcdecl_sd);
   806   delete sfcdecl;
   867   delete sfcdecl;
       
   868   s4o_incl.print("\n");
   807   
   869   
   808   /* (A.5) Program data structure type name. */
   870   /* (A.5) Program data structure type name. */
   809   s4o_incl.indent_left();
   871   s4o_incl.indent_left();
   810   s4o_incl.print("} ");
   872   s4o_incl.print("} ");
   811   symbol->program_type_name->accept(*typedecl);
   873   symbol->program_type_name->accept(*typedecl);
   812   s4o_incl.print(";\n\n");
   874   s4o_incl.print(";\n\n");
   813   delete typedecl;
   875   delete typedecl;
   814 
   876 
       
   877   /* (A.6) Function Block inline function declaration for function invocation */
       
   878   inlinedecl = new generate_c_inlinefcall_c(&s4o, symbol->program_type_name, symbol, FB_FUNCTION_PARAM"->");
       
   879   inlinedecl->print(symbol->function_block_body);
       
   880   delete inlinedecl;
       
   881 
   815   /* (B) Constructor */
   882   /* (B) Constructor */
   816   /* (B.1) Constructor name... */
   883   /* (B.1) Constructor name... */
   817   s4o.print(s4o.indent_spaces + "void ");
   884   s4o.print(s4o.indent_spaces + "void ");
   818   symbol->program_type_name->accept(*this);
   885   symbol->program_type_name->accept(*this);
   819   s4o.print(FB_INIT_SUFFIX);
   886   s4o.print(FB_INIT_SUFFIX);
   821 
   888 
   822   /* first and only parameter is a pointer to the data */
   889   /* first and only parameter is a pointer to the data */
   823   symbol->program_type_name->accept(*this);
   890   symbol->program_type_name->accept(*this);
   824   s4o.print(" *");
   891   s4o.print(" *");
   825   s4o.print(FB_FUNCTION_PARAM);
   892   s4o.print(FB_FUNCTION_PARAM);
   826   s4o.print(") {\n");
   893   s4o.print(", BOOL retain) {\n");
   827   s4o.indent_right();
   894   s4o.indent_right();
   828 
   895 
   829   /* (B.2) Member initializations... */
   896   /* (B.2) Member initializations... */
   830   s4o.print(s4o.indent_spaces);
   897   s4o.print(s4o.indent_spaces);
   831   vardecl = new generate_c_vardecl_c(&s4o,
   898   vardecl = new generate_c_vardecl_c(&s4o,
   837                                      generate_c_vardecl_c::located_vt  |
   904                                      generate_c_vardecl_c::located_vt  |
   838                                      generate_c_vardecl_c::external_vt);
   905                                      generate_c_vardecl_c::external_vt);
   839   vardecl->print(symbol->var_declarations, NULL,  FB_FUNCTION_PARAM"->");
   906   vardecl->print(symbol->var_declarations, NULL,  FB_FUNCTION_PARAM"->");
   840   delete vardecl;
   907   delete vardecl;
   841   s4o.print("\n");
   908   s4o.print("\n");
       
   909 
       
   910   sfcdecl = new generate_c_sfcdecl_c(&s4o, symbol, FB_FUNCTION_PARAM"->");
       
   911 
   842   /* (B.3) Generate private internal variables for SFC */
   912   /* (B.3) Generate private internal variables for SFC */
   843   sfcdecl = new generate_c_sfcdecl_c(&s4o, generate_c_sfcdecl_c::sfcinit_sd);
   913   sfcdecl->generate(symbol->function_block_body, generate_c_sfcdecl_c::sfcinit_sd);
   844   sfcdecl->print(symbol->function_block_body,FB_FUNCTION_PARAM"->");
       
   845   delete sfcdecl;
       
   846 
   914 
   847   s4o.indent_left();
   915   s4o.indent_left();
   848   s4o.print(s4o.indent_spaces + "}\n\n");
   916   s4o.print(s4o.indent_spaces + "}\n\n");
   849 
   917 
   850   /* (C) Function with PROGRAM body */
   918   /* (C) Function with PROGRAM body */
   851   /* (C.1) Step definitions */
   919   /* (C.1) Step definitions */
   852   sfcdecl = new generate_c_sfcdecl_c(&s4o, generate_c_sfcdecl_c::stepdef_sd);
   920   sfcdecl->generate(symbol->function_block_body, generate_c_sfcdecl_c::stepdef_sd);
   853   sfcdecl->print(symbol->function_block_body);
       
   854   delete sfcdecl;
       
   855   
   921   
   856   /* (C.2) Action definitions */
   922   /* (C.2) Action definitions */
   857   sfcdecl = new generate_c_sfcdecl_c(&s4o, generate_c_sfcdecl_c::actiondef_sd);
   923   sfcdecl->generate(symbol->function_block_body, generate_c_sfcdecl_c::actiondef_sd);
   858   sfcdecl->print(symbol->function_block_body);
       
   859   delete sfcdecl;
       
   860 
   924 
   861   /* (C.3) Function declaration */
   925   /* (C.3) Function declaration */
   862   s4o.print("// Code part\n");
   926   s4o.print("// Code part\n");
   863   /* function interface */
   927   /* function interface */
   864   s4o.print("void ");
   928   s4o.print("void ");
   881   vardecl->print(symbol->var_declarations, NULL,  FB_FUNCTION_PARAM"->");
   945   vardecl->print(symbol->var_declarations, NULL,  FB_FUNCTION_PARAM"->");
   882   delete vardecl;
   946   delete vardecl;
   883   s4o.print("\n");
   947   s4o.print("\n");
   884 
   948 
   885   /* (C.5) Function code */
   949   /* (C.5) Function code */
   886   generate_c_SFC_IL_ST_c generate_c_code(&s4o, symbol, FB_FUNCTION_PARAM"->");
   950   generate_c_SFC_IL_ST_c generate_c_code(&s4o, symbol->program_type_name, symbol, FB_FUNCTION_PARAM"->");
   887   symbol->function_block_body->accept(generate_c_code);
   951   symbol->function_block_body->accept(generate_c_code);
   888   s4o.indent_left();
   952   s4o.indent_left();
   889   s4o.print(s4o.indent_spaces + "} // ");
   953   s4o.print(s4o.indent_spaces + "} // ");
   890   symbol->program_type_name->accept(*this);
   954   symbol->program_type_name->accept(*this);
   891   s4o.print(FB_FUNCTION_SUFFIX);
   955   s4o.print(FB_FUNCTION_SUFFIX);
   892   s4o.print(s4o.indent_spaces + "() \n\n");
   956   s4o.print(s4o.indent_spaces + "() \n\n");
   893 
   957 
   894   /* (C.6) Step undefinitions */
   958   /* (C.6) Step undefinitions */
   895   sfcdecl = new generate_c_sfcdecl_c(&s4o, generate_c_sfcdecl_c::stepundef_sd);
   959   sfcdecl->generate(symbol->function_block_body, generate_c_sfcdecl_c::stepundef_sd);
   896   sfcdecl->print(symbol->function_block_body);
   960   
       
   961   /* (C.7) Action undefinitions */
       
   962   sfcdecl->generate(symbol->function_block_body, generate_c_sfcdecl_c::actionundef_sd);
       
   963   
   897   delete sfcdecl;
   964   delete sfcdecl;
   898   
   965 
   899   /* (C.7) Action undefinitions */
       
   900   sfcdecl = new generate_c_sfcdecl_c(&s4o, generate_c_sfcdecl_c::actionundef_sd);
       
   901   sfcdecl->print(symbol->function_block_body);
       
   902   delete sfcdecl;
       
   903   
       
   904   s4o.indent_left();
   966   s4o.indent_left();
   905   s4o.print("\n\n\n\n");
   967   s4o.print("\n\n\n\n");
   906 
   968 
   907   return NULL;
   969   return NULL;
   908 }
   970 }
   960   s4o.print("/* Editing this file is not recommended... */\n");
  1022   s4o.print("/* Editing this file is not recommended... */\n");
   961   s4o.print("/*******************************************/\n\n");
  1023   s4o.print("/*******************************************/\n\n");
   962   s4o.print("#include \"iec_std_lib.h\"\n\n");
  1024   s4o.print("#include \"iec_std_lib.h\"\n\n");
   963   s4o.print("#include \"accessor.h\"\n\n"); 
  1025   s4o.print("#include \"accessor.h\"\n\n"); 
   964   
  1026   
       
  1027   s4o.print("#include \"accessor.h\"\n\n");
       
  1028 
   965   /* (A) configuration declaration... */
  1029   /* (A) configuration declaration... */
   966   /* (A.1) configuration name in comment */
  1030   /* (A.1) configuration name in comment */
   967   s4o.print("// CONFIGURATION ");
  1031   s4o.print("// CONFIGURATION ");
   968   symbol->configuration_name->accept(*this);
  1032   symbol->configuration_name->accept(*this);
   969   s4o.print("\n");
  1033   s4o.print("\n");
   985   /* (B.2) Initialisation function name... */
  1049   /* (B.2) Initialisation function name... */
   986   s4o.print(s4o.indent_spaces + "void config");
  1050   s4o.print(s4o.indent_spaces + "void config");
   987   s4o.print(FB_INIT_SUFFIX);
  1051   s4o.print(FB_INIT_SUFFIX);
   988   s4o.print("(void) {\n");
  1052   s4o.print("(void) {\n");
   989   s4o.indent_right();
  1053   s4o.indent_right();
       
  1054   s4o.print(s4o.indent_spaces);
       
  1055   s4o.print("BOOL retain = 0;\n");
   990   
  1056   
   991   /* (B.3) Global variables initializations... */
  1057   /* (B.3) Global variables initializations... */
   992   s4o.print(s4o.indent_spaces);
  1058   s4o.print(s4o.indent_spaces);
   993   vardecl = new generate_c_vardecl_c(&s4o,
  1059   vardecl = new generate_c_vardecl_c(&s4o,
   994                                      generate_c_vardecl_c::constructorinit_vf,
  1060                                      generate_c_vardecl_c::constructorinit_vf,
  1012   s4o.print("\n");
  1078   s4o.print("\n");
  1013 
  1079 
  1014   /* (C.2) Run function name... */
  1080   /* (C.2) Run function name... */
  1015   s4o.print(s4o.indent_spaces + "void config");
  1081   s4o.print(s4o.indent_spaces + "void config");
  1016   s4o.print(FB_RUN_SUFFIX);
  1082   s4o.print(FB_RUN_SUFFIX);
  1017   s4o.print("(int tick) {\n");
  1083   s4o.print("(unsigned long tick) {\n");
  1018   s4o.indent_right();
  1084   s4o.indent_right();
  1019 
  1085 
  1020   /* (C.3) Resources initializations... */
  1086   /* (C.3) Resources initializations... */
  1021   wanted_declaretype = rundeclare_dt;
  1087   wanted_declaretype = rundeclare_dt;
  1022   symbol->resource_declarations->accept(*this);
  1088   symbol->resource_declarations->accept(*this);
  1036       s4o.print(FB_INIT_SUFFIX);
  1102       s4o.print(FB_INIT_SUFFIX);
  1037       s4o.print("(void);\n");
  1103       s4o.print("(void);\n");
  1038     }
  1104     }
  1039     else {
  1105     else {
  1040       s4o.print(FB_RUN_SUFFIX);
  1106       s4o.print(FB_RUN_SUFFIX);
  1041       s4o.print("(int tick);\n");
  1107       s4o.print("(unsigned long tick);\n");
  1042     }
  1108     }
  1043   }
  1109   }
  1044   if (wanted_declaretype == initdeclare_dt || wanted_declaretype == rundeclare_dt) {
  1110   if (wanted_declaretype == initdeclare_dt || wanted_declaretype == rundeclare_dt) {
  1045     s4o.print(s4o.indent_spaces);
  1111     s4o.print(s4o.indent_spaces);
  1046     symbol->resource_name->accept(*this);
  1112     symbol->resource_name->accept(*this);
  1063       s4o.print(FB_INIT_SUFFIX);
  1129       s4o.print(FB_INIT_SUFFIX);
  1064       s4o.print("(void);\n");
  1130       s4o.print("(void);\n");
  1065     }
  1131     }
  1066     else {
  1132     else {
  1067       s4o.print(FB_RUN_SUFFIX);
  1133       s4o.print(FB_RUN_SUFFIX);
  1068       s4o.print("(int tick);\n");
  1134       s4o.print("(unsigned long tick);\n");
  1069     }
  1135     }
  1070   }
  1136   }
  1071   if (wanted_declaretype == initdeclare_dt || wanted_declaretype == rundeclare_dt) {
  1137   if (wanted_declaretype == initdeclare_dt || wanted_declaretype == rundeclare_dt) {
  1072     s4o.print(s4o.indent_spaces + "RESOURCE");
  1138     s4o.print(s4o.indent_spaces + "RESOURCE");
  1073     if (wanted_declaretype == initdeclare_dt) {
  1139     if (wanted_declaretype == initdeclare_dt) {
  1137       send_at
  1203       send_at
  1138     } assigntype_t;
  1204     } assigntype_t;
  1139 
  1205 
  1140     assigntype_t wanted_assigntype;
  1206     assigntype_t wanted_assigntype;
  1141 
  1207 
       
  1208     /* the qualifier of variables that need to be processed... */
       
  1209     static const unsigned int none_vq        = 0x0000;
       
  1210     static const unsigned int constant_vq    = 0x0001;  // CONSTANT
       
  1211     static const unsigned int retain_vq      = 0x0002;  // RETAIN
       
  1212     static const unsigned int non_retain_vq  = 0x0004;  // NON_RETAIN
       
  1213 
       
  1214     /* variable used to store the qualifier of program currently being processed... */
       
  1215     unsigned int current_varqualifier;
       
  1216 
       
  1217     void *print_retain(void) {
       
  1218 	  s4o.print(",");
       
  1219       switch (current_varqualifier) {
       
  1220 		case retain_vq:
       
  1221           s4o.print("1");
       
  1222           break;
       
  1223         case non_retain_vq:
       
  1224           s4o.print("0");
       
  1225           break;
       
  1226 		default:
       
  1227 		  s4o.print("retain");
       
  1228 		  break;
       
  1229       }
       
  1230       return NULL;
       
  1231     }
       
  1232 
       
  1233     /******************************************/
       
  1234     /* B 1.4.3 - Declaration & Initialisation */
       
  1235     /******************************************/
       
  1236 
       
  1237     void *visit(constant_option_c *symbol) {
       
  1238       current_varqualifier = constant_vq;
       
  1239       return NULL;
       
  1240     }
       
  1241 
       
  1242     void *visit(retain_option_c *symbol) {
       
  1243       current_varqualifier = retain_vq;
       
  1244       return NULL;
       
  1245     }
       
  1246 
       
  1247     void *visit(non_retain_option_c *symbol) {
       
  1248       current_varqualifier = non_retain_vq;
       
  1249       return NULL;
       
  1250     }
       
  1251 
  1142 /********************************/
  1252 /********************************/
  1143 /* B 1.7 Configuration elements */
  1253 /* B 1.7 Configuration elements */
  1144 /********************************/
  1254 /********************************/
  1145 
  1255 
  1146 /*
  1256 /*
  1180       /* (A.1) resource name in comment */
  1290       /* (A.1) resource name in comment */
  1181       s4o.print("// RESOURCE ");
  1291       s4o.print("// RESOURCE ");
  1182       current_resource_name->accept(*this);
  1292       current_resource_name->accept(*this);
  1183       s4o.print("\n\n");
  1293       s4o.print("\n\n");
  1184       
  1294       
  1185       s4o.print("extern int common_ticktime__;\n\n");
  1295       s4o.print("extern unsigned long long common_ticktime__;\n\n");
  1186        
  1296 
       
  1297       s4o.print("#include \"accessor.h\"\n\n");
       
  1298 
  1187       /* (A.2) Global variables... */
  1299       /* (A.2) Global variables... */
  1188       if (current_global_vars != NULL) {
  1300       if (current_global_vars != NULL) {
  1189         vardecl = new generate_c_vardecl_c(&s4o,
  1301         vardecl = new generate_c_vardecl_c(&s4o,
  1190                                            generate_c_vardecl_c::local_vf,
  1302                                            generate_c_vardecl_c::local_vf,
  1191                                            generate_c_vardecl_c::global_vt,
  1303                                            generate_c_vardecl_c::global_vt,
  1214       s4o.print("void ");
  1326       s4o.print("void ");
  1215       current_resource_name->accept(*this);
  1327       current_resource_name->accept(*this);
  1216       s4o.print(FB_INIT_SUFFIX);
  1328       s4o.print(FB_INIT_SUFFIX);
  1217       s4o.print("(void) {\n");
  1329       s4o.print("(void) {\n");
  1218       s4o.indent_right();
  1330       s4o.indent_right();
       
  1331       s4o.print(s4o.indent_spaces);
       
  1332       s4o.print("BOOL retain = 0;\n");
  1219       
  1333       
  1220       /* (B.2) Global variables initialisations... */
  1334       /* (B.2) Global variables initialisations... */
  1221       if (current_global_vars != NULL) {
  1335       if (current_global_vars != NULL) {
  1222         s4o.print(s4o.indent_spaces);
  1336         s4o.print(s4o.indent_spaces);
  1223         vardecl = new generate_c_vardecl_c(&s4o,
  1337         vardecl = new generate_c_vardecl_c(&s4o,
  1224                                            generate_c_vardecl_c::constructorinit_vf,
  1338                                            generate_c_vardecl_c::constructorinit_vf,
  1225                                            generate_c_vardecl_c::global_vt);
  1339                                            generate_c_vardecl_c::global_vt,
       
  1340                                            current_resource_name);
  1226         vardecl->print(current_global_vars);
  1341         vardecl->print(current_global_vars);
  1227         delete vardecl;
  1342         delete vardecl;
  1228       }
  1343       }
  1229       s4o.print("\n");
  1344       s4o.print("\n");
  1230       
  1345       
  1242       /* (C) Resource run function... */
  1357       /* (C) Resource run function... */
  1243       /* (C.1) Run function name... */
  1358       /* (C.1) Run function name... */
  1244       s4o.print("void ");
  1359       s4o.print("void ");
  1245       current_resource_name->accept(*this);
  1360       current_resource_name->accept(*this);
  1246       s4o.print(FB_RUN_SUFFIX);
  1361       s4o.print(FB_RUN_SUFFIX);
  1247       s4o.print("(int tick) {\n");
  1362       s4o.print("(unsigned long tick) {\n");
  1248       s4o.indent_right();
  1363       s4o.indent_right();
  1249       
  1364       
  1250       wanted_declaretype = run_dt;
  1365       wanted_declaretype = run_dt;
  1251       
  1366       
  1252       /* (C.2) Task management... */
  1367       /* (C.2) Task management... */
  1283           s4o.print("__");
  1398           s4o.print("__");
  1284           symbol->program_name->accept(*this);
  1399           symbol->program_name->accept(*this);
  1285           s4o.print("\n");
  1400           s4o.print("\n");
  1286           break;
  1401           break;
  1287         case init_dt:
  1402         case init_dt:
       
  1403           if (symbol->retain_option != NULL)
       
  1404         	symbol->retain_option->accept(*this);
  1288           s4o.print(s4o.indent_spaces);
  1405           s4o.print(s4o.indent_spaces);
  1289           symbol->program_type_name->accept(*this);
  1406           symbol->program_type_name->accept(*this);
  1290           s4o.print(FB_INIT_SUFFIX);
  1407           s4o.print(FB_INIT_SUFFIX);
  1291           s4o.print("(&");
  1408           s4o.print("(&");
  1292           symbol->program_name->accept(*this);
  1409           symbol->program_name->accept(*this);
       
  1410           print_retain();
  1293           s4o.print(");\n");
  1411           s4o.print(");\n");
  1294           break;
  1412           break;
  1295         case run_dt:
  1413         case run_dt:
  1296           current_program_name = ((identifier_c*)(symbol->program_name))->value;
  1414           current_program_name = ((identifier_c*)(symbol->program_name))->value;
  1297           if (symbol->task_name != NULL) {
  1415           if (symbol->task_name != NULL) {
  1370           if (symbol->single_data_source != NULL) {
  1488           if (symbol->single_data_source != NULL) {
  1371             s4o.print(s4o.indent_spaces + "R_TRIG");
  1489             s4o.print(s4o.indent_spaces + "R_TRIG");
  1372             s4o.print(FB_INIT_SUFFIX);
  1490             s4o.print(FB_INIT_SUFFIX);
  1373             s4o.print("(&");
  1491             s4o.print("(&");
  1374             current_task_name->accept(*this);
  1492             current_task_name->accept(*this);
  1375             s4o.print("_R_TRIG);\n");
  1493             s4o.print("_R_TRIG, retain);\n");
  1376           }
  1494           }
  1377           break;
  1495           break;
  1378         case run_dt:
  1496         case run_dt:
  1379           if (symbol->single_data_source != NULL) {
  1497           if (symbol->single_data_source != NULL) {
  1380             symbol_c *config_var_decl = NULL;
  1498             symbol_c *config_var_decl = NULL;
  1381             symbol_c *res_var_decl = NULL;
  1499             symbol_c *res_var_decl = NULL;
       
  1500             unsigned int vartype;
  1382             symbol_c *current_var_reference = ((global_var_reference_c *)(symbol->single_data_source))->global_var_name;
  1501             symbol_c *current_var_reference = ((global_var_reference_c *)(symbol->single_data_source))->global_var_name;
  1383             res_var_decl = search_resource_instance->get_decl(current_var_reference);
  1502             res_var_decl = search_resource_instance->get_decl(current_var_reference);
  1384             if (res_var_decl == NULL) {
  1503             if (res_var_decl == NULL) {
  1385               config_var_decl = search_config_instance->get_decl(current_var_reference);
  1504               config_var_decl = search_config_instance->get_decl(current_var_reference);
  1386               if (config_var_decl == NULL)
  1505               if (config_var_decl == NULL)
  1387                 ERROR;
  1506                 ERROR;
       
  1507               vartype = search_config_instance->get_vartype();
  1388               s4o.print(s4o.indent_spaces + "{extern ");
  1508               s4o.print(s4o.indent_spaces + "{extern ");
  1389               config_var_decl->accept(*this);
  1509               config_var_decl->accept(*this);
  1390               s4o.print(" *");
  1510               s4o.print(" *");
  1391               symbol->single_data_source->accept(*this);
  1511               symbol->single_data_source->accept(*this);
  1392               s4o.print("; ");
  1512               s4o.print("; ");
  1393             }
  1513             }
  1394             else
  1514             else {
       
  1515               vartype = search_resource_instance->get_vartype();
  1395               s4o.print(s4o.indent_spaces);
  1516               s4o.print(s4o.indent_spaces);
       
  1517             }
       
  1518             s4o.print(SET_VAR);
       
  1519             s4o.print("(");
  1396             current_task_name->accept(*this);
  1520             current_task_name->accept(*this);
  1397             s4o.print("_R_TRIG.CLK = *");
  1521             s4o.print("_R_TRIG.CLK, *__GET_GLOBAL_");
  1398             symbol->single_data_source->accept(*this);
  1522             symbol->single_data_source->accept(*this);
  1399             s4o.print(";");
  1523             s4o.print("());");
  1400             if (config_var_decl != NULL)
  1524             if (config_var_decl != NULL)
  1401               s4o.print("}");
  1525               s4o.print("}");
  1402             s4o.print("\n");
  1526             s4o.print("\n");
  1403             s4o.print(s4o.indent_spaces + "R_TRIG");
  1527             s4o.print(s4o.indent_spaces + "R_TRIG");
  1404             s4o.print(FB_FUNCTION_SUFFIX);
  1528             s4o.print(FB_FUNCTION_SUFFIX);
  1406             current_task_name->accept(*this);
  1530             current_task_name->accept(*this);
  1407             s4o.print("_R_TRIG);\n");
  1531             s4o.print("_R_TRIG);\n");
  1408             s4o.print(s4o.indent_spaces);
  1532             s4o.print(s4o.indent_spaces);
  1409             current_task_name->accept(*this);
  1533             current_task_name->accept(*this);
  1410             s4o.print(" = ");
  1534             s4o.print(" = ");
       
  1535             s4o.print(GET_VAR);
       
  1536             s4o.print("(");
  1411             current_task_name->accept(*this);
  1537             current_task_name->accept(*this);
  1412             s4o.print("_R_TRIG.Q");
  1538             s4o.print("_R_TRIG.Q)");
  1413           }
  1539           }
  1414           else {
  1540           else {
  1415             s4o.print(s4o.indent_spaces);
  1541             s4o.print(s4o.indent_spaces);
  1416             current_task_name->accept(*this);
  1542             current_task_name->accept(*this);
  1417             s4o.print(" = ");
  1543             s4o.print(" = ");
  1531     symbol_c *current_configuration;
  1657     symbol_c *current_configuration;
  1532 
  1658 
  1533     const char *current_name;
  1659     const char *current_name;
  1534     const char *current_builddir;
  1660     const char *current_builddir;
  1535 
  1661 
  1536     unsigned long common_ticktime;
  1662     unsigned long long common_ticktime;
  1537 
  1663 
  1538   public:
  1664   public:
  1539     generate_c_c(stage4out_c *s4o_ptr, const char *builddir): 
  1665     generate_c_c(stage4out_c *s4o_ptr, const char *builddir): 
  1540             s4o(*s4o_ptr),
  1666             s4o(*s4o_ptr),
  1541             pous_s4o(builddir, "POUS", "c"),
  1667             pous_s4o(builddir, "POUS", "c"),
  1551 
  1677 
  1552 /***************************/
  1678 /***************************/
  1553 /* B 0 - Programming Model */
  1679 /* B 0 - Programming Model */
  1554 /***************************/
  1680 /***************************/
  1555     void *visit(library_c *symbol) {
  1681     void *visit(library_c *symbol) {
  1556       pous_incl_s4o.print("#ifndef __POUS_H\n#define __POUS_H\n\n");
  1682       pous_incl_s4o.print("#ifndef __POUS_H\n#define __POUS_H\n\n#include \"accessor.h\"\n\n");
  1557       for(int i = 0; i < symbol->n; i++) {
  1683       for(int i = 0; i < symbol->n; i++) {
  1558         symbol->elements[i]->accept(*this);
  1684         symbol->elements[i]->accept(*this);
  1559       }
  1685       }
  1560       pous_incl_s4o.print("#endif //__POUS_H\n");
  1686       pous_incl_s4o.print("#endif //__POUS_H\n");
  1561       
  1687       
  1629       
  1755       
  1630       current_configuration = symbol;
  1756       current_configuration = symbol;
  1631       
  1757       
  1632       calculate_common_ticktime_c calculate_common_ticktime;
  1758       calculate_common_ticktime_c calculate_common_ticktime;
  1633       symbol->accept(calculate_common_ticktime);
  1759       symbol->accept(calculate_common_ticktime);
  1634       common_ticktime = calculate_common_ticktime.get_ticktime();
  1760       common_ticktime = calculate_common_ticktime.get_common_ticktime();
       
  1761       if (common_ticktime == 0) {
       
  1762         fprintf(stderr, "\nYou must at least define a periodic task to set cycle period!");
       
  1763         ERROR;
       
  1764       }
  1635       
  1765       
  1636       symbol->configuration_name->accept(*this);
  1766       symbol->configuration_name->accept(*this);
  1637       stage4out_c config_s4o(current_builddir, current_name, "c");
  1767       stage4out_c config_s4o(current_builddir, current_name, "c");
  1638       generate_c_config_c generate_c_config(&config_s4o);
  1768       generate_c_config_c generate_c_config(&config_s4o);
  1639       symbol->accept(generate_c_config);
  1769       symbol->accept(generate_c_config);
  1640         
  1770         
  1641       config_s4o.print("int common_ticktime__ = ");
  1771       config_s4o.print("unsigned long long common_ticktime__ = ");
  1642       config_s4o.print_integer((int)(common_ticktime / 1000000));
  1772       config_s4o.print_long_long_integer(common_ticktime);
  1643       config_s4o.print("; /*ms*/\n");
  1773       config_s4o.print("; /*ns*/\n");
       
  1774       config_s4o.print("unsigned long greatest_tick_count__ = ");
       
  1775       config_s4o.print_long_integer(calculate_common_ticktime.get_greatest_tick_count());
       
  1776       config_s4o.print("; /*tick*/\n");
  1644       
  1777       
  1645       symbol->resource_declarations->accept(*this);
  1778       symbol->resource_declarations->accept(*this);
  1646 
  1779 
  1647       current_configuration = NULL;
  1780       current_configuration = NULL;
  1648       
  1781