Add support for Stepname.X syntax.
--- a/lib/iec_types_all.h Sat May 31 12:49:43 2014 +0100
+++ b/lib/iec_types_all.h Sat May 31 16:22:57 2014 +0100
@@ -126,11 +126,12 @@
__ANY(__DECLARE_IEC_TYPE)
typedef struct {
- __IEC_BOOL_t state; // current step state. 0 : inative, 1: active
+ __IEC_BOOL_t X; // state; --> current step state. 0 : inative, 1: active. We name it 'X' as it may be accessed from IEC 61131.3 code using stepname.X syntax!!
BOOL prev_state; // previous step state. 0 : inative, 1: active
- TIME elapsed_time; // time since step is active
+ TIME elapsed_time; // T; // elapsed_time; --> time since step is active. We name it 'T' as it may be accessed from IEC 61131.3 code using stepname.T syntax!!
} STEP;
+
typedef struct {
BOOL stored; // action storing state. 0 : not stored, 1: stored
__IEC_BOOL_t state; // current action state. 0 : inative, 1: active
--- a/stage4/generate_c/generate_c_sfc.cc Sat May 31 12:49:43 2014 +0100
+++ b/stage4/generate_c/generate_c_sfc.cc Sat May 31 16:22:57 2014 +0100
@@ -110,10 +110,8 @@
void print_step_argument(symbol_c *step_name, const char* argument, bool setter=false) {
print_variable_prefix();
if (setter) s4o.print(",");
- s4o.print("__step_list[");
- s4o.print(SFC_STEP_ACTION_PREFIX);
- step_name->accept(*this);
- s4o.print("].");
+ step_name->accept(*this); // in the generated C code, the 'step_name' will have been previously #define'd as equiv to '__step_list[<step_number>]", so now we simply print out the name!
+ s4o.print(".");
s4o.print(argument);
}
@@ -135,7 +133,7 @@
s4o.print(s4o.indent_spaces);
s4o.print(SET_VAR);
s4o.print("(");
- print_step_argument(step_name, "state", true);
+ print_step_argument(step_name, "X", true);
s4o.print(",,0);\n");
}
@@ -143,7 +141,7 @@
s4o.print(s4o.indent_spaces);
s4o.print(SET_VAR);
s4o.print("(");
- print_step_argument(step_name, "state", true);
+ print_step_argument(step_name, "X", true);
s4o.print(",,1);\n" + s4o.indent_spaces);
print_step_argument(step_name, "elapsed_time");
s4o.print(" = __time_to_timespec(1, 0, 0, 0, 0, 0);\n");
@@ -166,21 +164,21 @@
s4o.print(s4o.indent_spaces + "char activated = ");
s4o.print(GET_VAR);
s4o.print("(");
- print_step_argument(current_step, "state");
+ print_step_argument(current_step, "X");
s4o.print(") && !");
print_step_argument(current_step, "prev_state");
s4o.print(";\n");
s4o.print(s4o.indent_spaces + "char desactivated = !");
s4o.print(GET_VAR);
s4o.print("(");
- print_step_argument(current_step, "state");
+ print_step_argument(current_step, "X");
s4o.print(") && ");
print_step_argument(current_step, "prev_state");
s4o.print(";\n");
s4o.print(s4o.indent_spaces + "char active = ");
s4o.print(GET_VAR);
s4o.print("(");
- print_step_argument(current_step, "state");
+ print_step_argument(current_step, "X");
s4o.print(");\n");
symbol->action_association_list->accept(*this);
s4o.indent_left();
@@ -207,21 +205,21 @@
s4o.print(s4o.indent_spaces + "activated = ");
s4o.print(GET_VAR);
s4o.print("(");
- print_step_argument(current_step, "state");
+ print_step_argument(current_step, "X");
s4o.print(") && !");
print_step_argument(current_step, "prev_state");
s4o.print(";\n");
s4o.print(s4o.indent_spaces + "desactivated = !");
s4o.print(GET_VAR);
s4o.print("(");
- print_step_argument(current_step, "state");
+ print_step_argument(current_step, "X");
s4o.print(") && ");
print_step_argument(current_step, "prev_state");
s4o.print(";\n");
s4o.print(s4o.indent_spaces + "active = ");
s4o.print(GET_VAR);
s4o.print("(");
- print_step_argument(current_step, "state");
+ print_step_argument(current_step, "X");
s4o.print(");\n");
symbol->action_association_list->accept(*this);
s4o.indent_left();
@@ -437,7 +435,7 @@
case transitiontest_sg:
s4o.print(GET_VAR);
s4o.print("(");
- print_step_argument(symbol->step_name, "state");
+ print_step_argument(symbol->step_name, "X");
s4o.print(")");
break;
case stepset_sg:
@@ -462,7 +460,7 @@
for(int i = 0; i < symbol->n; i++) {
s4o.print(GET_VAR);
s4o.print("(");
- print_step_argument(symbol->elements[i], "state");
+ print_step_argument(symbol->elements[i], "X");
s4o.print(")");
if (i < symbol->n - 1) {
s4o.print(" && ");
@@ -507,7 +505,7 @@
s4o.print(s4o.indent_spaces + "if (");
s4o.print(GET_VAR);
s4o.print("(");
- print_step_argument(current_step, "state");
+ print_step_argument(current_step, "X");
s4o.print(")) {\n");
s4o.indent_right();
s4o.print(s4o.indent_spaces);
@@ -744,12 +742,12 @@
s4o.print(GET_VAR);
s4o.print("(");
print_variable_prefix();
- s4o.print("__step_list[i].state);\n");
+ s4o.print("__step_list[i].X);\n");
s4o.print(s4o.indent_spaces + "if (");
s4o.print(GET_VAR);
s4o.print("(");
print_variable_prefix();
- s4o.print("__step_list[i].state)) {\n");
+ s4o.print("__step_list[i].X)) {\n");
s4o.indent_right();
s4o.print(s4o.indent_spaces);
print_variable_prefix();
--- a/stage4/generate_c/generate_c_sfcdecl.cc Sat May 31 12:49:43 2014 +0100
+++ b/stage4/generate_c/generate_c_sfcdecl.cc Sat May 31 16:22:57 2014 +0100
@@ -252,11 +252,17 @@
print_variable_prefix();
s4o.print(",__step_list[");
s4o.print(step_number);
- s4o.print("].state,,1);\n");
+ s4o.print("].X,,1);\n");
step_number++;
break;
case stepdef_sd:
s4o.print("#define ");
+ symbol->step_name->accept(*this);
+ s4o.print(" __step_list[");
+ s4o.print(step_number);
+ s4o.print("]\n");
+
+ s4o.print("#define ");
s4o.print(SFC_STEP_ACTION_PREFIX);
symbol->step_name->accept(*this);
s4o.print(" ");
@@ -266,6 +272,10 @@
break;
case stepundef_sd:
s4o.print("#undef ");
+ symbol->step_name->accept(*this);
+ s4o.print("\n");
+
+ s4o.print("#undef ");
s4o.print(SFC_STEP_ACTION_PREFIX);
symbol->step_name->accept(*this);
s4o.print("\n");
@@ -289,6 +299,12 @@
break;
case stepdef_sd:
s4o.print("#define ");
+ symbol->step_name->accept(*this);
+ s4o.print(" __step_list[");
+ s4o.print(step_number);
+ s4o.print("]\n");
+
+ s4o.print("#define ");
s4o.print(SFC_STEP_ACTION_PREFIX);
symbol->step_name->accept(*this);
s4o.print(" ");
@@ -298,6 +314,10 @@
break;
case stepundef_sd:
s4o.print("#undef ");
+ symbol->step_name->accept(*this);
+ s4o.print("\n");
+
+ s4o.print("#undef ");
s4o.print(SFC_STEP_ACTION_PREFIX);
symbol->step_name->accept(*this);
s4o.print("\n");
--- a/stage4/generate_c/generate_c_st.cc Sat May 31 12:49:43 2014 +0100
+++ b/stage4/generate_c/generate_c_st.cc Sat May 31 16:22:57 2014 +0100
@@ -211,8 +211,7 @@
symbol->accept(*this);
s4o.print(",");
s4o.print(",");
- }
- else {
+ } else {
print_variable_prefix();
s4o.print(",");
wanted_variablegeneration = complextype_base_vg;
@@ -334,7 +333,19 @@
switch (wanted_variablegeneration) {
case complextype_base_vg:
symbol->record_variable->accept(*this);
- if ( get_datatype_info_c::is_function_block(symbol->record_variable->datatype)) {
+ /* NOTE: The following test includes a special case for SFC Steps. They are currently mapped onto a C data structure
+ * that does not follow the standard IEC_<typename> pattern used for user defined structure datatypes
+ * (i.e. it does not include the 'values' and 'flag' structure
+ * elements that are tested by __GET_VAR and __SET_VAR acessor macros defined in acessor.h). However, the
+ * STEP.T and STEP.X elements of this step structure are of the IEC_BOOL and IEC_TIME datatypes, and are
+ * actually structures that do have the 'value' and 'flags' elements. So, it is safe to say that any variable
+ * that is a STEPname is not of a complex type, as its .T and .X elements are and can later be safely accessed
+ * using the __SET_VAR and __GET_VAR macros.
+ *
+ * For the above reason, a STEP must be handled as a FB, i.e. it does NOT contain the 'flags' and 'value' elements!
+ */
+ if ( get_datatype_info_c::is_function_block(symbol->record_variable->datatype)
+ || get_datatype_info_c::is_sfc_step (symbol->record_variable->datatype)) {
if (NULL == symbol->record_variable->scope) ERROR;
search_var_instance_decl_c search_var_instance_decl(symbol->record_variable->scope);
if (search_var_instance_decl_c::external_vt == search_var_instance_decl.get_vartype(get_var_name_c::get_last_field(symbol->record_variable)))
@@ -346,7 +357,9 @@
break;
case complextype_suffix_vg:
symbol->record_variable->accept(*this);
- if (!get_datatype_info_c::is_function_block(symbol->record_variable->datatype)) { // if the record variable is not a FB, then it will certainly be a structure!
+ // the following condition MUST be a negation of the above condition used in the 'case complextype_base_vg:'
+ if (!( get_datatype_info_c::is_function_block(symbol->record_variable->datatype) // if the record variable is not a FB...
+ || get_datatype_info_c::is_sfc_step (symbol->record_variable->datatype))) { // ...nor an SFC step name, then it will certainly be a structure!
s4o.print(".");
symbol->field_selector->accept(*this);
}