lbessard@70: /* lbessard@70: * (c) 2007 Mario de Sousa, Laurent Bessard lbessard@70: * lbessard@70: * Offered to the public under the terms of the GNU General Public License lbessard@70: * as published by the Free Software Foundation; either version 2 of the lbessard@70: * License, or (at your option) any later version. lbessard@70: * lbessard@70: * This program is distributed in the hope that it will be useful, but lbessard@70: * WITHOUT ANY WARRANTY; without even the implied warranty of lbessard@70: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General lbessard@70: * Public License for more details. lbessard@70: * lbessard@70: * This code is made available on the understanding that it will not be lbessard@70: * used in safety-critical situations without a full and competent review. lbessard@70: */ lbessard@70: lbessard@70: /* lbessard@70: * An IEC 61131-3 IL and ST compiler. lbessard@70: * lbessard@70: * Based on the lbessard@70: * FINAL DRAFT - IEC 61131-3, 2nd Ed. (2001-12-10) lbessard@70: * lbessard@70: */ lbessard@70: lbessard@70: lbessard@70: /* lbessard@70: * Conversion of sfc networks (i.e. SFC code). lbessard@70: * lbessard@70: * This is part of the 4th stage that generates lbessard@70: * a c++ source program equivalent to the SFC, IL and ST lbessard@70: * code. lbessard@70: */ lbessard@70: lbessard@70: lbessard@70: lbessard@70: lbessard@70: /***********************************************************************/ lbessard@70: /***********************************************************************/ lbessard@70: /***********************************************************************/ lbessard@70: /***********************************************************************/ lbessard@70: lbessard@70: class generate_c_sfcdecl_c: protected generate_c_typedecl_c { lbessard@70: lbessard@70: public: lbessard@70: typedef enum { lbessard@70: sfcdecl_sd, lbessard@70: sfcinit_sd, lbessard@70: stepcount_sd, lbessard@70: stepdef_sd, lbessard@70: stepundef_sd, lbessard@70: actiondef_sd, lbessard@70: actionundef_sd, lbessard@70: actioncount_sd lbessard@70: } sfcdeclaration_t; lbessard@70: lbessard@70: private: lbessard@70: char step_number; lbessard@70: char action_number; lbessard@70: char transition_number; lbessard@70: lbessard@70: sfcdeclaration_t wanted_sfcdeclaration; lbessard@70: lbessard@70: public: lbessard@70: generate_c_sfcdecl_c(stage4out_c *s4o_ptr, sfcdeclaration_t sfcdeclaration) lbessard@70: : generate_c_typedecl_c(s4o_ptr) { lbessard@70: wanted_sfcdeclaration = sfcdeclaration; lbessard@70: } lbessard@70: ~generate_c_sfcdecl_c(void) {} lbessard@70: lbessard@70: void print(symbol_c *symbol, const char *variable_prefix = NULL) { lbessard@70: this->set_variable_prefix(variable_prefix); lbessard@70: lbessard@70: symbol->accept(*this); lbessard@70: } lbessard@70: lbessard@70: /*********************************************/ lbessard@70: /* B.1.6 Sequential function chart elements */ lbessard@70: /*********************************************/ lbessard@70: lbessard@70: void *visit(sequential_function_chart_c *symbol) { lbessard@70: step_number = 0; lbessard@70: action_number = 0; lbessard@70: transition_number = 0; lbessard@70: switch (wanted_sfcdeclaration) { lbessard@70: case sfcdecl_sd: lbessard@70: for(int i = 0; i < symbol->n; i++) lbessard@70: symbol->elements[i]->accept(*this); lbessard@70: lbessard@70: /* steps table declaration */ lbessard@70: s4o.print(s4o.indent_spaces + "STEP step_list["); lbessard@70: s4o.print_integer(step_number); lbessard@70: s4o.print("];\n"); lbessard@70: s4o.print(s4o.indent_spaces + "UINT nb_steps;\n"); lbessard@70: lbessard@70: /* actions table declaration */ lbessard@70: s4o.print(s4o.indent_spaces + "ACTION action_list["); lbessard@70: s4o.print_integer(action_number); lbessard@70: s4o.print("];\n"); lbessard@70: s4o.print(s4o.indent_spaces + "UINT nb_actions;\n"); lbessard@70: lbessard@70: /* transitions table declaration */ lbessard@116: s4o.print(s4o.indent_spaces + "BOOL transition_list["); lbessard@70: s4o.print_integer(transition_number); lbessard@70: s4o.print("];\n"); lbessard@70: lbessard@125: /* last_ticktime declaration */ lbessard@125: s4o.print(s4o.indent_spaces + "TIME lasttick_time;\n"); lbessard@70: break; lbessard@70: case sfcinit_sd: lbessard@70: s4o.print(s4o.indent_spaces); lbessard@70: s4o.print("UINT i;\n"); lbessard@70: lbessard@70: /* steps table count */ lbessard@70: wanted_sfcdeclaration = stepcount_sd; lbessard@70: for(int i = 0; i < symbol->n; i++) lbessard@70: symbol->elements[i]->accept(*this); lbessard@70: s4o.print(s4o.indent_spaces); lbessard@70: print_variable_prefix(); lbessard@70: s4o.print("nb_steps = "); lbessard@70: s4o.print_integer(step_number); lbessard@70: s4o.print(";\n"); lbessard@70: step_number = 0; lbessard@70: wanted_sfcdeclaration = sfcinit_sd; lbessard@70: lbessard@70: /* steps table initialisation */ lbessard@70: s4o.print(s4o.indent_spaces + "STEP temp_step = {0, 0, 0};\n"); lbessard@70: s4o.print(s4o.indent_spaces + "for(i = 0; i < "); lbessard@70: print_variable_prefix(); lbessard@70: s4o.print("nb_steps; i++) {\n"); lbessard@70: s4o.indent_right(); lbessard@70: s4o.print(s4o.indent_spaces); lbessard@70: print_variable_prefix(); lbessard@70: s4o.print("step_list[i] = temp_step;\n"); lbessard@70: s4o.indent_left(); lbessard@70: s4o.print(s4o.indent_spaces + "}\n"); lbessard@70: for(int i = 0; i < symbol->n; i++) lbessard@70: symbol->elements[i]->accept(*this); lbessard@70: lbessard@70: /* steps table count */ lbessard@70: wanted_sfcdeclaration = actioncount_sd; lbessard@70: for(int i = 0; i < symbol->n; i++) lbessard@70: symbol->elements[i]->accept(*this); lbessard@70: s4o.print(s4o.indent_spaces); lbessard@70: print_variable_prefix(); lbessard@70: s4o.print("nb_actions = "); lbessard@70: s4o.print_integer(action_number); lbessard@70: s4o.print(";\n"); lbessard@70: action_number = 0; lbessard@70: wanted_sfcdeclaration = sfcinit_sd; lbessard@70: lbessard@70: /* actions table initialisation */ lbessard@70: s4o.print(s4o.indent_spaces + "ACTION temp_action = {0, 0, 0, 0, 0, 0};\n"); lbessard@70: s4o.print(s4o.indent_spaces + "for(i = 0; i < "); lbessard@70: print_variable_prefix(); lbessard@70: s4o.print("nb_actions; i++) {\n"); lbessard@70: s4o.indent_right(); lbessard@70: s4o.print(s4o.indent_spaces); lbessard@70: print_variable_prefix(); lbessard@70: s4o.print("action_list[i] = temp_action;\n"); lbessard@70: s4o.indent_left(); lbessard@70: s4o.print(s4o.indent_spaces + "}\n"); lbessard@125: lbessard@125: /* last_ticktime initialisation */ lbessard@125: print_variable_prefix(); lbessard@125: s4o.print("lasttick_time = __CURRENT_TIME;\n"); lbessard@70: break; lbessard@70: case stepdef_sd: lbessard@70: s4o.print("// Steps definitions\n"); lbessard@70: for(int i = 0; i < symbol->n; i++) lbessard@70: symbol->elements[i]->accept(*this); lbessard@70: s4o.print("\n"); lbessard@70: break; lbessard@70: case actiondef_sd: lbessard@70: s4o.print("// Actions definitions\n"); lbessard@70: for(int i = 0; i < symbol->n; i++) lbessard@70: symbol->elements[i]->accept(*this); lbessard@70: s4o.print("\n"); lbessard@70: break; lbessard@70: case stepundef_sd: lbessard@70: s4o.print("// Steps undefinitions\n"); lbessard@70: for(int i = 0; i < symbol->n; i++) lbessard@70: symbol->elements[i]->accept(*this); lbessard@70: s4o.print("\n"); lbessard@70: break; lbessard@70: case actionundef_sd: lbessard@70: s4o.print("// Actions undefinitions\n"); lbessard@70: for(int i = 0; i < symbol->n; i++) lbessard@70: symbol->elements[i]->accept(*this); lbessard@70: s4o.print("\n"); lbessard@70: break; lbessard@70: default: lbessard@70: break; lbessard@70: } lbessard@70: return NULL; lbessard@70: } lbessard@70: lbessard@70: void *visit(initial_step_c *symbol) { lbessard@70: switch (wanted_sfcdeclaration) { lbessard@70: case stepcount_sd: lbessard@70: case sfcdecl_sd: lbessard@70: step_number++; lbessard@70: break; lbessard@70: case sfcinit_sd: lbessard@70: s4o.print(s4o.indent_spaces); lbessard@70: print_variable_prefix(); lbessard@70: s4o.print("step_list["); lbessard@70: s4o.print_integer(step_number); lbessard@70: s4o.print("].state = 1;\n"); lbessard@70: step_number++; lbessard@70: break; lbessard@70: case stepdef_sd: lbessard@70: s4o.print("#define "); lbessard@70: s4o.print(SFC_STEP_ACTION_PREFIX); lbessard@70: symbol->step_name->accept(*this); lbessard@70: s4o.print(" "); lbessard@70: s4o.print_integer(step_number); lbessard@70: s4o.print("\n"); lbessard@70: step_number++; lbessard@70: break; lbessard@70: case stepundef_sd: lbessard@70: s4o.print("#undef "); lbessard@70: s4o.print(SFC_STEP_ACTION_PREFIX); lbessard@70: symbol->step_name->accept(*this); lbessard@70: s4o.print("\n"); lbessard@70: break; lbessard@70: default: lbessard@70: break; lbessard@70: } lbessard@70: return NULL; lbessard@70: } lbessard@70: lbessard@70: void *visit(step_c *symbol) { lbessard@70: switch (wanted_sfcdeclaration) { lbessard@70: case stepcount_sd: lbessard@70: case sfcdecl_sd: lbessard@119: case sfcinit_sd: lbessard@70: step_number++; lbessard@70: break; lbessard@70: case stepdef_sd: lbessard@70: s4o.print("#define "); lbessard@70: s4o.print(SFC_STEP_ACTION_PREFIX); lbessard@70: symbol->step_name->accept(*this); lbessard@70: s4o.print(" "); lbessard@70: s4o.print_integer(step_number); lbessard@70: s4o.print("\n"); lbessard@70: step_number++; lbessard@70: break; lbessard@70: case stepundef_sd: lbessard@70: s4o.print("#undef "); lbessard@70: s4o.print(SFC_STEP_ACTION_PREFIX); lbessard@70: symbol->step_name->accept(*this); lbessard@70: s4o.print("\n"); lbessard@70: break; lbessard@70: default: lbessard@70: break; lbessard@70: } lbessard@70: return NULL; lbessard@70: } lbessard@70: lbessard@70: void *visit(transition_c *symbol) { lbessard@70: switch (wanted_sfcdeclaration) { lbessard@70: case sfcdecl_sd: lbessard@70: transition_number++; lbessard@70: break; lbessard@70: default: lbessard@70: break; lbessard@70: } lbessard@70: return NULL; lbessard@70: } lbessard@70: lbessard@70: void *visit(action_c *symbol) { lbessard@70: switch (wanted_sfcdeclaration) { lbessard@70: case actiondef_sd: lbessard@70: s4o.print("#define "); lbessard@70: s4o.print(SFC_STEP_ACTION_PREFIX); lbessard@70: symbol->action_name->accept(*this); lbessard@70: s4o.print(" "); lbessard@70: s4o.print_integer(action_number); lbessard@70: s4o.print("\n"); lbessard@70: action_number++; lbessard@70: break; lbessard@70: case actionundef_sd: lbessard@70: s4o.print("#undef "); lbessard@70: s4o.print(SFC_STEP_ACTION_PREFIX); lbessard@70: symbol->action_name->accept(*this); lbessard@70: s4o.print("\n"); lbessard@70: break; lbessard@70: case actioncount_sd: lbessard@70: case sfcdecl_sd: lbessard@70: action_number++; lbessard@70: break; lbessard@70: default: lbessard@70: break; lbessard@70: } lbessard@70: return NULL; lbessard@70: } lbessard@70: lbessard@70: void *visit(instruction_list_c *symbol) { lbessard@70: return NULL; lbessard@70: } lbessard@70: lbessard@70: void *visit(statement_list_c *symbol) { lbessard@70: return NULL; lbessard@70: } lbessard@70: lbessard@70: }; /* generate_c_sfcdecl_c */ lbessard@70: