# HG changeset patch # User lbessard # Date 1172254763 -3600 # Node ID 38754701ac41bdfe11c23a09544c3e6f1d6737f1 # Parent e8b99f89641678edf1886197350b76e419e9af4a SFC state machine first approach generator implemented diff -r e8b99f896416 -r 38754701ac41 absyntax/absyntax.def --- a/absyntax/absyntax.def Tue Feb 20 18:17:21 2007 +0100 +++ b/absyntax/absyntax.def Fri Feb 23 19:19:23 2007 +0100 @@ -577,8 +577,6 @@ SYM_LIST(step_name_list_c) -SYM_REF2(transition_condition_c, simple_instr_list, expression) - SYM_REF2(action_c, action_name, function_block_body) /********************************/ diff -r e8b99f896416 -r 38754701ac41 stage1_2/iec.y --- a/stage1_2/iec.y Tue Feb 20 18:17:21 2007 +0100 +++ b/stage1_2/iec.y Fri Feb 23 19:19:23 2007 +0100 @@ -3771,12 +3771,12 @@ transition_condition_il: ':' eol_list simple_instr_list - {$$ = new transition_condition_c($3, NULL);} + {$$ = $3;} ; transition_condition_st: ASSIGN expression ';' - {$$ = new transition_condition_c(NULL, $2);} + {$$ = $2} ; transition: diff -r e8b99f896416 -r 38754701ac41 stage4/generate_cc/generate_cc.cc --- a/stage4/generate_cc/generate_cc.cc Tue Feb 20 18:17:21 2007 +0100 +++ b/stage4/generate_cc/generate_cc.cc Fri Feb 23 19:19:23 2007 +0100 @@ -180,6 +180,7 @@ #include "search_expression_type.cc" #include "generate_cc_base.cc" +#include "generate_cc_sfcdecl.cc" #include "generate_cc_typedecl.cc" #include "generate_cc_vardecl.cc" #include "generate_cc_configbody.cc" @@ -213,59 +214,76 @@ /***********************************************************************/ /* A helper class that knows how to generate code for both the IL and ST languages... */ -class generate_cc_IL_and_ST_c: public null_visitor_c { +class generate_cc_SFC_IL_ST_c: public null_visitor_c { private: stage4out_c *s4o_ptr; symbol_c *scope; const char *variable_prefix; public: - generate_cc_IL_and_ST_c(stage4out_c *s4o_ptr, symbol_c *scope, const char *variable_prefix = NULL) { - if (NULL == scope) ERROR; - this->s4o_ptr = s4o_ptr; - this->scope = scope; - this->variable_prefix = variable_prefix; - } - - - public: -/****************************************/ -/* B.2 - Language IL (Instruction List) */ -/****************************************/ - -/***********************************/ -/* B 2.1 Instructions and Operands */ -/***********************************/ -/*| instruction_list il_instruction */ -void *visit(instruction_list_c *symbol) { + generate_cc_SFC_IL_ST_c(stage4out_c *s4o_ptr, symbol_c *scope, const char *variable_prefix = NULL); + /*********************************************/ + /* B.1.6 Sequential function chart elements */ + /*********************************************/ + + /*| sequential_function_chart sfc_network*/ + void *visit(sequential_function_chart_c * symbol); + + /****************************************/ + /* B.2 - Language IL (Instruction List) */ + /****************************************/ + + /***********************************/ + /* B 2.1 Instructions and Operands */ + /***********************************/ + /*| instruction_list il_instruction */ + void *visit(instruction_list_c *symbol); + + /* Remainder implemented in generate_cc_il_c... */ + + /***************************************/ + /* B.3 - Language ST (Structured Text) */ + /***************************************/ + /***********************/ + /* B 3.1 - Expressions */ + /***********************/ + /* Implemented in generate_cc_st_c */ + + /********************/ + /* B 3.2 Statements */ + /********************/ + void *visit(statement_list_c *symbol); + +/* Remainder implemented in generate_cc_st_c... */ +}; + +#include "generate_cc_sfc.cc" + +generate_cc_SFC_IL_ST_c::generate_cc_SFC_IL_ST_c(stage4out_c *s4o_ptr, symbol_c *scope, const char *variable_prefix) { + if (NULL == scope) ERROR; + this->s4o_ptr = s4o_ptr; + this->scope = scope; + this->variable_prefix = variable_prefix; +} + +void *generate_cc_SFC_IL_ST_c::visit(sequential_function_chart_c * symbol) { + generate_cc_sfc_c generate_cc_sfc(s4o_ptr, scope, variable_prefix); + generate_cc_sfc.generate(symbol); + return NULL; +} + +void *generate_cc_SFC_IL_ST_c::visit(instruction_list_c *symbol) { generate_cc_il_c generate_cc_il(s4o_ptr, scope, variable_prefix); generate_cc_il.generate(symbol); return NULL; } -/* Remainder implemented in generate_cc_il_c... */ - -/***************************************/ -/* B.3 - Language ST (Structured Text) */ -/***************************************/ -/***********************/ -/* B 3.1 - Expressions */ -/***********************/ -/* Implemented in generate_cc_st_c */ - -/********************/ -/* B 3.2 Statements */ -/********************/ -void *visit(statement_list_c *symbol) { +void *generate_cc_SFC_IL_ST_c::visit(statement_list_c *symbol) { generate_cc_st_c generate_cc_st(s4o_ptr, scope, variable_prefix); generate_cc_st.generate(symbol); return NULL; } -/* Remainder implemented in generate_cc_st_c... */ -}; - - @@ -450,7 +468,7 @@ s4o.print(";\n\n"); /* (C) Function body */ - generate_cc_IL_and_ST_c generate_cc_code(&s4o, symbol); + generate_cc_SFC_IL_ST_c generate_cc_code(&s4o, symbol); symbol->function_body->accept(generate_cc_code); s4o.print(s4o.indent_spaces + "return "); symbol->derived_function_name->accept(*this); @@ -543,7 +561,7 @@ s4o.print("\n"); /* (B.3) Function code */ - generate_cc_IL_and_ST_c generate_cc_code(&s4o, symbol, FB_FUNCTION_PARAM"->"); + generate_cc_SFC_IL_ST_c generate_cc_code(&s4o, symbol, FB_FUNCTION_PARAM"->"); symbol->fblock_body->accept(generate_cc_code); s4o.indent_left(); s4o.print(s4o.indent_spaces + "} // "); @@ -602,16 +620,20 @@ /* (A.3) Private internal variables */ s4o.print(s4o.indent_spaces + "// PROGRAM private variables - TEMP, private and located variables\n"); vardecl = new generate_cc_vardecl_c(&s4o, - generate_cc_vardecl_c::local_vf, - generate_cc_vardecl_c::temp_vt | - generate_cc_vardecl_c::private_vt | - generate_cc_vardecl_c::located_vt | - generate_cc_vardecl_c::external_vt); + generate_cc_vardecl_c::local_vf, + generate_cc_vardecl_c::temp_vt | + generate_cc_vardecl_c::private_vt | + generate_cc_vardecl_c::located_vt | + generate_cc_vardecl_c::external_vt); vardecl->print(symbol->var_declarations); delete vardecl; s4o.print("\n"); - /* (A.4) Program data structure type name. */ + /* (A.4) Generate private internal variables for SFC*/ + generate_cc_sfcdecl_c generate_cc_sfcdecl(&s4o); + symbol->function_block_body->accept(generate_cc_sfcdecl); + + /* (A.5) Program data structure type name. */ s4o.indent_left(); s4o.print("} "); symbol->program_type_name->accept(*this); @@ -643,7 +665,7 @@ s4o.print("\n"); /* (B.3) Function code */ - generate_cc_IL_and_ST_c generate_cc_code(&s4o, symbol, FB_FUNCTION_PARAM"->"); + generate_cc_SFC_IL_ST_c generate_cc_code(&s4o, symbol, FB_FUNCTION_PARAM"->"); symbol->function_block_body->accept(generate_cc_code); s4o.indent_left(); s4o.print(s4o.indent_spaces + "} // "); diff -r e8b99f896416 -r 38754701ac41 stage4/generate_cc/generate_cc_il.cc --- a/stage4/generate_cc/generate_cc_il.cc Tue Feb 20 18:17:21 2007 +0100 +++ b/stage4/generate_cc/generate_cc_il.cc Fri Feb 23 19:19:23 2007 +0100 @@ -319,6 +319,21 @@ il->accept(*this); } + /* Declare the backup to the default variable, that will store the result + * of the IL operations executed inside a parenthesis... + */ + void declare_backup_variable(void) { + s4o.print(s4o.indent_spaces); + s4o.print(IL_DEFVAR_T); + s4o.print(" "); + print_backup_variable(); + s4o.print(";\n"); + } + + void print_backup_variable(void) { + this->default_variable_back_name.accept(*this); + } + private: /* A helper function... */ /* @@ -458,15 +473,12 @@ /*| instruction_list il_instruction */ void *visit(instruction_list_c *symbol) { + /* Declare the backup to the default variable, that will store the result * of the IL operations executed inside a parenthesis... */ - s4o.print(s4o.indent_spaces); - s4o.print(IL_DEFVAR_T); - s4o.print(" "); - this->default_variable_back_name.accept(*this); - s4o.print(";\n"); - + declare_backup_variable(); + /* Declare the default variable, that will store the result of the IL operations... */ s4o.print(s4o.indent_spaces); s4o.print(IL_DEFVAR_T); diff -r e8b99f896416 -r 38754701ac41 stage4/generate_cc/generate_cc_sfc.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stage4/generate_cc/generate_cc_sfc.cc Fri Feb 23 19:19:23 2007 +0100 @@ -0,0 +1,567 @@ +/* + * (c) 2007 Mario de Sousa, Laurent Bessard + * + * Offered to the public under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * This code is made available on the understanding that it will not be + * used in safety-critical situations without a full and competent review. + */ + +/* + * An IEC 61131-3 IL and ST compiler. + * + * Based on the + * FINAL DRAFT - IEC 61131-3, 2nd Ed. (2001-12-10) + * + */ + + +/* + * Conversion of sfc networks (i.e. SFC code). + * + * This is part of the 4th stage that generates + * a c++ source program equivalent to the SFC, IL and ST + * code. + */ + + + +/***********************************************************************/ +/***********************************************************************/ +/***********************************************************************/ +/***********************************************************************/ + +class generate_cc_sfc_transitiontest_c: public generate_cc_base_c { + + private: + generate_cc_il_c *generate_cc_il; + generate_cc_st_c *generate_cc_st; + + public: + generate_cc_sfc_transitiontest_c(stage4out_c *s4o_ptr, symbol_c *scope, const char *variable_prefix = NULL) + : generate_cc_base_c(s4o_ptr) { + generate_cc_il = new generate_cc_il_c(s4o_ptr, scope, variable_prefix); + generate_cc_st = new generate_cc_st_c(s4o_ptr, scope, variable_prefix); + this->set_variable_prefix(variable_prefix); + } + + ~generate_cc_sfc_transitiontest_c(void) { + delete generate_cc_il; + delete generate_cc_st; + } + + void print_step_argument(symbol_c *step_name, const char* argument) { + print_variable_prefix(); + s4o.print("step_list["); + step_name->accept(*this); + s4o.print("]."); + s4o.print(argument); + } + + void print_reset_step(symbol_c *step_name) { + s4o.print(s4o.indent_spaces); + print_step_argument(step_name, "state"); + s4o.print(" = 0;\n" + s4o.indent_spaces + "if ("); + print_step_argument(step_name, "pulse"); + s4o.print(" != 1 {\n"); + s4o.indent_right(); + s4o.print(s4o.indent_spaces); + print_step_argument(step_name, "pulse"); + s4o.print(" = 2;\n"); + s4o.indent_left(); + s4o.print(s4o.indent_spaces + "}\n" + s4o.indent_spaces + "else {\n"); + s4o.indent_right(); + s4o.print(s4o.indent_spaces); + print_step_argument(step_name, "pulse"); + s4o.print(" = 0;\n"); + s4o.indent_left(); + s4o.print(s4o.indent_spaces + "}\n" + s4o.indent_spaces); + print_step_argument(step_name, "elapsed_time"); + s4o.print(" = __time_to_timespec(1, 0, 0, 0, 0, 0);"); + } + + void print_set_step(symbol_c *step_name) { + s4o.print(s4o.indent_spaces); + print_step_argument(step_name, "state"); + s4o.print(" = 1;\n" + s4o.indent_spaces); + print_step_argument(step_name, "pulse"); + s4o.print(" = 1;"); + } + + void print_steps_state_test(steps_c *symbol) { + if (symbol->step_name != NULL) { + print_step_argument(symbol->step_name, "state"); + } + if (symbol->step_name_list != NULL) { + for(int i = 0; i < ((list_c*)symbol->step_name_list)->n; i++) { + print_step_argument(((list_c*)symbol->step_name_list)->elements[i], "state"); + if (i < ((list_c*)symbol->step_name_list)->n - 1) { + s4o.print(" && "); + } + } + } + } + + void print_reset_steps(steps_c *symbol) { + if (symbol->step_name != NULL) { + print_reset_step(symbol->step_name); + s4o.print("\n"); + } + if (symbol->step_name_list != NULL) { + for(int i = 0; i < ((list_c*)symbol->step_name_list)->n; i++) { + print_reset_step(((list_c*)symbol->step_name_list)->elements[i]); + s4o.print("\n"); + } + } + } + + void print_set_steps(steps_c *symbol) { + if (symbol->step_name != NULL) { + print_set_step(symbol->step_name); + s4o.print("\n"); + } + if (symbol->step_name_list != NULL) { + for(int i = 0; i < ((list_c*)symbol->step_name_list)->n; i++) { + print_set_step(((list_c*)symbol->step_name_list)->elements[i]); + s4o.print("\n"); + } + } + } + +/*********************************************/ +/* B.1.6 Sequential function chart elements */ +/*********************************************/ + + void *visit(initial_step_c *symbol) {return NULL;} + + void *visit(step_c *symbol) {return NULL;} + + void *visit(transition_c *symbol) { + s4o.print(s4o.indent_spaces + "if ("); + print_steps_state_test((steps_c *)symbol->from_steps); + s4o.print(") {\n"); + s4o.indent_right(); + + // Calculate transition value + if (symbol->transition_condition_il != NULL) { + generate_cc_il->declare_backup_variable(); + s4o.print(s4o.indent_spaces); + symbol->transition_condition_il->accept(*generate_cc_il); + s4o.print("if ("); + generate_cc_il->print_backup_variable(); + s4o.print(") {\n"); + } + if (symbol->transition_condition_st != NULL) { + s4o.print(s4o.indent_spaces + "if ("); + symbol->transition_condition_st->accept(*generate_cc_st); + s4o.print(") {\n"); + } + + s4o.indent_right(); + print_reset_steps((steps_c *)symbol->from_steps); + print_set_steps((steps_c *)symbol->to_steps); + s4o.indent_left(); + + s4o.print(s4o.indent_spaces + "}\n"); + s4o.indent_left(); + s4o.print(s4o.indent_spaces + "}\n\n"); + return NULL; + } + + void *visit(action_c *symbol) {return NULL;} + +}; /* generate_cc_sfc_transitiontest_c */ + + + + +/***********************************************************************/ +/***********************************************************************/ +/***********************************************************************/ +/***********************************************************************/ + +class generate_cc_sfc_stepassociation_c: public generate_cc_base_c { + + private: + symbol_c *current_step; + symbol_c *current_action; + + public: + generate_cc_sfc_stepassociation_c(stage4out_c *s4o_ptr, symbol_c *scope, const char *variable_prefix = NULL) + : generate_cc_base_c(s4o_ptr) { + this->set_variable_prefix(variable_prefix); + } + + void print_step_argument(symbol_c *step_name, const char* argument) { + print_variable_prefix(); + s4o.print("step_list["); + step_name->accept(*this); + s4o.print("]."); + s4o.print(argument); + } + + void print_action_argument(symbol_c *action_name, const char* argument) { + print_variable_prefix(); + s4o.print("action_list["); + action_name->accept(*this); + s4o.print("]."); + s4o.print(argument); + } + +/*********************************************/ +/* B.1.6 Sequential function chart elements */ +/*********************************************/ + + void *visit(initial_step_c *symbol) { + s4o.print(s4o.indent_spaces + "// "); + symbol->step_name->accept(*this); + s4o.print(" action associations\n"); + current_step = symbol->step_name; + symbol->action_association_list->accept(*this); + return NULL; + } + + void *visit(step_c *symbol) { + s4o.print(s4o.indent_spaces + "// "); + symbol->step_name->accept(*this); + s4o.print(" action associations\n"); + current_step = symbol->step_name; + symbol->action_association_list->accept(*this); + return NULL; + } + + void *visit(transition_c *symbol) {return NULL;} + + void *visit(action_c *symbol) {return NULL;} + + void *visit(action_association_list_c* symbol) { + print_list(symbol, "", "\n", "\n\n"); + return NULL; + } + + void *visit(action_association_c *symbol) { + if (symbol->action_qualifier != NULL) { + current_action = symbol->action_name; + symbol->action_qualifier->accept(*this); + } + else { + s4o.print(s4o.indent_spaces + "if ("); + print_step_argument(current_step, "state"); + s4o.print(") {\n"); + s4o.indent_right(); + s4o.print(s4o.indent_spaces); + print_action_argument(symbol->action_name, "state"); + s4o.print(" = 1;\n"); + s4o.indent_left(); + s4o.print(s4o.indent_spaces + "}"); + } + return NULL; + } + + void *visit(action_qualifier_c *symbol) { + char *qualifier = (char *)symbol->action_qualifier->accept(*this); + + s4o.print(s4o.indent_spaces + "if ("); + if (strcmp(qualifier, "N") == 0) { + print_step_argument(current_step, "state"); + } + if (strcmp(qualifier, "P") == 0 || strcmp(qualifier, "SD") == 0 || + strcmp(qualifier, "DS") == 0 || strcmp(qualifier, "SL") == 0) { + print_step_argument(current_step, "pulse"); + s4o.print(" == 1"); + } + if (strcmp(qualifier, "D") == 0 || strcmp(qualifier, "L") == 0) { + print_step_argument(current_step, "state"); + s4o.print(" && "); + print_step_argument(current_step, "elapsed_time"); + if (strcmp(qualifier, "D") == 0) { + s4o.print(" >= "); + } + else { + s4o.print(" < "); + } + symbol->action_time->accept(*this); + } + s4o.print(") {\n"); + s4o.indent_right(); + s4o.print(s4o.indent_spaces); + if (strcmp(qualifier, "N") == 0 || strcmp(qualifier, "P") == 0 || + strcmp(qualifier, "D") == 0 || strcmp(qualifier, "L") == 0) { + print_action_argument(current_action, "state"); + s4o.print(" = 1;\n"); + } + if (strcmp(qualifier, "SD") == 0 || strcmp(qualifier, "DS") == 0 || + strcmp(qualifier, "SL") == 0) { + if (strcmp(qualifier, "SL") == 0) { + print_action_argument(current_action, "reset_remaining_time"); + } + else { + print_action_argument(current_action, "set_remaining_time"); + } + s4o.print(" = "); + symbol->action_time->accept(*this); + s4o.print(";\n"); + } + s4o.indent_left(); + s4o.print(s4o.indent_spaces + "}"); + if (strcmp(qualifier, "DS") == 0) { + print_step_argument(current_step, "pulse"); + s4o.print(" == 2) {\n"); + s4o.indent_right(); + s4o.print(s4o.indent_spaces); + print_action_argument(current_action, "set_remaining_time"); + s4o.print(" = __time_to_timespec(1, 0, 0, 0, 0, 0);\n"); + } + return NULL; + } + + void *visit(qualifier_c *symbol) { + return (void *)symbol->value; + } + + void *visit(timed_qualifier_c *symbol) { + return (void *)symbol->value; + } + +}; /* generate_cc_sfc_actiondecl_c */ + + + + +/***********************************************************************/ +/***********************************************************************/ +/***********************************************************************/ +/***********************************************************************/ + +class generate_cc_sfc_actionexecution_c: public generate_cc_base_c { + + private: + generate_cc_SFC_IL_ST_c *generate_cc_code; + + public: + generate_cc_sfc_actionexecution_c(stage4out_c *s4o_ptr, symbol_c *scope, const char *variable_prefix = NULL) + : generate_cc_base_c(s4o_ptr) { + generate_cc_code = new generate_cc_SFC_IL_ST_c(s4o_ptr, scope, variable_prefix); + this->set_variable_prefix(variable_prefix); + } + + ~generate_cc_sfc_actionexecution_c(void) { + delete generate_cc_code; + } + +/*********************************************/ +/* B.1.6 Sequential function chart elements */ +/*********************************************/ + + void *visit(initial_step_c *symbol) {return NULL;} + + void *visit(step_c *symbol) {return NULL;} + + void *visit(transition_c *symbol) {return NULL;} + + void *visit(action_c *symbol) { + s4o.print(s4o.indent_spaces + "if("); + print_variable_prefix(); + s4o.print("action_list["); + symbol->action_name->accept(*this); + s4o.print("].state) {"); + s4o.indent_right(); + + // generate action code + symbol->function_block_body->accept(*generate_cc_code); + + s4o.indent_left(); + s4o.print(s4o.indent_spaces + "}\n\n"); + return NULL; + } + +}; /* generate_cc_sfc_actiondecl_c */ + + + +/***********************************************************************/ +/***********************************************************************/ +/***********************************************************************/ +/***********************************************************************/ + +class generate_cc_sfc_c: public generate_cc_typedecl_c { + + private: + generate_cc_sfc_transitiontest_c *generate_cc_sfc_transitiontest; + generate_cc_sfc_stepassociation_c *generate_cc_sfc_stepassociation; + generate_cc_sfc_actionexecution_c *generate_cc_sfc_actionexecution; + + public: + generate_cc_sfc_c(stage4out_c *s4o_ptr, symbol_c *scope, const char *variable_prefix = NULL) + : generate_cc_typedecl_c(s4o_ptr) { + generate_cc_sfc_transitiontest = new generate_cc_sfc_transitiontest_c(s4o_ptr, scope, variable_prefix); + generate_cc_sfc_stepassociation = new generate_cc_sfc_stepassociation_c(s4o_ptr, scope, variable_prefix); + generate_cc_sfc_actionexecution = new generate_cc_sfc_actionexecution_c(s4o_ptr, scope, variable_prefix); + this->set_variable_prefix(variable_prefix); + } + + virtual ~generate_cc_sfc_c(void) { + delete generate_cc_sfc_transitiontest; + delete generate_cc_sfc_stepassociation; + delete generate_cc_sfc_actionexecution; + } + +/*********************************************/ +/* B.1.6 Sequential function chart elements */ +/*********************************************/ + + void *visit(sfc_network_c *symbol) { + s4o.print(s4o.indent_spaces +"INT i;\n\n"); + s4o.print(s4o.indent_spaces +"BOOL transition;\n\n"); + + /* generate step initilizations */ + s4o.print(s4o.indent_spaces + "// Steps initialisation\n"); + s4o.print(s4o.indent_spaces + "for (i = 0; i < "); + print_variable_prefix(); + s4o.print("nb_steps; i++) {\n"); + s4o.indent_right(); + s4o.print(s4o.indent_spaces); + print_variable_prefix(); + s4o.print("step_list[i].pulse = 0;\n"); + s4o.print(s4o.indent_spaces + "if ("); + print_variable_prefix(); + s4o.print("step_list[i].state) {\n"); + s4o.indent_right(); + s4o.print(s4o.indent_spaces); + print_variable_prefix(); + s4o.print("step_list[i].elapsed_time = __add_timespec("); + print_variable_prefix(); + s4o.print("step_list[i].elapsed_time, PERIOD);\n"); + s4o.indent_left(); + s4o.print(s4o.indent_spaces + "}\n"); + s4o.indent_left(); + s4o.print(s4o.indent_spaces + "}\n"); + + /* generate action initilizations */ + s4o.print(s4o.indent_spaces + "// Actions initialisation\n"); + s4o.print(s4o.indent_spaces + "for (i = 0; i < "); + print_variable_prefix(); + s4o.print("nb_actions; i++) {\n"); + s4o.indent_right(); + s4o.print(s4o.indent_spaces); + print_variable_prefix(); + s4o.print("action_list[i].state = 0;\n"); + s4o.print(s4o.indent_spaces); + print_variable_prefix(); + s4o.print("action_list[i].set = 0;\n"); + s4o.print(s4o.indent_spaces); + print_variable_prefix(); + s4o.print("action_list[i].reset = 0;\n"); + s4o.print(s4o.indent_spaces + "if ("); + print_variable_prefix(); + s4o.print("__compare_timespec(>, action_list[i].set_remaining_time, __time_to_timespec(1, 0, 0, 0, 0, 0)) {\n"); + s4o.indent_right(); + s4o.print(s4o.indent_spaces); + print_variable_prefix(); + s4o.print("action_list[i].set_remaining_time = __sub_timespec("); + print_variable_prefix(); + s4o.print("action_list[i].set_remaining_time, PERIOD);\n"); + s4o.print(s4o.indent_spaces + "if ("); + print_variable_prefix(); + s4o.print("__compare_timespec(<=, action_list[i].set_remaining_time, __time_to_timespec(1, 0, 0, 0, 0, 0)) {\n"); + s4o.indent_right(); + s4o.print(s4o.indent_spaces); + print_variable_prefix(); + s4o.print("action_list[i].set_remaining_time = __time_to_timespec(1, 0, 0, 0, 0, 0);\n"); + s4o.print(s4o.indent_spaces); + print_variable_prefix(); + s4o.print("action_list[i].set = 1;\n"); + s4o.indent_left(); + s4o.print(s4o.indent_spaces + "}\n"); + s4o.indent_left(); + s4o.print(s4o.indent_spaces + "}\n"); + s4o.print(s4o.indent_spaces + "if ("); + print_variable_prefix(); + s4o.print("__compare_timespec(>, action_list[i].reset_remaining_time, __time_to_timespec(1, 0, 0, 0, 0, 0)) {\n"); + s4o.indent_right(); + s4o.print(s4o.indent_spaces); + print_variable_prefix(); + s4o.print("action_list[i].reset_remaining_time = __sub_timespec("); + print_variable_prefix(); + s4o.print("action_list[i].reset_remaining_time, PERIOD);\n"); + s4o.print(s4o.indent_spaces + "if ("); + print_variable_prefix(); + s4o.print("__compare_timespec(<=, action_list[i].reset_remaining_time, __time_to_timespec(1, 0, 0, 0, 0, 0)) {\n"); + s4o.indent_right(); + s4o.print(s4o.indent_spaces); + print_variable_prefix(); + s4o.print("action_list[i].reset_remaining_time = __time_to_timespec(1, 0, 0, 0, 0, 0);\n"); + s4o.print(s4o.indent_spaces); + print_variable_prefix(); + s4o.print("action_list[i].reset = 1;\n"); + s4o.indent_left(); + s4o.print(s4o.indent_spaces + "}\n"); + s4o.indent_left(); + s4o.print(s4o.indent_spaces + "}\n"); + s4o.indent_left(); + s4o.print(s4o.indent_spaces + "}\n\n"); + + /* generate transition tests */ + s4o.print(s4o.indent_spaces + "// Transitions fire test\n"); + symbol->accept(*generate_cc_sfc_transitiontest); + s4o.print("\n"); + + /* generate step association */ + s4o.print(s4o.indent_spaces + "// Steps association\n"); + symbol->accept(*generate_cc_sfc_stepassociation); + s4o.print("\n"); + + /* generate action state evaluation */ + s4o.print(s4o.indent_spaces + "// Actions state evaluation\n"); + s4o.print(s4o.indent_spaces + "for (i = 0; i < "); + print_variable_prefix(); + s4o.print("nb_actions; i++) {\n"); + s4o.indent_right(); + s4o.print(s4o.indent_spaces + "if ("); + print_variable_prefix(); + s4o.print("action_list[i].set) {\n"); + s4o.indent_right(); + s4o.print(s4o.indent_spaces); + print_variable_prefix(); + s4o.print("action_list[i].stored = 1;\n"); + s4o.indent_left(); + s4o.print(s4o.indent_spaces + "}\n" + s4o.indent_spaces + "if ("); + print_variable_prefix(); + s4o.print("action_list[i].set) {\n"); + s4o.indent_right(); + s4o.print(s4o.indent_spaces); + print_variable_prefix(); + s4o.print("action_list[i].set_remaining_time = 0;\n" + s4o.indent_spaces); + print_variable_prefix(); + s4o.print("action_list[i].reset_remaining_time = 0;\n" + s4o.indent_spaces); + print_variable_prefix(); + s4o.print("action_list[i].stored = 0;\n"); + s4o.indent_left(); + s4o.print(s4o.indent_spaces + "}\n" + s4o.indent_spaces); + print_variable_prefix(); + s4o.print("action_list[i].state |= "); + print_variable_prefix(); + s4o.print("action_list[i].stored;\n"); + s4o.indent_left(); + s4o.print(s4o.indent_spaces + "}\n\n"); + + /* generate action execution */ + s4o.print(s4o.indent_spaces + "// Actions execution\n"); + symbol->accept(*generate_cc_sfc_actionexecution); + s4o.print("\n"); + + return NULL; + } + + void generate(sequential_function_chart_c *sfc) { + sfc->accept(*this); + } + +}; /* generate_cc_sfc_c */ diff -r e8b99f896416 -r 38754701ac41 stage4/generate_cc/generate_cc_sfcdecl.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stage4/generate_cc/generate_cc_sfcdecl.cc Fri Feb 23 19:19:23 2007 +0100 @@ -0,0 +1,235 @@ +/* + * (c) 2007 Mario de Sousa, Laurent Bessard + * + * Offered to the public under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * This code is made available on the understanding that it will not be + * used in safety-critical situations without a full and competent review. + */ + +/* + * An IEC 61131-3 IL and ST compiler. + * + * Based on the + * FINAL DRAFT - IEC 61131-3, 2nd Ed. (2001-12-10) + * + */ + + +/* + * Conversion of sfc networks (i.e. SFC code). + * + * This is part of the 4th stage that generates + * a c++ source program equivalent to the SFC, IL and ST + * code. + */ + + + + +/***********************************************************************/ +/***********************************************************************/ +/***********************************************************************/ +/***********************************************************************/ + +class generate_cc_sfc_stepdecl_c: public generate_cc_base_c { + + private: + char step_number; + + public: + generate_cc_sfc_stepdecl_c(stage4out_c *s4o_ptr): generate_cc_base_c(s4o_ptr) {} + ~generate_cc_sfc_stepdecl_c(void) {} + + void reset_step_number(void) {step_number = 0;} + char get_step_number(void) {return step_number;} + void increment_step_number(void) {step_number++;} + void print_step_number(void) { + char str[10]; + sprintf(str, "%d", step_number); + s4o.print(str); + } + +/*********************************************/ +/* B.1.6 Sequential function chart elements */ +/*********************************************/ + + void *visit(initial_step_c *symbol) { + s4o.print("#define "); + symbol->step_name->accept(*this); + s4o.print(" "); + print_step_number(); + s4o.print("\n"); + increment_step_number(); + return NULL; + } + + void *visit(step_c *symbol) { + s4o.print("#define "); + symbol->step_name->accept(*this); + s4o.print(" "); + print_step_number(); + s4o.print("\n"); + increment_step_number(); + return NULL; + } + + void *visit(transition_c *symbol) {return NULL;} + + void *visit(action_c *symbol) {return NULL;} + +}; /* generate_cc_sfc_stepdecl_c */ + + + + +/***********************************************************************/ +/***********************************************************************/ +/***********************************************************************/ +/***********************************************************************/ + +class generate_cc_sfc_actiondecl_c: public generate_cc_base_c { + + private: + char action_number; + + public: + generate_cc_sfc_actiondecl_c(stage4out_c *s4o_ptr): generate_cc_base_c(s4o_ptr) {} + ~generate_cc_sfc_actiondecl_c(void) {} + + void reset_action_number(void) {action_number = 0;} + char get_action_number(void) {return action_number;} + void increment_action_number(void) {action_number++;} + void print_action_number(void) { + char str[10]; + sprintf(str, "%d", action_number); + s4o.print(str); + } + +/*********************************************/ +/* B.1.6 Sequential function chart elements */ +/*********************************************/ + + void *visit(initial_step_c *symbol) {return NULL;} + + void *visit(step_c *symbol) {return NULL;} + + void *visit(transition_c *symbol) {return NULL;} + + void *visit(action_c *symbol) { + s4o.print("#define "); + symbol->action_name->accept(*this); + s4o.print(" "); + print_action_number(); + s4o.print("\n"); + increment_action_number(); + return NULL; + } + +}; /* generate_cc_sfc_actiondecl_c */ + + + +/***********************************************************************/ +/***********************************************************************/ +/***********************************************************************/ +/***********************************************************************/ + +class generate_cc_sfcdecl_c: public iterator_visitor_c { + + protected: + stage4out_c &s4o; + + private: + generate_cc_sfc_stepdecl_c *generate_cc_sfc_stepdecl; + generate_cc_sfc_actiondecl_c *generate_cc_sfc_actiondecl; + + public: + generate_cc_sfcdecl_c(stage4out_c *s4o_ptr) : s4o(*s4o_ptr) { + generate_cc_sfc_stepdecl = new generate_cc_sfc_stepdecl_c(s4o_ptr); + generate_cc_sfc_actiondecl = new generate_cc_sfc_actiondecl_c(s4o_ptr); + } + + virtual ~generate_cc_sfcdecl_c(void) { + delete generate_cc_sfc_stepdecl; + delete generate_cc_sfc_actiondecl; + } + + public: + +/*********************************************/ +/* B.1.6 Sequential function chart elements */ +/*********************************************/ + + /*| sequential_function_chart sfc_network*/ + void *visit(sfc_network_c *symbol) { + char i; + + /* generate step number definitions */ + s4o.print(s4o.indent_spaces + "// Steps declaration\n"); + generate_cc_sfc_stepdecl->reset_step_number(); + symbol->accept(*generate_cc_sfc_stepdecl); + s4o.print("\n" + s4o.indent_spaces + "nb_steps = "); + generate_cc_sfc_stepdecl->print_step_number(); + s4o.print(";\n" + s4o.indent_spaces + "STEP step_list["); + generate_cc_sfc_stepdecl->print_step_number(); + s4o.print("] = {\n"); + s4o.indent_right(); + for (i = 0; i < generate_cc_sfc_stepdecl->get_step_number(); i++) { + if (i == 0) { + s4o.print(s4o.indent_spaces + "{1, 0, 0}"); + } + else { + s4o.print(",\n" + s4o.indent_spaces + "{0, 0, 0}"); + } + } + s4o.indent_left(); + s4o.print("\n" + s4o.indent_spaces + "};\n\n"); + + /* generate action number definitions */ + s4o.print(s4o.indent_spaces + "// Actions declaration\n"); + generate_cc_sfc_actiondecl->reset_action_number(); + symbol->accept(*generate_cc_sfc_actiondecl); + s4o.print("\n" + s4o.indent_spaces + "nb_actions = "); + generate_cc_sfc_actiondecl->print_action_number(); + s4o.print(";\n" + s4o.indent_spaces + "STEP step_list["); + generate_cc_sfc_actiondecl->print_action_number(); + s4o.print("] = {\n"); + s4o.indent_right(); + for (i = 0; i < generate_cc_sfc_actiondecl->get_action_number(); i++) { + if (i == 0) { + s4o.print(s4o.indent_spaces + "{0, 0, 0, 0, 0, 0}"); + } + else { + s4o.print(",\n" + s4o.indent_spaces + "{0, 0, 0, 0, 0, 0}"); + } + } + s4o.indent_left(); + s4o.print("\n" + s4o.indent_spaces + "};\n\n"); + + return NULL; + } + +/***********************************/ +/* B 2.1 Instructions and Operands */ +/***********************************/ +/*| instruction_list il_instruction */ + void *visit(instruction_list_c *symbol) {return NULL;} + +/***************************************/ +/* B.3 - Language ST (Structured Text) */ +/***************************************/ +/********************/ +/* B 3.2 Statements */ +/********************/ +void *visit(statement_list_c *symbol) {return NULL;} + +/* Remainder implemented in generate_cc_sfcdecl_c... */ +}; diff -r e8b99f896416 -r 38754701ac41 stage4/generate_cc/generate_cc_vardecl.cc --- a/stage4/generate_cc/generate_cc_vardecl.cc Tue Feb 20 18:17:21 2007 +0100 +++ b/stage4/generate_cc/generate_cc_vardecl.cc Fri Feb 23 19:19:23 2007 +0100 @@ -82,15 +82,15 @@ str1 = s1; str2 = s2; print_flag = false; - embedded_scope = NULL; + embedded_scope = NULL; } std::string get(void) { if (NULL != embedded_scope) - return embedded_scope->get(); + return embedded_scope->get(); bool old_print_flag = print_flag; - print_flag = true; + print_flag = true; if (!old_print_flag) return str1; else @@ -103,21 +103,21 @@ */ void push(std::string s1, std::string s2) { if (NULL != embedded_scope) - return embedded_scope->push(s1, s2); + return embedded_scope->push(s1, s2); embedded_scope = new next_var_c(s1, s2); - if (NULL == embedded_scope) - ERROR; - return; + if (NULL == embedded_scope) + ERROR; + return; } /* Remove the inner-most scope... */ void pop(void) { if (NULL != embedded_scope) - return embedded_scope->pop(); - - delete embedded_scope; - embedded_scope = NULL; + return embedded_scope->pop(); + + delete embedded_scope; + embedded_scope = NULL; } }; @@ -285,16 +285,16 @@ for(int i = 0; i < list->n; i++) { s4o.print(s4o.indent_spaces); if (wanted_varformat != init_vf) { - this->current_var_type_symbol->accept(*this); + this->current_var_type_symbol->accept(*this); s4o.print(" "); - } - this->print_variable_prefix(); + } + this->print_variable_prefix(); list->elements[i]->accept(*this); if (wanted_varformat != local_vf) { if (this->current_var_init_symbol != NULL) { s4o.print(" = "); this->current_var_init_symbol->accept(*this); - } + } } s4o.print(";\n"); } @@ -366,7 +366,7 @@ case finterface_vf: /* fall through... */ case localinit_vf: /* fall through... */ case local_vf: nv = new next_var_c("", ", "); break; - default: nv = NULL; + default: nv = NULL; } /* switch() */ symbol->accept(*this); diff -r e8b99f896416 -r 38754701ac41 stage4/generate_cc/search_expression_type.cc --- a/stage4/generate_cc/search_expression_type.cc Tue Feb 20 18:17:21 2007 +0100 +++ b/stage4/generate_cc/search_expression_type.cc Fri Feb 23 19:19:23 2007 +0100 @@ -71,6 +71,7 @@ if (typeid(*type_symbol) == typeid(ulint_type_name_c)) {return true;} if (typeid(*type_symbol) == typeid(real_type_name_c)) {return true;} if (typeid(*type_symbol) == typeid(lreal_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(bool_type_name_c)) {return true;} if (typeid(*type_symbol) == typeid(byte_type_name_c)) {return true;} if (typeid(*type_symbol) == typeid(word_type_name_c)) {return true;} if (typeid(*type_symbol) == typeid(dword_type_name_c)) {return true;} diff -r e8b99f896416 -r 38754701ac41 stage4/generate_iec/generate_iec.cc --- a/stage4/generate_iec/generate_iec.cc Tue Feb 20 18:17:21 2007 +0100 +++ b/stage4/generate_iec/generate_iec.cc Fri Feb 23 19:19:23 2007 +0100 @@ -1118,7 +1118,7 @@ /* TRANSITION [transition_name] ['(' 'PRIORITY' ':=' integer ')'] * FROM steps TO steps - * transition_condition + * ':' simple_instr_list | ':=' expression * END_TRANSITION */ void *visit(transition_c *symbol) { @@ -1139,10 +1139,15 @@ symbol->to_steps->accept(*this); s4o.indent_right(); if (symbol->transition_condition_il != NULL) { - symbol->transition_condition_il->accept(*this); + s4o.print(":\n"); + symbol->transition_condition_il->accept(*this); } if (symbol->transition_condition_st != NULL) { - symbol->transition_condition_st->accept(*this); + s4o.print("\n"); + s4o.print(s4o.indent_spaces); + s4o.print(":= "); + symbol->transition_condition_st->accept(*this); + s4o.print(";\n"); } s4o.indent_left(); s4o.print(s4o.indent_spaces); @@ -1167,22 +1172,6 @@ return NULL; } -/* ':' simple_instr_list | ':=' expression */ -void *visit(transition_condition_c *symbol) { - if (symbol->simple_instr_list != NULL) { - s4o.print(":\n"); - symbol->simple_instr_list->accept(*this); - } - if (symbol->expression != NULL) { - s4o.print("\n"); - s4o.print(s4o.indent_spaces); - s4o.print(":= "); - symbol->expression->accept(*this); - s4o.print(";\n"); - } - return NULL; -} - /* ACTION action_name ':' function_block_body END_ACTION */ void *visit(action_c *symbol) { s4o.print(s4o.indent_spaces);