--- a/absyntax/absyntax.def Mon Jan 06 12:25:21 2014 +0000
+++ b/absyntax/absyntax.def Tue Feb 11 10:55:27 2014 +0000
@@ -862,6 +862,10 @@
/* enumvalue_symtable is filled in by enum_declaration_check_c, during stage3 semantic verification, with a list of all enumerated constants declared inside this POU */
SYM_REF5(configuration_declaration_c, configuration_name, global_var_declarations, resource_declarations, access_declarations, instance_specific_initializations, enumvalue_symtable_t enumvalue_symtable;)
+/* intermediate helper symbol for configuration_declaration */
+/* { global_var_declarations_list } */
+SYM_LIST(global_var_declarations_list_c)
+
/* helper symbol for configuration_declaration */
SYM_LIST(resource_declaration_list_c)
--- a/absyntax_utils/get_datatype_info.cc Mon Jan 06 12:25:21 2014 +0000
+++ b/absyntax_utils/get_datatype_info.cc Tue Feb 11 10:55:27 2014 +0000
@@ -292,7 +292,7 @@
bool get_datatype_info_c::is_subrange(symbol_c *type_symbol) {
- symbol_c *type_decl = search_base_type_c::get_basetype_decl(type_symbol); /* NOTE: will work correctly once we update the way search_base_type_c works, by adding a new search_effective_type:c */
+ symbol_c *type_decl = search_base_type_c::get_equivtype_decl(type_symbol); /* NOTE: do NOT call search_base_type_c !! */
if (NULL == type_decl) {return false;}
if (typeid(*type_decl) == typeid(subrange_type_declaration_c)) {return true;} /* subrange_type_name ':' subrange_spec_init */
--- a/absyntax_utils/search_base_type.cc Mon Jan 06 12:25:21 2014 +0000
+++ b/absyntax_utils/search_base_type.cc Tue Feb 11 10:55:27 2014 +0000
@@ -54,7 +54,7 @@
-search_base_type_c::search_base_type_c(void) {current_type_name = NULL; current_basetype = NULL;}
+search_base_type_c::search_base_type_c(void) {current_basetype_name = NULL; current_basetype = NULL; current_equivtype = NULL;}
/* static method! */
void search_base_type_c::create_singleton(void) {
@@ -63,11 +63,25 @@
}
/* static method! */
+symbol_c *search_base_type_c::get_equivtype_decl(symbol_c *symbol) {
+ create_singleton();
+ if (NULL == symbol) return NULL;
+ search_base_type_singleton->current_basetype_name = NULL;
+ search_base_type_singleton->current_basetype = NULL;
+ search_base_type_singleton->current_equivtype = NULL;
+ symbol_c *basetype = (symbol_c *)symbol->accept(*search_base_type_singleton);
+ if (NULL != search_base_type_singleton->current_equivtype)
+ return search_base_type_singleton->current_equivtype;
+ return basetype;
+}
+
+/* static method! */
symbol_c *search_base_type_c::get_basetype_decl(symbol_c *symbol) {
create_singleton();
if (NULL == symbol) return NULL;
- search_base_type_singleton->current_type_name = NULL;
+ search_base_type_singleton->current_basetype_name = NULL;
search_base_type_singleton->current_basetype = NULL;
+ search_base_type_singleton->current_equivtype = NULL;
return (symbol_c *)symbol->accept(*search_base_type_singleton);
}
@@ -75,10 +89,11 @@
symbol_c *search_base_type_c::get_basetype_id (symbol_c *symbol) {
create_singleton();
if (NULL == symbol) return NULL;
- search_base_type_singleton->current_type_name = NULL;
+ search_base_type_singleton->current_basetype_name = NULL;
search_base_type_singleton->current_basetype = NULL;
+ search_base_type_singleton->current_equivtype = NULL;
symbol->accept(*search_base_type_singleton);
- return (symbol_c *)search_base_type_singleton->current_type_name;
+ return (symbol_c *)search_base_type_singleton->current_basetype_name;
}
@@ -93,7 +108,7 @@
void *search_base_type_c::visit(identifier_c *type_name) {
symbol_c *type_decl;
- this->current_type_name = type_name;
+ this->current_basetype_name = type_name;
/* if we have reached this point, it is because the current_basetype is not yet pointing to the base datatype we are looking for,
* so we will be searching for the delcaration of the type named in type_name, which might be the base datatype (we search recursively!)
*/
@@ -210,16 +225,21 @@
/* subrange_type_name ':' subrange_spec_init */
void *search_base_type_c::visit(subrange_type_declaration_c *symbol) {
+ this->current_equivtype = symbol;
return symbol->subrange_spec_init->accept(*this);
}
/* subrange_specification ASSIGN signed_integer */
void *search_base_type_c::visit(subrange_spec_init_c *symbol) {
+ if (NULL == this->current_equivtype)
+ this->current_equivtype = symbol;
return symbol->subrange_specification->accept(*this);
}
/* integer_type_name '(' subrange')' */
void *search_base_type_c::visit(subrange_specification_c *symbol) {
+ if (NULL == this->current_equivtype)
+ this->current_equivtype = symbol;
return symbol->integer_type_name->accept(*this);
}
@@ -228,7 +248,7 @@
/* enumerated_type_name ':' enumerated_spec_init */
void *search_base_type_c::visit(enumerated_type_declaration_c *symbol) {
- this->current_type_name = symbol->enumerated_type_name;
+ this->current_basetype_name = symbol->enumerated_type_name;
/* NOTE: We want search_base_type_c to return a enumerated_type_declaration_c as the base datatpe if possible
* (i.e. if it is a named datatype declared inside a TYPE ... END_TYPE declarations, as opposed to an
* anonymous datatype declared in a VAR ... AND_VAR declaration).
@@ -266,7 +286,7 @@
/* identifier ':' array_spec_init */
void *search_base_type_c::visit(array_type_declaration_c *symbol) {
- this->current_type_name = symbol->identifier;
+ this->current_basetype_name = symbol->identifier;
return symbol->array_spec_init->accept(*this);
}
@@ -303,7 +323,7 @@
* structure_element_declaration_list_c
*/
void *search_base_type_c::visit(structure_type_declaration_c *symbol) {
- this->current_type_name = symbol->structure_type_name;
+ this->current_basetype_name = symbol->structure_type_name;
return symbol->structure_specification->accept(*this);
}
@@ -370,14 +390,14 @@
/* INITIAL_STEP step_name ':' action_association_list END_STEP */
// SYM_REF2(initial_step_c, step_name, action_association_list)
void *search_base_type_c::visit(initial_step_c *symbol) {
- this->current_type_name = NULL; /* this pseudo data type does not have a type name! */
+ this->current_basetype_name = NULL; /* this pseudo data type does not have a type name! */
return (void *)symbol;
}
/* STEP step_name ':' action_association_list END_STEP */
// SYM_REF2(step_c, step_name, action_association_list)
void *search_base_type_c::visit(step_c *symbol) {
- this->current_type_name = NULL; /* this pseudo data type does not have a type name! */
+ this->current_basetype_name = NULL; /* this pseudo data type does not have a type name! */
return (void *)symbol;
}
--- a/absyntax_utils/search_base_type.hh Mon Jan 06 12:25:21 2014 +0000
+++ b/absyntax_utils/search_base_type.hh Tue Feb 11 10:55:27 2014 +0000
@@ -31,19 +31,35 @@
*/
-/* Determine the data type on which another data type is based on.
- * If a new default initial value is given, we DO NOT consider it a
- * new base class, and continue looking further!
- *
- * E.g. TYPE new_int_t : INT; END_TYPE;
- * TYPE new_int2_t : INT = 2; END_TYPE;
- * TYPE new_subr_t : INT (4..5); END_TYPE;
- *
- * new_int_t is really an INT!!
- * new_int2_t is also really an INT!!
- * new_subr_t is also really an INT!!
- *
- * Note that a FB declaration is also considered a base type, as
+/* Determine the data type on which another data type is based on. */
+
+/*
+ * What is a Base Type?
+ * A base type is the fundamental data type from which the type is derived.
+ * The main idea is that if two datatyes (A and B) share a common base type,
+ * then these two datatypes may be used interchangeably in an expression.
+ *
+ * What is an Equivalent Type?
+ * An equivalent type is the data type from which the type is derived.
+ * The Base type and the Equivalent type will always be the same, with the
+ * exception of subranges!
+ *
+ * E.g. TYPE new_int_t : INT; END_TYPE;
+ * TYPE new_int2_t : INT := 2; END_TYPE;
+ * TYPE new_int3_t : new_int2_t := 3; END_TYPE;
+ * TYPE new_sub_t : INT (4..10); END_TYPE;
+ * TYPE new_sub2_t : new_sub_t := 5 ; END_TYPE;
+ * TYPE new_sub3_t : new_sub2_t := 6 ; END_TYPE;
+ * TYPE new_sub4_t : new_int3_t (4..10); END_TYPE; <----- This is NOT legal syntax!
+ *
+ * new_int_t : base type->INT equivalent type->INT
+ * new_int2_t : base type->INT equivalent type->INT
+ * new_int3_t : base type->INT equivalent type->INT
+ * new_sub_t : base type->INT equivalent type->new_sub_t
+ * new_sub2_t : base type->INT equivalent type->new_sub_t
+ * new_sub3_t : base type->INT equivalent type->new_sub_t
+ *
+ * Note too that a FB declaration is also considered a base type, as
* we may have FB instances declared of a specific FB type.
*/
@@ -51,8 +67,9 @@
class search_base_type_c: public null_visitor_c {
private:
- symbol_c *current_type_name;
+ symbol_c *current_basetype_name;
symbol_c *current_basetype;
+ symbol_c *current_equivtype;
static search_base_type_c *search_base_type_singleton; // Make this a singleton class!
private:
@@ -60,8 +77,9 @@
public:
search_base_type_c(void);
- static symbol_c *get_basetype_decl (symbol_c *symbol);
- static symbol_c *get_basetype_id (symbol_c *symbol);
+ static symbol_c *get_equivtype_decl(symbol_c *symbol); /* get the Equivalent Type declaration */
+ static symbol_c *get_basetype_decl (symbol_c *symbol); /* get the Base Type declaration */
+ static symbol_c *get_basetype_id (symbol_c *symbol); /* get the Base Type identifier */
public:
/*************************/
--- a/stage1_2/iec_bison.yy Mon Jan 06 12:25:21 2014 +0000
+++ b/stage1_2/iec_bison.yy Tue Feb 11 10:55:27 2014 +0000
@@ -1046,7 +1046,7 @@
// - configuration_declaration
// - resource_declaration
//
-%type <leaf> optional_global_var_declarations
+%type <list> global_var_declarations_list
// helper symbol for configuration_declaration
%type <leaf> optional_access_declarations
// helper symbol for configuration_declaration
@@ -5563,7 +5563,7 @@
configuration_declaration:
CONFIGURATION configuration_name
- optional_global_var_declarations
+ global_var_declarations_list
single_resource_declaration
{variable_name_symtable.pop();
direct_variable_symtable.pop();}
@@ -5576,7 +5576,7 @@
direct_variable_symtable.pop();
}
| CONFIGURATION configuration_name
- optional_global_var_declarations
+ global_var_declarations_list
resource_declaration_list
optional_access_declarations
optional_instance_specific_initializations
@@ -5588,7 +5588,7 @@
}
/* ERROR_CHECK_BEGIN */
| CONFIGURATION
- optional_global_var_declarations
+ global_var_declarations_list
single_resource_declaration
{variable_name_symtable.pop();
direct_variable_symtable.pop();}
@@ -5597,14 +5597,14 @@
END_CONFIGURATION
{$$ = NULL; print_err_msg(locl(@1), locf(@2), "no configuration name defined in configuration declaration."); yynerrs++;}
| CONFIGURATION
- optional_global_var_declarations
+ global_var_declarations_list
resource_declaration_list
optional_access_declarations
optional_instance_specific_initializations
END_CONFIGURATION
{$$ = NULL; print_err_msg(locl(@1), locf(@2), "no configuration name defined in configuration declaration."); yynerrs++;}
| CONFIGURATION error
- optional_global_var_declarations
+ global_var_declarations_list
single_resource_declaration
{variable_name_symtable.pop();
direct_variable_symtable.pop();}
@@ -5613,27 +5613,27 @@
END_CONFIGURATION
{$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid configuration name defined in configuration declaration."); yyerrok;}
| CONFIGURATION error
- optional_global_var_declarations
+ global_var_declarations_list
resource_declaration_list
optional_access_declarations
optional_instance_specific_initializations
END_CONFIGURATION
{$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid configuration name defined in configuration declaration."); yyerrok;}
| CONFIGURATION configuration_name
- optional_global_var_declarations
+ global_var_declarations_list
optional_access_declarations
optional_instance_specific_initializations
END_CONFIGURATION
{$$ = NULL; print_err_msg(locl(@3), locf(@4), "no resource(s) defined in configuration declaration."); yynerrs++;}
| CONFIGURATION configuration_name
- optional_global_var_declarations
+ global_var_declarations_list
error
optional_access_declarations
optional_instance_specific_initializations
END_CONFIGURATION
{$$ = NULL; print_err_msg(locf(@4), locl(@4), "invalid resource(s) defined in configuration declaration."); yyerrok;}
/*| CONFIGURATION configuration_name
- optional_global_var_declarations
+ global_var_declarations_list
single_resource_declaration
{variable_name_symtable.pop();
direct_variable_symtable.pop();}
@@ -5642,7 +5642,7 @@
END_OF_INPUT
{$$ = NULL; print_err_msg(locf(@1), locl(@2), "unclosed configuration declaration."); yyerrok;}*/
| CONFIGURATION configuration_name
- optional_global_var_declarations
+ global_var_declarations_list
resource_declaration_list
optional_access_declarations
optional_instance_specific_initializations
@@ -5657,12 +5657,30 @@
// - configuration_declaration
// - resource_declaration
//
-optional_global_var_declarations:
+/* NOTE: The IEC 61131-3 v2 standard defines this list as being: [global_var_declarations]
+ * e.g.:
+ * 'CONFIGURATION' configuration_name [global_var_declarations] ...
+ *
+ * However, this means that a single VAR_GLOBAL ... END_VAR construct is allowed
+ * in each CONFIGURATION or RESOURCE declaration. If the user wishes to have global
+ * variables with distinct properties (e.g. some with RETAIN, others with CONSTANT,
+ * and yet other variables with none of these qualifiers), the syntax defined in the
+ * standard does not allow this.
+ * Amazingly, IEC 61131-3 v3 also does not seem to allow it either!!
+ * Since this is most likely a bug in the standard, we are changing the syntax slightly
+ * to become:
+ * 'CONFIGURATION' configuration_name {global_var_declarations} ...
+ *
+ * Remember that:
+ * {S}, closure, meaning zero or more concatenations of S.
+ * [S], option, meaning zero or one occurrence of S.
+ */
+global_var_declarations_list:
// empty
- {$$ = NULL;}
-| global_var_declarations
-;
-
+ {$$ = new global_var_declarations_list_c(locloc(@$));}
+| global_var_declarations_list global_var_declarations
+ {$$ = $1; $$->add_element($2);}
+;
// helper symbol for configuration_declaration //
optional_access_declarations:
@@ -5693,7 +5711,7 @@
resource_declaration:
RESOURCE {variable_name_symtable.push();direct_variable_symtable.push();} resource_name {variable_name_symtable.insert($3, prev_declared_resource_name_token);} ON resource_type_name
- optional_global_var_declarations
+ global_var_declarations_list
single_resource_declaration
END_RESOURCE
{$$ = new resource_declaration_c($3, $6, $7, $8, locloc(@$));
@@ -5703,12 +5721,12 @@
}
/* ERROR_CHECK_BEGIN */
| RESOURCE {variable_name_symtable.push();direct_variable_symtable.push();} ON resource_type_name
- optional_global_var_declarations
+ global_var_declarations_list
single_resource_declaration
END_RESOURCE
{$$ = NULL; print_err_msg(locl(@1), locf(@3), "no resource name defined in resource declaration."); yynerrs++;}
/*| RESOURCE {variable_name_symtable.push();direct_variable_symtable.push();} resource_name ON resource_type_name
- optional_global_var_declarations
+ global_var_declarations_list
single_resource_declaration
END_OF_INPUT
{$$ = NULL; print_err_msg(locf(@1), locl(@5), "unclosed resource declaration."); yyerrok;}*/
--- a/stage4/generate_c/generate_c.cc Mon Jan 06 12:25:21 2014 +0000
+++ b/stage4/generate_c/generate_c.cc Tue Feb 11 10:55:27 2014 +0000
@@ -713,15 +713,13 @@
} inlinearray_mode_t;
private:
- stage4out_c *s4o_ptr;
std::map<std::string, int> inline_array_defined;
std::string current_array_name;
inlinearray_mode_t current_mode;
public:
generate_c_datatypes_c(stage4out_c *s4o_ptr, stage4out_c *s4o_incl_ptr)
- : generate_c_typedecl_c(s4o_ptr, s4o_incl_ptr) {
- generate_c_datatypes_c::s4o_ptr = s4o_ptr;
+ : generate_c_typedecl_c(s4o_incl_ptr) {
current_mode = none_im;
};
virtual ~generate_c_datatypes_c(void) {
@@ -907,11 +905,20 @@
void *visit(array_spec_init_c *symbol) {
switch (current_mode) {
case arraydeclaration_im:
+ {
+ array_specification_c *specification = dynamic_cast<array_specification_c*>(symbol->array_specification);
+ if (specification != NULL)
+ symbol->array_specification->accept(*this);
+ }
+ break;
case arrayname_im:
{
array_specification_c *specification = dynamic_cast<array_specification_c*>(symbol->array_specification);
if (specification != NULL)
symbol->array_specification->accept(*this);
+ identifier_c *name = dynamic_cast<identifier_c*>(symbol->array_specification);
+ if (name != NULL)
+ s4o_incl.print(name->value);
}
break;
default:
@@ -1138,14 +1145,13 @@
/***********************************************************************/
-class generate_c_pous_c: public generate_c_typedecl_c {
+class generate_c_pous_c: public generate_c_base_c {
private:
- stage4out_c *s4o_ptr;
+ stage4out_c &s4o_incl;
public:
generate_c_pous_c(stage4out_c *s4o_ptr, stage4out_c *s4o_incl_ptr)
- : generate_c_typedecl_c(s4o_ptr, s4o_incl_ptr) {
- generate_c_pous_c::s4o_ptr = s4o_ptr;
+ : generate_c_base_c(s4o_ptr), s4o_incl(*s4o_incl_ptr) {
};
virtual ~generate_c_pous_c(void) {}
@@ -1179,8 +1185,8 @@
/********************/
/* 2.1.6 - Pragmas */
/********************/
-void *visit(enable_code_generation_pragma_c * symbol) {s4o_ptr->enable_output(); return NULL;}
-void *visit(disable_code_generation_pragma_c * symbol) {s4o_ptr->disable_output(); return NULL;}
+void *visit(enable_code_generation_pragma_c * symbol) {s4o.enable_output(); return NULL;}
+void *visit(disable_code_generation_pragma_c * symbol) {s4o.disable_output(); return NULL;}
/*************************/
/* B.1 - Common elements */
@@ -1742,16 +1748,13 @@
/***********************************************************************/
/***********************************************************************/
-class generate_c_config_c: public generate_c_typedecl_c {
+class generate_c_config_c: public generate_c_base_c {
private:
- stage4out_c *s4o_ptr;
- stage4out_c *s4o_incl_ptr;
+ stage4out_c &s4o_incl;
public:
generate_c_config_c(stage4out_c *s4o_ptr, stage4out_c *s4o_incl_ptr)
- : generate_c_typedecl_c(s4o_ptr, s4o_incl_ptr) {
- generate_c_config_c::s4o_ptr = s4o_ptr;
- generate_c_config_c::s4o_incl_ptr = s4o_incl_ptr;
+ : generate_c_base_c(s4o_ptr), s4o_incl(*s4o_incl_ptr) {
};
virtual ~generate_c_config_c(void) {}
@@ -1771,14 +1774,14 @@
/* 2.1.6 - Pragmas */
/********************/
void *visit(enable_code_generation_pragma_c * symbol) {
- s4o_ptr->enable_output();
- s4o_incl_ptr->enable_output();
+ s4o.enable_output();
+ s4o_incl.enable_output();
return NULL;
}
void *visit(disable_code_generation_pragma_c * symbol) {
- s4o_ptr->disable_output();
- s4o_incl_ptr->disable_output();
+ s4o.disable_output();
+ s4o_incl.disable_output();
return NULL;
}
--- a/stage4/generate_c/generate_c_base.cc Mon Jan 06 12:25:21 2014 +0000
+++ b/stage4/generate_c/generate_c_base.cc Tue Feb 11 10:55:27 2014 +0000
@@ -583,6 +583,60 @@
/********************************/
/* leave for derived classes... */
+
+/* enumerated_type_name '#' identifier */
+void *visit(enumerated_value_c *symbol) {
+ if (NULL == symbol->datatype) {
+ debug_c::print(symbol);
+ ERROR;
+ }
+
+ symbol_c *type_name = get_datatype_info_c::get_id(symbol->datatype);
+ if (NULL == type_name) {
+ ERROR_MSG("C code generator does not currently support anonymous enumerated data types.");
+ }
+
+ type_name->accept(*this);
+ s4o.print("__");
+ symbol->value->accept(*this);
+ return NULL;
+}
+
+
+
+/* NOTE: visit(subrange_spec_init_c *)
+ * and visit(subrange_specification_c *)
+ * together simply print out the integer datatype
+ * on which the subrange is based.
+ *
+ * Future code clean-ups should delete these two
+ * visit mehotds, and make sure whoever calls them
+ * uses symbol->datatype instead!
+ */
+/* subrange_specification ASSIGN signed_integer */
+void *visit(subrange_spec_init_c *symbol) {
+ TRACE("subrange_spec_init_c");
+ symbol->subrange_specification->accept(*this);
+ return NULL;
+}
+
+/* integer_type_name '(' subrange')' */
+void *visit(subrange_specification_c *symbol) {
+ TRACE("subrange_specification_c");
+ symbol->integer_type_name->accept(*this);
+ return NULL;
+}
+
+
+/* helper symbol for array_specification */
+/* array_subrange_list ',' subrange */
+void *visit(array_subrange_list_c *symbol) {
+ TRACE("array_subrange_list_c");
+ print_list(symbol);
+ return NULL;
+}
+
+
/*********************/
/* B 1.4 - Variables */
/*********************/
--- a/stage4/generate_c/generate_c_il.cc Mon Jan 06 12:25:21 2014 +0000
+++ b/stage4/generate_c/generate_c_il.cc Tue Feb 11 10:55:27 2014 +0000
@@ -126,7 +126,7 @@
-class generate_c_il_c: public generate_c_typedecl_c, il_default_variable_visitor_c {
+class generate_c_il_c: public generate_c_base_c, il_default_variable_visitor_c {
public:
typedef enum {
@@ -197,7 +197,7 @@
public:
generate_c_il_c(stage4out_c *s4o_ptr, symbol_c *name, symbol_c *scope, const char *variable_prefix = NULL)
- : generate_c_typedecl_c(s4o_ptr),
+ : generate_c_base_c(s4o_ptr),
implicit_variable_current (IL_DEFVAR, NULL),
implicit_variable_result (IL_DEFVAR, NULL),
implicit_variable_result_back(IL_DEFVAR_BACK, NULL)
--- a/stage4/generate_c/generate_c_inlinefcall.cc Mon Jan 06 12:25:21 2014 +0000
+++ b/stage4/generate_c/generate_c_inlinefcall.cc Tue Feb 11 10:55:27 2014 +0000
@@ -26,7 +26,7 @@
#define INLINE_RESULT_TEMP_VAR "__res"
#define INLINE_PARAM_COUNT "__PARAM_COUNT"
-class generate_c_inlinefcall_c: public generate_c_typedecl_c {
+class generate_c_inlinefcall_c: public generate_c_base_c {
public:
typedef enum {
@@ -76,7 +76,7 @@
public:
generate_c_inlinefcall_c(stage4out_c *s4o_ptr, symbol_c *name, symbol_c *scope, const char *variable_prefix = NULL)
- : generate_c_typedecl_c(s4o_ptr),
+ : generate_c_base_c(s4o_ptr),
implicit_variable_current(IL_DEFVAR, NULL)
{
search_varfb_instance_type = new search_varfb_instance_type_c(scope);
--- a/stage4/generate_c/generate_c_sfc.cc Mon Jan 06 12:25:21 2014 +0000
+++ b/stage4/generate_c/generate_c_sfc.cc Tue Feb 11 10:55:27 2014 +0000
@@ -657,7 +657,7 @@
/***********************************************************************/
/***********************************************************************/
-class generate_c_sfc_c: public generate_c_typedecl_c {
+class generate_c_sfc_c: public generate_c_base_c {
private:
std::list<VARIABLE> variable_list;
@@ -667,7 +667,7 @@
public:
generate_c_sfc_c(stage4out_c *s4o_ptr, symbol_c *name, symbol_c *scope, const char *variable_prefix = NULL)
- : generate_c_typedecl_c(s4o_ptr) {
+ : generate_c_base_c(s4o_ptr) {
generate_c_sfc_elements = new generate_c_sfc_elements_c(s4o_ptr, name, scope, variable_prefix);
search_var_instance_decl = new search_var_instance_decl_c(scope);
this->set_variable_prefix(variable_prefix);
--- a/stage4/generate_c/generate_c_sfcdecl.cc Mon Jan 06 12:25:21 2014 +0000
+++ b/stage4/generate_c/generate_c_sfcdecl.cc Tue Feb 11 10:55:27 2014 +0000
@@ -32,7 +32,7 @@
/***********************************************************************/
/***********************************************************************/
-class generate_c_sfcdecl_c: protected generate_c_typedecl_c {
+class generate_c_sfcdecl_c: protected generate_c_base_c {
public:
typedef enum {
@@ -59,7 +59,7 @@
public:
generate_c_sfcdecl_c(stage4out_c *s4o_ptr, symbol_c *scope, const char *variable_prefix = NULL)
- : generate_c_typedecl_c(s4o_ptr) {
+ : generate_c_base_c(s4o_ptr) {
this->set_variable_prefix(variable_prefix);
search_var_instance_decl = new search_var_instance_decl_c(scope);
}
--- a/stage4/generate_c/generate_c_st.cc Mon Jan 06 12:25:21 2014 +0000
+++ b/stage4/generate_c/generate_c_st.cc Tue Feb 11 10:55:27 2014 +0000
@@ -44,7 +44,7 @@
/***********************************************************************/
-class generate_c_st_c: public generate_c_typedecl_c {
+class generate_c_st_c: public generate_c_base_c {
public:
typedef enum {
@@ -95,7 +95,7 @@
public:
generate_c_st_c(stage4out_c *s4o_ptr, symbol_c *name, symbol_c *scope, const char *variable_prefix = NULL)
- : generate_c_typedecl_c(s4o_ptr) {
+ : generate_c_base_c(s4o_ptr) {
search_fb_instance_decl = new search_fb_instance_decl_c (scope);
search_varfb_instance_type = new search_varfb_instance_type_c(scope);
search_var_instance_decl = new search_var_instance_decl_c (scope);
@@ -864,20 +864,20 @@
/* fb_name '(' [param_assignment_list] ')' */
-/* param_assignment_list -> may be NULL ! */
-//SYM_REF2(fb_invocation_c, fb_name, param_assignment_list)
+/* formal_param_list -> may be NULL ! */
+/* nonformal_param_list -> may be NULL ! */
+/* NOTE: The parameter 'called_fb_declaration'is used to pass data between stage 3 and stage4 (although currently it is not used in stage 4 */
+// SYM_REF3(fb_invocation_c, fb_name, formal_param_list, nonformal_param_list, symbol_c *called_fb_declaration;)
void *visit(fb_invocation_c *symbol) {
TRACE("fb_invocation_c");
- /* first figure out what is the name of the function block type of the function block being called... */
- symbol_c *function_block_type_name = this->search_fb_instance_decl->get_type_name(symbol->fb_name);
- /* should never occur. The function block instance MUST have been declared... */
- if (function_block_type_name == NULL) ERROR;
-
- /* Now find the declaration of the function block type being called... */
- function_block_declaration_c *fb_decl = function_block_type_symtable.find_value(function_block_type_name);
- /* should never occur. The function block type being called MUST be in the symtable... */
- if (fb_decl == function_block_type_symtable.end_value()) ERROR;
-
+
+ /* find the declaration of the function block type being called... */
+ symbol_c *fb_decl = symbol->called_fb_declaration;
+ if (fb_decl == NULL) ERROR;
+ /* figure out the name of the function block type of the function block being called... */
+ symbol_c *function_block_type_name = get_datatype_info_c::get_id(fb_decl);
+ if (NULL == function_block_type_name) ERROR;
+
/* loop through each function block parameter, find the value we should pass
* to it, and then output the c equivalent...
*/
--- a/stage4/generate_c/generate_c_typedecl.cc Mon Jan 06 12:25:21 2014 +0000
+++ b/stage4/generate_c/generate_c_typedecl.cc Tue Feb 11 10:55:27 2014 +0000
@@ -31,16 +31,9 @@
private:
symbol_c* current_type_name;
bool array_is_derived;
-
generate_c_base_c *basedecl;
public:
- generate_c_typedecl_c(stage4out_c *s4o_ptr, stage4out_c *s4o_incl_ptr): generate_c_base_c(s4o_ptr), s4o_incl(*s4o_incl_ptr) {
- current_typedefinition = none_td;
- current_basetypedeclaration = none_bd;
- current_type_name = NULL;
- basedecl = new generate_c_base_c(&s4o_incl);
- }
generate_c_typedecl_c(stage4out_c *s4o_ptr): generate_c_base_c(s4o_ptr), s4o_incl(*s4o_ptr) {
current_typedefinition = none_td;
current_basetypedeclaration = none_bd;
@@ -190,6 +183,7 @@
/* integer_type_name '(' subrange')' */
void *visit(subrange_specification_c *symbol) {
+ TRACE("subrange_specification_c");
if (current_typedefinition == subrange_td) {
switch (current_basetypedeclaration) {
case subrangebasetype_bd:
@@ -197,45 +191,52 @@
break;
case subrangetest_bd:
if (symbol->subrange != NULL) {
- current_type_name->accept(*this);
- s4o.print(" __CHECK_");
- current_type_name->accept(*this);
- s4o.print("(");
- current_type_name->accept(*this);
- s4o.print(" value) {\n");
- s4o.indent_right();
-
+ s4o_incl.print("static inline ");
+ current_type_name->accept(*basedecl);
+ s4o_incl.print(" __CHECK_");
+ current_type_name->accept(*basedecl);
+ s4o_incl.print("(");
+ current_type_name->accept(*basedecl);
+ s4o_incl.print(" value) {\n");
+ s4o_incl.indent_right();
+
+ /* NOTE: IEC 61131-3 v2 syntax mandates that the integer type name be one of SINT, ..., LINT, USINT, ... ULIT */
+ /* For this reason, the following condition will always be false, and therefore this is a block
+ * of dead code. However, let's not delete it for now. It might come in useful for IEC 61131-3 v3.
+ * For the moment, we just comment it out!
+ */
+ /*
if (get_datatype_info_c::is_subrange(symbol->integer_type_name)) {
- s4o.print(s4o.indent_spaces + "value = __CHECK_");
+ s4o_incl.print(s4o_incl.indent_spaces + "value = __CHECK_");
symbol->integer_type_name->accept(*this);
- s4o.print("(value);\n");
+ s4o_incl.print("(value);\n");
}
+ */
symbol->subrange->accept(*this);
- s4o.indent_left();
- s4o.print("}\n");
+ s4o_incl.indent_left();
+ s4o_incl.print("}\n");
}
else {
- s4o.print("#define __CHECK_");
- current_type_name->accept(*this);
- s4o.print(" __CHECK_");
- symbol->integer_type_name->accept(*this);
- s4o.print("\n");
+ s4o_incl.print("#define __CHECK_");
+ current_type_name->accept(*basedecl);
+ s4o_incl.print(" __CHECK_");
+ symbol->integer_type_name->accept(*basedecl);
+ s4o_incl.print("\n");
}
break;
default:
break;
}
}
- else {
- symbol->integer_type_name->accept(*basedecl);
- }
- return NULL;
-}
+ return NULL;
+}
+
/* signed_integer DOTDOT signed_integer */
void *visit(subrange_c *symbol) {
+ TRACE("subrange_c");
int dimension;
switch (current_typedefinition) {
case array_td:
@@ -248,26 +249,26 @@
symbol->lower_limit->accept(*this);
break;
case subrange_td:
- s4o.print(s4o.indent_spaces + "if (value < ");
- symbol->lower_limit->accept(*this);
- s4o.print(")\n");
- s4o.indent_right();
- s4o.print(s4o.indent_spaces + "return ");
- symbol->lower_limit->accept(*this);
- s4o.print(";\n");
- s4o.indent_left();
- s4o.print(s4o.indent_spaces + "else if (value > ");
- symbol->upper_limit->accept(*this);
- s4o.print(")\n");
- s4o.indent_right();
- s4o.print(s4o.indent_spaces + "return ");
- symbol->upper_limit->accept(*this);
- s4o.print(";\n");
- s4o.indent_left();
- s4o.print(s4o.indent_spaces + "else\n");
- s4o.indent_right();
- s4o.print(s4o.indent_spaces + "return value;\n");
- s4o.indent_left();
+ s4o_incl.print(s4o_incl.indent_spaces + "if (value < ");
+ symbol->lower_limit->accept(*basedecl);
+ s4o_incl.print(")\n");
+ s4o_incl.indent_right();
+ s4o_incl.print(s4o_incl.indent_spaces + "return ");
+ symbol->lower_limit->accept(*basedecl);
+ s4o_incl.print(";\n");
+ s4o_incl.indent_left();
+ s4o_incl.print(s4o_incl.indent_spaces + "else if (value > ");
+ symbol->upper_limit->accept(*basedecl);
+ s4o_incl.print(")\n");
+ s4o_incl.indent_right();
+ s4o_incl.print(s4o_incl.indent_spaces + "return ");
+ symbol->upper_limit->accept(*basedecl);
+ s4o_incl.print(";\n");
+ s4o_incl.indent_left();
+ s4o_incl.print(s4o_incl.indent_spaces + "else\n");
+ s4o_incl.indent_right();
+ s4o_incl.print(s4o_incl.indent_spaces + "return value;\n");
+ s4o_incl.indent_left();
default:
break;
}
@@ -308,29 +309,15 @@
/* helper symbol for enumerated_specification->enumerated_spec_init */
/* enumerated_value_list ',' enumerated_value */
void *visit(enumerated_value_list_c *symbol) {
+ TRACE("enumerated_value_list_c");
print_list_incl(symbol, s4o_incl.indent_spaces, ",\n"+s4o_incl.indent_spaces, "\n");
return NULL;
}
/* enumerated_type_name '#' identifier */
-void *visit(enumerated_value_c *symbol) {
- if (current_typedefinition == enumerated_td)
- current_type_name->accept(*basedecl);
- else {
- if (NULL == symbol->datatype) {
- debug_c::print(symbol);
- ERROR;
- }
- symbol_c *type_name = get_datatype_info_c::get_id(symbol->datatype);
- if (NULL == type_name) {
-// ERROR_MSG("generate_c does not support anonymous enumerated data types.");
- } else
- type_name->accept(*basedecl);
- }
- s4o_incl.print("__");
- symbol->value->accept(*basedecl);
- return NULL;
-}
+/* Handled by generate_c_base_c class!!
+void *visit(enumerated_value_c *symbol) {}
+*/
/* identifier ':' array_spec_init */
void *visit(array_type_declaration_c *symbol) {
@@ -393,6 +380,7 @@
/* ARRAY '[' array_subrange_list ']' OF non_generic_type_name */
void *visit(array_specification_c *symbol) {
+ TRACE("array_specification_c");
switch (current_basetypedeclaration) {
case arraybasetype_bd:
symbol->non_generic_type_name->accept(*this);
@@ -409,18 +397,12 @@
return NULL;
}
-/* helper symbol for array_specification */
-/* array_subrange_list ',' subrange */
-void *visit(array_subrange_list_c *symbol) {
- print_list(symbol);
- return NULL;
-}
/* TYPE type_declaration_list END_TYPE */
void *visit(data_type_declaration_c *symbol) {
TRACE("data_type_declaration_c");
symbol->type_declaration_list->accept(*this);
- s4o.print("\n\n");
+ s4o_incl.print("\n\n");
return NULL;
}
@@ -441,11 +423,11 @@
s4o_incl.print(")\n");
if (get_datatype_info_c::is_subrange(symbol->simple_type_name)) {
- s4o.print("#define __CHECK_");
- current_type_name->accept(*this);
- s4o.print(" __CHECK_");
+ s4o_incl.print("#define __CHECK_");
+ current_type_name->accept(*basedecl);
+ s4o_incl.print(" __CHECK_");
symbol->simple_spec_init->accept(*this);
- s4o.print("\n");
+ s4o_incl.print("\n");
}
return NULL;
@@ -565,7 +547,7 @@
s4o_incl.print(" ");
symbol->structure_element_name->accept(*basedecl);
s4o_incl.print(";\n");
- s4o_incl.print(s4o.indent_spaces);
+ s4o_incl.print(s4o_incl.indent_spaces);
return NULL;
}
--- a/stage4/generate_iec/generate_iec.cc Mon Jan 06 12:25:21 2014 +0000
+++ b/stage4/generate_iec/generate_iec.cc Tue Feb 11 10:55:27 2014 +0000
@@ -1422,6 +1422,10 @@
}
+/* intermediate helper symbol for configuration_declaration */
+/* { global_var_declarations_list } */
+void *visit(global_var_declarations_list_c *symbol) {return print_list(symbol);}
+
/* helper symbol for configuration_declaration */
/*| resource_declaration_list resource_declaration */
void *visit(resource_declaration_list_c *symbol) {return print_list(symbol);}