stage4/generate_cc/generate_cc.cc
changeset 28 5b170c9ce134
parent 27 667721cf52c5
child 29 3ba8ef691003
equal deleted inserted replaced
27:667721cf52c5 28:5b170c9ce134
   102 
   102 
   103 /* returns 0 if the names are equal!! */
   103 /* returns 0 if the names are equal!! */
   104 /* NOTE: it must ignore case!! */
   104 /* NOTE: it must ignore case!! */
   105 static int compare_identifiers(symbol_c *ident1, symbol_c *ident2) {
   105 static int compare_identifiers(symbol_c *ident1, symbol_c *ident2) {
   106 
   106 
   107   identifier_c *name1 = dynamic_cast<identifier_c *>(ident1);
   107   token_c *name1 = dynamic_cast<token_c *>(ident1);
   108   identifier_c *name2 = dynamic_cast<identifier_c *>(ident2);
   108   token_c *name2 = dynamic_cast<token_c *>(ident2);
   109 
   109   
   110   if ((name1 == NULL) || (name2 == NULL))
   110   if ((name1 == NULL) || (name2 == NULL))
   111     /* invalid identifiers... */
   111     /* invalid identifiers... */
   112     return -1;
   112     return -1;
   113 
   113 
   114   if (strcasecmp(name1->value, name2->value) == 0)
   114   if (strcasecmp(name1->value, name2->value) == 0)
   148 #define FB_FUNCTION_SUFFIX "_body__"
   148 #define FB_FUNCTION_SUFFIX "_body__"
   149 
   149 
   150 /* Idem as body, but for initializer FB function */
   150 /* Idem as body, but for initializer FB function */
   151 #define FB_INIT_SUFFIX "_init__"
   151 #define FB_INIT_SUFFIX "_init__"
   152 
   152 
       
   153 /* Idem as body, but for run CONFIG and RESOURCE function */
       
   154 #define FB_RUN_SUFFIX "_run__"
       
   155 
   153 /* The FB body function is passed as the only parameter a pointer to the FB data
   156 /* The FB body function is passed as the only parameter a pointer to the FB data
   154  * structure instance. The name of this parameter is given by the following constant.
   157  * structure instance. The name of this parameter is given by the following constant.
   155  * In order not to clash with any variable in the IL and ST source codem the
   158  * In order not to clash with any variable in the IL and ST source codem the
   156  * following constant should contain a double underscore, which is not allowed
   159  * following constant should contain a double underscore, which is not allowed
   157  * in IL and ST.
   160  * in IL and ST.
   163 
   166 
   164 #define FB_FUNCTION_PARAM "data__"
   167 #define FB_FUNCTION_PARAM "data__"
   165 
   168 
   166 
   169 
   167 #define SFC_STEP_ACTION_PREFIX "__SFC_"
   170 #define SFC_STEP_ACTION_PREFIX "__SFC_"
   168 
       
   169 
   171 
   170 /***********************************************************************/
   172 /***********************************************************************/
   171 /***********************************************************************/
   173 /***********************************************************************/
   172 /***********************************************************************/
   174 /***********************************************************************/
   173 /***********************************************************************/
   175 /***********************************************************************/
   211 #include "generate_cc_st.cc"
   213 #include "generate_cc_st.cc"
   212 #include "generate_cc_il.cc"
   214 #include "generate_cc_il.cc"
   213 
   215 
   214 #include "generate_cc.hh"
   216 #include "generate_cc.hh"
   215 
   217 
   216 
   218 /***********************************************************************/
       
   219 /***********************************************************************/
       
   220 /***********************************************************************/
       
   221 /***********************************************************************/
       
   222 
       
   223 #define MILLISECOND 1000000
       
   224 #define SECOND 1000 * MILLISECOND
       
   225 
       
   226 /* A helper class that knows how to generate code for both the IL and ST languages... */
       
   227 class calculate_time_c: public iterator_visitor_c {
       
   228   private:
       
   229     unsigned long time;
       
   230     float current_value;
       
   231   
       
   232   public:
       
   233     calculate_time_c(void){time = 0;};
       
   234     
       
   235     unsigned long get_time(void) {return time;};
       
   236 
       
   237     void *get_integer_value(token_c *token) {
       
   238       std::string str = "";
       
   239       for (unsigned int i = 0; i < strlen(token->value); i++)
       
   240         if (token->value[i] != '_')
       
   241           str += token->value[i];
       
   242       current_value = atof(str.c_str());
       
   243       return NULL;
       
   244     }
       
   245 
       
   246     void *get_float_value(token_c *token) {
       
   247       current_value = atof(token->value);
       
   248       return NULL;
       
   249     }
       
   250 
       
   251 /******************************/
       
   252 /* B 1.2.1 - Numeric Literals */
       
   253 /******************************/
       
   254 
       
   255     void *visit(integer_c *symbol) {return get_integer_value(symbol);}
       
   256     
       
   257 /************************/
       
   258 /* B 1.2.3.1 - Duration */
       
   259 /************************/
       
   260   
       
   261     /* SYM_REF2(duration_c, neg, interval) */
       
   262     void *visit(duration_c *symbol) {
       
   263       if (symbol->neg != NULL)
       
   264         ERROR;
       
   265       symbol->interval->accept(*this);
       
   266       return NULL;
       
   267     }
       
   268     
       
   269     /* SYM_TOKEN(fixed_point_c) */
       
   270     void *visit(fixed_point_c *symbol) {return get_float_value(symbol);}
       
   271     
       
   272     /* SYM_REF2(days_c, days, hours) */
       
   273     void *visit(days_c *symbol) {
       
   274       if (symbol->hours)
       
   275         symbol->hours->accept(*this);
       
   276       symbol->days->accept(*this);
       
   277       time += (unsigned long)(current_value * 24 * 3600 * SECOND);
       
   278       return NULL;
       
   279     }
       
   280     
       
   281     /* SYM_REF2(hours_c, hours, minutes) */
       
   282     void *visit(hours_c *symbol) {
       
   283       if (symbol->minutes)
       
   284         symbol->minutes->accept(*this);
       
   285       symbol->hours->accept(*this);
       
   286       time += (unsigned long)(current_value * 3600 * SECOND);
       
   287       return NULL;
       
   288     }
       
   289     
       
   290     /* SYM_REF2(minutes_c, minutes, seconds) */
       
   291     void *visit(minutes_c *symbol) {
       
   292       if (symbol->seconds)
       
   293         symbol->seconds->accept(*this);
       
   294       symbol->minutes->accept(*this);
       
   295       time += (unsigned long)(current_value * 60 * SECOND);
       
   296       return NULL;
       
   297     }
       
   298     
       
   299     /* SYM_REF2(seconds_c, seconds, milliseconds) */
       
   300     void *visit(seconds_c *symbol) {
       
   301       if (symbol->milliseconds)
       
   302         symbol->milliseconds->accept(*this);
       
   303       symbol->seconds->accept(*this);
       
   304       time += (unsigned long)(current_value * SECOND);
       
   305       return NULL;
       
   306     }
       
   307     
       
   308     /* SYM_REF2(milliseconds_c, milliseconds, unused) */
       
   309     void *visit(milliseconds_c *symbol) {
       
   310       symbol->milliseconds->accept(*this);
       
   311       time += (unsigned long)(current_value * MILLISECOND);
       
   312       return NULL;
       
   313     }
       
   314 };
       
   315 
       
   316 /***********************************************************************/
       
   317 /***********************************************************************/
       
   318 /***********************************************************************/
       
   319 /***********************************************************************/
       
   320 
       
   321 class calculate_common_ticktime_c: public iterator_visitor_c {
       
   322   private:
       
   323     unsigned long common_ticktime;
       
   324     
       
   325   public:
       
   326     calculate_common_ticktime_c(void){common_ticktime = 0;}
       
   327     
       
   328     unsigned long euclide(unsigned long a, unsigned long b) {
       
   329       unsigned long c = a % b;
       
   330       if (c == 0)
       
   331         return b;
       
   332       else
       
   333         return euclide(b, c);
       
   334     }
       
   335     
       
   336     void update_ticktime(unsigned long time) {
       
   337       if (common_ticktime == 0)
       
   338         common_ticktime = time;
       
   339       else if (time > common_ticktime)
       
   340         common_ticktime = euclide(time, common_ticktime);
       
   341       else
       
   342         common_ticktime = euclide(common_ticktime, time);
       
   343     }
       
   344 
       
   345     unsigned long get_ticktime(void) {
       
   346       return common_ticktime;
       
   347     }
       
   348 
       
   349 /*  TASK task_name task_initialization */
       
   350 //SYM_REF2(task_configuration_c, task_name, task_initialization)  
       
   351     void *visit(task_initialization_c *symbol) {
       
   352       calculate_time_c calculate_time;
       
   353       unsigned long time = 0;
       
   354       if (symbol->interval_data_source != NULL) {
       
   355         symbol->interval_data_source->accept(calculate_time);
       
   356         time = calculate_time.get_time();
       
   357       }
       
   358       if (time > 0)
       
   359         update_ticktime(time);
       
   360       return NULL;
       
   361     }
       
   362 };    
   217 
   363 
   218 /***********************************************************************/
   364 /***********************************************************************/
   219 /***********************************************************************/
   365 /***********************************************************************/
   220 /***********************************************************************/
   366 /***********************************************************************/
   221 /***********************************************************************/
   367 /***********************************************************************/
   526   s4o.print("\n");
   672   s4o.print("\n");
   527   /* (A.3) Private internal variables */
   673   /* (A.3) Private internal variables */
   528   s4o.print(s4o.indent_spaces + "// FB private variables - TEMP, private and located variables\n");
   674   s4o.print(s4o.indent_spaces + "// FB private variables - TEMP, private and located variables\n");
   529   vardecl = new generate_cc_vardecl_c(&s4o,
   675   vardecl = new generate_cc_vardecl_c(&s4o,
   530   				      generate_cc_vardecl_c::local_vf,
   676   				      generate_cc_vardecl_c::local_vf,
   531 				      generate_cc_vardecl_c::temp_vt |
   677 				        generate_cc_vardecl_c::temp_vt |
   532   				      generate_cc_vardecl_c::private_vt |
   678   				      generate_cc_vardecl_c::private_vt |
   533   				      generate_cc_vardecl_c::located_vt |
   679   				      generate_cc_vardecl_c::located_vt |
   534   				      generate_cc_vardecl_c::external_vt);
   680   				      generate_cc_vardecl_c::external_vt);
   535   vardecl->print(symbol->var_declarations);
   681   vardecl->print(symbol->var_declarations);
   536   delete vardecl;
   682   delete vardecl;
   563   				      generate_cc_vardecl_c::constructorinit_vf,
   709   				      generate_cc_vardecl_c::constructorinit_vf,
   564   				      generate_cc_vardecl_c::input_vt |
   710   				      generate_cc_vardecl_c::input_vt |
   565   				      generate_cc_vardecl_c::output_vt |
   711   				      generate_cc_vardecl_c::output_vt |
   566   				      generate_cc_vardecl_c::inoutput_vt |
   712   				      generate_cc_vardecl_c::inoutput_vt |
   567   				      generate_cc_vardecl_c::private_vt |
   713   				      generate_cc_vardecl_c::private_vt |
   568 				      generate_cc_vardecl_c::located_vt |
   714 				        generate_cc_vardecl_c::located_vt |
   569 				      generate_cc_vardecl_c::external_vt);
   715 				        generate_cc_vardecl_c::external_vt);
   570   vardecl->print(symbol->var_declarations, NULL,  FB_FUNCTION_PARAM"->");
   716   vardecl->print(symbol->var_declarations, NULL,  FB_FUNCTION_PARAM"->");
   571   delete vardecl;
   717   delete vardecl;
   572   s4o.indent_left();
   718   s4o.indent_left();
   573   s4o.print("\n" + s4o.indent_spaces + "}\n\n");
   719   s4o.print("\n" + s4o.indent_spaces + "}\n\n");
   574 
   720 
   674   s4o.indent_left();
   820   s4o.indent_left();
   675   s4o.print("} ");
   821   s4o.print("} ");
   676   symbol->program_type_name->accept(*this);
   822   symbol->program_type_name->accept(*this);
   677   s4o.print(";\n\n");
   823   s4o.print(";\n\n");
   678 
   824 
   679 
       
   680 
       
   681 
       
   682 
       
   683 
       
   684 
       
   685 
       
   686   /* (B) Constructor */
   825   /* (B) Constructor */
   687   /* (B.1) Constructor name... */
   826   /* (B.1) Constructor name... */
   688   s4o.print(s4o.indent_spaces + "void ");
   827   s4o.print(s4o.indent_spaces + "void ");
   689   symbol->program_type_name->accept(*this);
   828   symbol->program_type_name->accept(*this);
   690   s4o.print(FB_INIT_SUFFIX);
   829   s4o.print(FB_INIT_SUFFIX);
   710   vardecl->print(symbol->var_declarations, NULL,  FB_FUNCTION_PARAM"->");
   849   vardecl->print(symbol->var_declarations, NULL,  FB_FUNCTION_PARAM"->");
   711   delete vardecl;
   850   delete vardecl;
   712   s4o.indent_left();
   851   s4o.indent_left();
   713   s4o.print("\n" + s4o.indent_spaces + "}\n\n");
   852   s4o.print("\n" + s4o.indent_spaces + "}\n\n");
   714 
   853 
   715 
       
   716 
       
   717 
       
   718 
       
   719 
       
   720 
       
   721 
       
   722 
       
   723   /* (C) Function with PROGRAM body */
   854   /* (C) Function with PROGRAM body */
   724   /* (C.1) Step and Action definitions */
   855   /* (C.1) Step and Action definitions */
   725   generate_cc_sfcdecl_c generate_cc_sfcdecl(&s4o);
   856   generate_cc_sfcdecl_c generate_cc_sfcdecl(&s4o);
   726   symbol->function_block_body->accept(generate_cc_sfcdecl);
   857   symbol->function_block_body->accept(generate_cc_sfcdecl);
   727 
   858 
   779 /***********************************************************************/
   910 /***********************************************************************/
   780 /***********************************************************************/
   911 /***********************************************************************/
   781 
   912 
   782 class generate_cc_config_c: public generate_cc_typedecl_c {
   913 class generate_cc_config_c: public generate_cc_typedecl_c {
   783 
   914 
   784   public:
   915     public:
   785     generate_cc_config_c(stage4out_c *s4o_ptr)
   916     generate_cc_config_c(stage4out_c *s4o_ptr)
   786       : generate_cc_typedecl_c(s4o_ptr) {};
   917       : generate_cc_typedecl_c(s4o_ptr) {};
   787     virtual ~generate_cc_config_c(void) {}
   918     virtual ~generate_cc_config_c(void) {}
   788 
   919 
       
   920     typedef enum {
       
   921       initprotos_dt,
       
   922       initdeclare_dt,
       
   923       runprotos_dt,
       
   924       rundeclare_dt
       
   925     } declaretype_t;
       
   926 
       
   927     declaretype_t wanted_declaretype;
   789 
   928 
   790 /********************************/
   929 /********************************/
   791 /* B 1.7 Configuration elements */
   930 /* B 1.7 Configuration elements */
   792 /********************************/
   931 /********************************/
   793 
   932 
   803 */
   942 */
   804 /*
   943 /*
   805 SYM_REF6(configuration_declaration_c, configuration_name, global_var_declarations, resource_declarations, access_declarations, instance_specific_initializations, unused)
   944 SYM_REF6(configuration_declaration_c, configuration_name, global_var_declarations, resource_declarations, access_declarations, instance_specific_initializations, unused)
   806 */
   945 */
   807 void *visit(configuration_declaration_c *symbol) {
   946 void *visit(configuration_declaration_c *symbol) {
   808   static int configuration_count = 0;
       
   809   generate_cc_vardecl_c *vardecl;
   947   generate_cc_vardecl_c *vardecl;
   810   TRACE("configuration_declaration_c");
   948   
   811 
   949   /* (A) configuration declaration... */
   812   configuration_count++;
       
   813   if (configuration_count == 1) {
       
   814     /* the first configuration is the one we will use!! */
       
   815     s4o.print("#define __configuration_c ");
       
   816     symbol->configuration_name->accept(*this);
       
   817     s4o.print("\n" + s4o.indent_spaces);
       
   818   }
       
   819 
       
   820   /* (A) Class (__configuration) declaration... */
       
   821   /* (A.1) configuration name in comment */
   950   /* (A.1) configuration name in comment */
   822   s4o.print("// CONFIGURATION\n" + s4o.indent_spaces);
   951   s4o.print("// CONFIGURATION ");
   823   s4o.print("class ");
       
   824   symbol->configuration_name->accept(*this);
   952   symbol->configuration_name->accept(*this);
   825   s4o.print(" {\n");
   953   s4o.print("\n");
   826   s4o.indent_right();
   954   
   827 
   955   /* (A.2) Global variables */
   828   /* (A.2) Global variables
       
   829    *    AND
       
   830    * (A.3) Programs in the Configuration
       
   831    */
       
   832   /* Programs types are mapped onto classes,
       
   833    * and programs are then instantiated inside the configuration
       
   834    * as objects of the appropriate class!
       
   835    */
       
   836   s4o.print(s4o.indent_spaces + "private:\n");
       
   837   s4o.indent_right();
       
   838   vardecl = new generate_cc_vardecl_c(&s4o,
   956   vardecl = new generate_cc_vardecl_c(&s4o,
   839   				      generate_cc_vardecl_c::local_vf,
   957   				      generate_cc_vardecl_c::local_vf,
   840   				      generate_cc_vardecl_c::global_vt |
   958   				      generate_cc_vardecl_c::global_vt);
   841 				      generate_cc_vardecl_c::program_vt |
       
   842   				      generate_cc_vardecl_c::resource_vt);
       
   843   vardecl->print(symbol);
   959   vardecl->print(symbol);
   844   delete vardecl;
   960   delete vardecl;
   845   s4o.indent_left();
       
   846   s4o.print("\n");
   961   s4o.print("\n");
   847 
   962 
   848 
   963   /* (B) Initialisation Function */
   849 
   964   /* (B.1) Ressources initialisation protos... */
   850   /* (B) Constructor */
   965   wanted_declaretype = initprotos_dt;
   851   /* (B.1) Constructor name... */
   966   symbol->resource_declarations->accept(*this);
   852   s4o.print(s4o.indent_spaces + "public:\n");
   967   s4o.print("\n");
       
   968   
       
   969   /* (B.2) Initialisation function name... */
       
   970   s4o.print(s4o.indent_spaces + "void config");
       
   971   s4o.print(FB_INIT_SUFFIX);
       
   972   s4o.print("(void) {\n");
   853   s4o.indent_right();
   973   s4o.indent_right();
   854   s4o.print(s4o.indent_spaces);
   974   
   855   symbol->configuration_name->accept(*this);
   975   /* (B.3) Global variables initializations... */
   856   s4o.print("(void)\n");
       
   857 
       
   858   /* (B.2) Member initializations... */
       
   859   s4o.indent_right();
       
   860   s4o.print(s4o.indent_spaces);
   976   s4o.print(s4o.indent_spaces);
   861   vardecl = new generate_cc_vardecl_c(&s4o,
   977   vardecl = new generate_cc_vardecl_c(&s4o,
   862   				      generate_cc_vardecl_c::constructorinit_vf,
   978   				      generate_cc_vardecl_c::constructorinit_vf,
   863 				      generate_cc_vardecl_c::program_vt |
   979   				      generate_cc_vardecl_c::global_vt);
   864   				      generate_cc_vardecl_c::global_vt |
       
   865   				      generate_cc_vardecl_c::resource_vt);
       
   866   vardecl->print(symbol);
   980   vardecl->print(symbol);
   867   delete vardecl;
   981   delete vardecl;
   868 
   982   s4o.print("\n");
   869   /* (B.3) Constructor Body... */
   983   
   870   s4o.print("\n" + s4o.indent_spaces + "{}\n\n");
   984   /* (B.3) Resources initializations... */
       
   985   wanted_declaretype = initdeclare_dt;
       
   986   symbol->resource_declarations->accept(*this);
       
   987   
   871   s4o.indent_left();
   988   s4o.indent_left();
       
   989   s4o.print(s4o.indent_spaces + "}\n\n");
       
   990 
       
   991 
       
   992   /* (C) Run Function*/
       
   993   /* (C.1) Resources run functions protos... */
       
   994   wanted_declaretype = runprotos_dt;
       
   995   symbol->resource_declarations->accept(*this);
       
   996   s4o.print("\n");
       
   997 
       
   998   /* (C.2) Run function name... */
       
   999   s4o.print(s4o.indent_spaces + "void config");
       
  1000   s4o.print(FB_RUN_SUFFIX);
       
  1001   s4o.print("(int tick) {\n");
       
  1002   s4o.indent_right();
       
  1003 
       
  1004   /* (C.3) Resources initializations... */
       
  1005   wanted_declaretype = rundeclare_dt;
       
  1006   symbol->resource_declarations->accept(*this);
       
  1007 
       
  1008   /* (C.3) Close Public Function body */
   872   s4o.indent_left();
  1009   s4o.indent_left();
   873 
  1010   s4o.print(s4o.indent_spaces + "}\n");
   874   /* (C) Public Function*/
       
   875   /* (C.1) Public Function declaration */
       
   876   s4o.print(s4o.indent_spaces + "public:\n");
       
   877   s4o.indent_right();
       
   878   s4o.print(s4o.indent_spaces + "void run(void) {\n");
       
   879 
       
   880   /* (C.2) Public Function body */
       
   881   /* Invoke each program in the configuration */
       
   882   s4o.indent_right();
       
   883   generate_cc_configbody_c *configbody = new generate_cc_configbody_c(&s4o);
       
   884   symbol->accept(*configbody);
       
   885   delete configbody;
       
   886   s4o.indent_left();
       
   887 
       
   888   /* (C.3) Close Public Function body */
       
   889   s4o.print(s4o.indent_spaces + "} /* f() */\n\n");
       
   890   s4o.indent_left();
       
   891 
       
   892   /* (D) Close the class declaration... */
       
   893   s4o.indent_left();
       
   894   s4o.print(s4o.indent_spaces + "}; /* class ");
       
   895   symbol->configuration_name->accept(*this);
       
   896 
       
   897   s4o.print(" */\n\n\n");
       
   898 
  1011 
   899   return NULL;
  1012   return NULL;
   900 }
  1013 }
   901     
  1014 
       
  1015 void *visit(resource_declaration_c *symbol) {
       
  1016   if (wanted_declaretype == initprotos_dt || wanted_declaretype == runprotos_dt) {
       
  1017     s4o.print(s4o.indent_spaces + "void ");
       
  1018     symbol->resource_name->accept(*this);
       
  1019     if (wanted_declaretype == initprotos_dt) {
       
  1020       s4o.print(FB_INIT_SUFFIX);
       
  1021       s4o.print("(void);\n");
       
  1022     }
       
  1023     else {
       
  1024       s4o.print(FB_RUN_SUFFIX);
       
  1025       s4o.print("(int tick);\n");
       
  1026     }
       
  1027   }
       
  1028   if (wanted_declaretype == initdeclare_dt || wanted_declaretype == rundeclare_dt) {
       
  1029     s4o.print(s4o.indent_spaces);
       
  1030     symbol->resource_name->accept(*this);
       
  1031     if (wanted_declaretype == initdeclare_dt) {
       
  1032       s4o.print(FB_INIT_SUFFIX);
       
  1033       s4o.print("();\n");
       
  1034     }
       
  1035     else {
       
  1036       s4o.print(FB_RUN_SUFFIX);
       
  1037       s4o.print("(tick);\n");
       
  1038     }
       
  1039   }
       
  1040   return NULL;
       
  1041 }
       
  1042 
       
  1043 void *visit(single_resource_declaration_c *symbol) {
       
  1044   if (wanted_declaretype == initprotos_dt || wanted_declaretype == runprotos_dt) {
       
  1045     s4o.print(s4o.indent_spaces + "void RESOURCE");
       
  1046     if (wanted_declaretype == initprotos_dt) {
       
  1047       s4o.print(FB_INIT_SUFFIX);
       
  1048       s4o.print("(void);\n");
       
  1049     }
       
  1050     else {
       
  1051       s4o.print(FB_RUN_SUFFIX);
       
  1052       s4o.print("(int tick);\n");
       
  1053     }
       
  1054   }
       
  1055   if (wanted_declaretype == initdeclare_dt || wanted_declaretype == rundeclare_dt) {
       
  1056     s4o.print(s4o.indent_spaces + "RESOURCE");
       
  1057     if (wanted_declaretype == initdeclare_dt) {
       
  1058       s4o.print(FB_INIT_SUFFIX);
       
  1059       s4o.print("();\n");
       
  1060     }
       
  1061     else {
       
  1062       s4o.print(FB_RUN_SUFFIX);
       
  1063       s4o.print("(tick);\n");
       
  1064     }
       
  1065   }
       
  1066   return NULL;
       
  1067 }
       
  1068 
   902 };
  1069 };
   903 
  1070 
   904 /***********************************************************************/
  1071 /***********************************************************************/
   905 /***********************************************************************/
  1072 /***********************************************************************/
   906 /***********************************************************************/
  1073 /***********************************************************************/
   911 /***********************************************************************/
  1078 /***********************************************************************/
   912 
  1079 
   913 
  1080 
   914 class generate_cc_resources_c: public generate_cc_typedecl_c {
  1081 class generate_cc_resources_c: public generate_cc_typedecl_c {
   915 
  1082 
       
  1083   search_var_instance_decl_c *search_config_instance;
       
  1084   search_var_instance_decl_c *search_resource_instance;
       
  1085 
       
  1086   private:
       
  1087     /* The name of the resource curretnly being processed... */
       
  1088     symbol_c *current_resource_name;
       
  1089     symbol_c *current_global_vars;
       
  1090 
   916   public:
  1091   public:
   917     generate_cc_resources_c(stage4out_c *s4o_ptr)
  1092     generate_cc_resources_c(stage4out_c *s4o_ptr, symbol_c *config_scope, symbol_c *resource_scope, unsigned long time)
   918       : generate_cc_typedecl_c(s4o_ptr) {};
  1093       : generate_cc_typedecl_c(s4o_ptr) {
   919     virtual ~generate_cc_resources_c(void) {}
  1094       search_config_instance = new search_var_instance_decl_c(config_scope);
   920 
  1095       search_resource_instance = new search_var_instance_decl_c(resource_scope);
       
  1096       common_ticktime = time;
       
  1097       current_resource_name = NULL;
       
  1098       current_global_vars = NULL;
       
  1099     };
       
  1100     virtual ~generate_cc_resources_c(void) {
       
  1101       delete search_config_instance;
       
  1102       delete search_resource_instance;
       
  1103     }
       
  1104 
       
  1105     typedef enum {
       
  1106       declare_dt,
       
  1107       init_dt,
       
  1108       run_dt
       
  1109     } declaretype_t;
       
  1110 
       
  1111     declaretype_t wanted_declaretype;
       
  1112 
       
  1113     unsigned long common_ticktime;
       
  1114     
       
  1115     const char *current_program_name;
       
  1116 
       
  1117     typedef enum {
       
  1118       assign_at,
       
  1119       send_at
       
  1120     } assigntype_t;
       
  1121 
       
  1122     assigntype_t wanted_assigntype;
       
  1123 
       
  1124 /********************************/
       
  1125 /* B 1.7 Configuration elements */
       
  1126 /********************************/
       
  1127 
       
  1128 /*
       
  1129 RESOURCE resource_name ON resource_type_name
       
  1130    optional_global_var_declarations
       
  1131    single_resource_declaration
       
  1132 END_RESOURCE
       
  1133 */
       
  1134 // SYM_REF4(resource_declaration_c, resource_name, resource_type_name, global_var_declarations, resource_declaration)
   921     void *visit(resource_declaration_c *symbol) {
  1135     void *visit(resource_declaration_c *symbol) {
   922     	return NULL;
  1136       current_resource_name = symbol->resource_name;
   923     }
  1137       current_global_vars = symbol->global_var_declarations;
   924 
  1138       
       
  1139       symbol->resource_declaration->accept(*this);
       
  1140       
       
  1141       current_resource_name = NULL;
       
  1142       current_global_vars = NULL;
       
  1143       return NULL;
       
  1144     }
       
  1145 
       
  1146 /* task_configuration_list program_configuration_list */
       
  1147 // SYM_REF2(single_resource_declaration_c, task_configuration_list, program_configuration_list)
   925     void *visit(single_resource_declaration_c *symbol) {
  1148     void *visit(single_resource_declaration_c *symbol) {
   926     	return NULL;
  1149     	bool single_resource = current_resource_name == NULL;
   927     }
  1150       if (single_resource)
   928     
  1151         current_resource_name = new identifier_c("RESOURCE");
       
  1152       generate_cc_vardecl_c *vardecl;
       
  1153       
       
  1154       /* (A) resource declaration... */
       
  1155       /* (A.1) resource name in comment */
       
  1156       s4o.print("// RESOURCE ");
       
  1157       current_resource_name->accept(*this);
       
  1158       s4o.print("\n");
       
  1159        
       
  1160       /* (A.2) POUs inclusion */
       
  1161       s4o.print("#include \"POUS.c\"\n\n");
       
  1162       
       
  1163       /* (A.3) Global variables... */
       
  1164       if (current_global_vars != NULL) {
       
  1165         vardecl = new generate_cc_vardecl_c(&s4o,
       
  1166                       generate_cc_vardecl_c::local_vf,
       
  1167                       generate_cc_vardecl_c::global_vt);
       
  1168         vardecl->print(symbol);
       
  1169         delete vardecl;
       
  1170       }
       
  1171       
       
  1172       /* (A.4) Resource programs declaration... */
       
  1173       wanted_declaretype = declare_dt;
       
  1174       symbol->program_configuration_list->accept(*this);
       
  1175       s4o.print("\n");
       
  1176       
       
  1177       /* (B) resource initialisation function... */
       
  1178       /* (B.1) initialisation function name... */
       
  1179       s4o.print("void ");
       
  1180       current_resource_name->accept(*this);
       
  1181       s4o.print(FB_INIT_SUFFIX);
       
  1182       s4o.print("(void) {\n");
       
  1183       s4o.indent_right();
       
  1184       
       
  1185       /* (B.2) Global variables initialisations... */
       
  1186       if (current_global_vars != NULL) {
       
  1187         s4o.print(s4o.indent_spaces);
       
  1188         vardecl = new generate_cc_vardecl_c(&s4o,
       
  1189                       generate_cc_vardecl_c::constructorinit_vf,
       
  1190                       generate_cc_vardecl_c::global_vt);
       
  1191         vardecl->print(symbol);
       
  1192         delete vardecl;
       
  1193       }
       
  1194       
       
  1195       /* (B.3) Resource programs initialisations... */
       
  1196       wanted_declaretype = init_dt;
       
  1197       symbol->program_configuration_list->accept(*this);
       
  1198       
       
  1199       s4o.indent_left();
       
  1200       s4o.print("}\n\n");
       
  1201       
       
  1202       /* (C) Resource run function... */
       
  1203       /* (C.1) Run function name... */
       
  1204       s4o.print("void ");
       
  1205       current_resource_name->accept(*this);
       
  1206       s4o.print(FB_RUN_SUFFIX);
       
  1207       s4o.print("(int tick) {\n");
       
  1208       s4o.indent_right();
       
  1209       
       
  1210       /* (C.2) Task management... */
       
  1211       symbol->task_configuration_list->accept(*this);
       
  1212       
       
  1213       /* (C.3) Program run declaration... */
       
  1214       wanted_declaretype = run_dt;
       
  1215       symbol->program_configuration_list->accept(*this);
       
  1216       
       
  1217       s4o.indent_left();
       
  1218       s4o.print("}\n\n");
       
  1219       
       
  1220       if (single_resource)
       
  1221         delete current_resource_name;
       
  1222       return NULL;
       
  1223     }
       
  1224     
       
  1225 /*  PROGRAM [RETAIN | NON_RETAIN] program_name [WITH task_name] ':' program_type_name ['(' prog_conf_elements ')'] */
       
  1226 //SYM_REF6(program_configuration_c, retain_option, program_name, task_name, program_type_name, prog_conf_elements, unused)
       
  1227     void *visit(program_configuration_c *symbol) {
       
  1228       if (wanted_declaretype == declare_dt) {
       
  1229         s4o.print(s4o.indent_spaces);
       
  1230         symbol->program_type_name->accept(*this);
       
  1231         s4o.print(" ");
       
  1232         symbol->program_name->accept(*this);
       
  1233         s4o.print(";\n");
       
  1234       }
       
  1235       if (wanted_declaretype == init_dt) {
       
  1236         s4o.print(s4o.indent_spaces);
       
  1237         symbol->program_type_name->accept(*this);
       
  1238         s4o.print(FB_INIT_SUFFIX);
       
  1239         s4o.print("(&");
       
  1240         symbol->program_name->accept(*this);
       
  1241         s4o.print(");\n");
       
  1242       }
       
  1243       if (wanted_declaretype == run_dt) {
       
  1244         current_program_name = ((identifier_c*)(symbol->program_name))->value;
       
  1245         if (symbol->task_name != NULL) {
       
  1246           s4o.print(s4o.indent_spaces);
       
  1247           s4o.print("if (");
       
  1248           symbol->task_name->accept(*this);
       
  1249           s4o.print(") {\n");
       
  1250           s4o.indent_right(); 
       
  1251         }
       
  1252         
       
  1253         wanted_assigntype = assign_at;
       
  1254         symbol->prog_conf_elements->accept(*this);
       
  1255         
       
  1256         s4o.print(s4o.indent_spaces);
       
  1257         symbol->program_type_name->accept(*this);
       
  1258         s4o.print(FB_FUNCTION_SUFFIX);
       
  1259         s4o.print("(&");
       
  1260         symbol->program_name->accept(*this);
       
  1261         s4o.print(");\n");
       
  1262         
       
  1263         wanted_assigntype = send_at;
       
  1264         symbol->prog_conf_elements->accept(*this);
       
  1265         
       
  1266         if (symbol->task_name != NULL) {
       
  1267           s4o.indent_left();
       
  1268           s4o.print(s4o.indent_spaces + "}\n");
       
  1269         }
       
  1270       }
       
  1271       return NULL;
       
  1272     }
       
  1273     
       
  1274 /*  TASK task_name task_initialization */
       
  1275 //SYM_REF2(task_configuration_c, task_name, task_initialization)
       
  1276     void *visit(task_configuration_c *symbol) {
       
  1277       s4o.print(s4o.indent_spaces + "int ");
       
  1278       symbol->task_name->accept(*this);
       
  1279       s4o.print(" = ");
       
  1280       symbol->task_initialization->accept(*this);
       
  1281       s4o.print(";\n");
       
  1282       return NULL;
       
  1283     }
       
  1284     
       
  1285 /*  '(' [SINGLE ASSIGN data_source ','] [INTERVAL ASSIGN data_source ','] PRIORITY ASSIGN integer ')' */
       
  1286 //SYM_REF4(task_initialization_c, single_data_source, interval_data_source, priority_data_source, unused)
       
  1287     void *visit(task_initialization_c *symbol) {
       
  1288       if (symbol->interval_data_source != NULL) {
       
  1289         calculate_time_c calculate_time;
       
  1290         symbol->interval_data_source->accept(calculate_time);
       
  1291         unsigned long time = calculate_time.get_time();
       
  1292         if (time != 0) {
       
  1293           s4o.print("tick % ");
       
  1294           s4o.print_integer((int)(time / common_ticktime));
       
  1295         }
       
  1296         else
       
  1297           s4o.print("1");
       
  1298       }
       
  1299       else
       
  1300         s4o.print("1");
       
  1301       return NULL;
       
  1302     }
       
  1303 
       
  1304 /*  any_symbolic_variable ASSIGN prog_data_source */
       
  1305 //SYM_REF2(prog_cnxn_assign_c, symbolic_variable, prog_data_source)
       
  1306     void *visit(prog_cnxn_assign_c *symbol) {
       
  1307       if (wanted_assigntype == assign_at) {
       
  1308         symbol_c *var_decl;
       
  1309         unsigned int vartype = 0;
       
  1310         symbol_c *current_var_reference = ((global_var_reference_c *)(symbol->prog_data_source))->global_var_name;
       
  1311         var_decl = search_resource_instance->get_decl(current_var_reference);
       
  1312         if (var_decl == NULL) {
       
  1313           var_decl = search_config_instance->get_decl(current_var_reference);
       
  1314           if (var_decl == NULL)
       
  1315             ERROR;
       
  1316           else
       
  1317             vartype = search_config_instance->get_vartype();
       
  1318         }
       
  1319         else
       
  1320           vartype = search_resource_instance->get_vartype();
       
  1321         
       
  1322         s4o.print(s4o.indent_spaces + "{extern ");
       
  1323         var_decl->accept(*this);
       
  1324         s4o.print(" ");
       
  1325         symbol->prog_data_source->accept(*this);
       
  1326         s4o.print("; ");
       
  1327         s4o.print(current_program_name);
       
  1328         s4o.print(".");
       
  1329         symbol->symbolic_variable->accept(*this);
       
  1330         s4o.print(" = ");
       
  1331         if (vartype || search_var_instance_decl_c::global_vt)
       
  1332           s4o.print("*");
       
  1333         symbol->prog_data_source->accept(*this);
       
  1334         s4o.print(";}\n");
       
  1335       }
       
  1336       return NULL;
       
  1337     }
       
  1338 
       
  1339 /* any_symbolic_variable SENDTO data_sink */
       
  1340 //SYM_REF2(prog_cnxn_sendto_c, symbolic_variable, data_sink)
       
  1341     void *visit(prog_cnxn_sendto_c *symbol) {
       
  1342       if (wanted_assigntype == send_at) {
       
  1343         symbol_c *var_decl;
       
  1344         unsigned int vartype = 0;
       
  1345         symbol_c *current_var_reference = ((global_var_reference_c *)(symbol->data_sink))->global_var_name;
       
  1346         var_decl = search_resource_instance->get_decl(current_var_reference);
       
  1347         if (var_decl == NULL) {
       
  1348           var_decl = search_config_instance->get_decl(current_var_reference);
       
  1349           if (var_decl == NULL)
       
  1350             ERROR;
       
  1351           else
       
  1352             vartype = search_config_instance->get_vartype();
       
  1353         }
       
  1354         else
       
  1355           vartype = search_resource_instance->get_vartype();
       
  1356         
       
  1357         s4o.print(s4o.indent_spaces);
       
  1358         s4o.print(s4o.indent_spaces + "{extern ");
       
  1359         var_decl->accept(*this);
       
  1360         s4o.print(" ");
       
  1361         symbol->data_sink->accept(*this);
       
  1362         s4o.print("; ");
       
  1363         if (vartype || search_var_instance_decl_c::global_vt)
       
  1364           s4o.print("*");
       
  1365         symbol->data_sink->accept(*this);
       
  1366         s4o.print(" = ");
       
  1367         s4o.print(current_program_name);
       
  1368         s4o.print(".");
       
  1369         symbol->symbolic_variable->accept(*this);
       
  1370         s4o.print("};\n");
       
  1371       }
       
  1372       return NULL;
       
  1373     }
       
  1374 
   929 };
  1375 };
       
  1376 
   930 /***********************************************************************/
  1377 /***********************************************************************/
   931 /***********************************************************************/
  1378 /***********************************************************************/
   932 /***********************************************************************/
  1379 /***********************************************************************/
   933 /***********************************************************************/
  1380 /***********************************************************************/
   934 /***********************************************************************/
  1381 /***********************************************************************/
   940   protected:
  1387   protected:
   941     stage4out_c &s4o;
  1388     stage4out_c &s4o;
   942     stage4out_c pous_s4o;
  1389     stage4out_c pous_s4o;
   943     generate_cc_pous_c generate_cc_pous;
  1390     generate_cc_pous_c generate_cc_pous;
   944 
  1391 
       
  1392     symbol_c *current_configuration;
       
  1393 
   945     const char *current_name;
  1394     const char *current_name;
       
  1395 
       
  1396     unsigned long common_ticktime;
   946 
  1397 
   947   public:
  1398   public:
   948     generate_cc_c(stage4out_c *s4o_ptr): 
  1399     generate_cc_c(stage4out_c *s4o_ptr): 
   949             s4o(*s4o_ptr),
  1400             s4o(*s4o_ptr),
   950             generate_cc_pous(&pous_s4o) {}
  1401             pous_s4o("POUS", "c"),
       
  1402             generate_cc_pous(&pous_s4o) {
       
  1403       current_configuration = NULL;
       
  1404     }
   951             
  1405             
   952     ~generate_cc_c(void) {}
  1406     ~generate_cc_c(void) {}
   953 
  1407 
   954 /*************************/
  1408 /*************************/
   955 /* B.1 - Common elements */
  1409 /* B.1 - Common elements */
   992 
  1446 
   993 /********************************/
  1447 /********************************/
   994 /* B 1.7 Configuration elements */
  1448 /* B 1.7 Configuration elements */
   995 /********************************/
  1449 /********************************/
   996     void *visit(configuration_declaration_c *symbol) {
  1450     void *visit(configuration_declaration_c *symbol) {
   997     	symbol->configuration_name->accept(*this);
  1451   	  static int configuration_count = 0;
       
  1452   
       
  1453       if (configuration_count++) {
       
  1454         /* the first configuration is the one we will use!! */
       
  1455         ERROR;
       
  1456       }
       
  1457       
       
  1458       current_configuration = symbol;
       
  1459       
       
  1460       calculate_common_ticktime_c calculate_common_ticktime;
       
  1461       symbol->accept(calculate_common_ticktime);
       
  1462       common_ticktime = calculate_common_ticktime.get_ticktime();
       
  1463       s4o.print("common_ticktime : ");
       
  1464       s4o.print_integer((int)(common_ticktime / 1000000));
       
  1465       s4o.print("ms\n");
       
  1466       
       
  1467       symbol->configuration_name->accept(*this);
   998     	stage4out_c config_s4o(current_name, "c");
  1468     	stage4out_c config_s4o(current_name, "c");
   999     	generate_cc_config_c generate_cc_config(&config_s4o);
  1469     	generate_cc_config_c generate_cc_config(&config_s4o);
  1000     	symbol->accept(generate_cc_config);
  1470     	symbol->accept(generate_cc_config);
  1001     	return NULL;
  1471       symbol->resource_declarations->accept(*this);
       
  1472     	
       
  1473       current_configuration = NULL;
       
  1474       
       
  1475       return NULL;
  1002     }
  1476     }
  1003 
  1477 
  1004     void *visit(resource_declaration_c *symbol) {
  1478     void *visit(resource_declaration_c *symbol) {
  1005     	symbol->resource_name->accept(*this);
  1479     	symbol->resource_name->accept(*this);
  1006     	stage4out_c resources_s4o(current_name, "c");
  1480     	stage4out_c resources_s4o(current_name, "c");
  1007     	generate_cc_resources_c generate_cc_resources(&resources_s4o);
  1481       generate_cc_resources_c generate_cc_resources(&resources_s4o, current_configuration, symbol, common_ticktime);
  1008     	symbol->accept(generate_cc_resources);
  1482     	symbol->accept(generate_cc_resources);
  1009     	return NULL;
  1483     	return NULL;
  1010     }
  1484     }
  1011 
  1485 
  1012     void *visit(single_resource_declaration_c *symbol) {
  1486     void *visit(single_resource_declaration_c *symbol) {
  1013     	stage4out_c resources_s4o("resource", "c");
  1487     	stage4out_c resources_s4o("RESOURCE", "c");
  1014     	generate_cc_resources_c generate_cc_resources(&resources_s4o);
  1488       generate_cc_resources_c generate_cc_resources(&resources_s4o, current_configuration, symbol, common_ticktime);
  1015     	symbol->accept(generate_cc_resources);
  1489     	symbol->accept(generate_cc_resources);
  1016     	return NULL;
  1490     	return NULL;
  1017     }
  1491     }
  1018 
       
  1019     
  1492     
  1020 };
  1493 };
  1021 
  1494 
  1022 /***********************************************************************/
  1495 /***********************************************************************/
  1023 /***********************************************************************/
  1496 /***********************************************************************/