--- a/stage4/generate_c/generate_c.cc Thu Mar 20 17:27:29 2014 +0100
+++ b/stage4/generate_c/generate_c.cc Wed May 28 11:32:09 2014 +0200
@@ -386,6 +386,131 @@
/***********************************************************************/
/***********************************************************************/
/***********************************************************************/
+/* A helper class that analyses if the datatype of a variable is 'complex'. */
+/* 'complex' means that it is either a strcuture or an array! */
+class print_getter_c: public search_visitor_c {
+ private:
+ static print_getter_c *singleton_;
+
+ public:
+ print_getter_c(void) {};
+
+ static bool is_complex_type(symbol_c *symbol) {
+ if (NULL == symbol) ERROR;
+ if (!get_datatype_info_c::is_type_valid (symbol->datatype)) return false;
+ return ( get_datatype_info_c::is_structure(symbol->datatype)
+ || get_datatype_info_c::is_array (symbol->datatype)
+ );
+ }
+
+
+ private:
+ symbol_c *last_fb, *first_non_fb_identifier;
+
+ public:
+ /* returns the first element (from left to right) in a structured variable that is not a FB, i.e. is either a structure or an array! */
+ /* eg:
+ * fb1.fb2.fb3.real returns ??????
+ * fb1.fb2.struct1.real returns struct1
+ * struct1.real returns struct1
+ */
+ static symbol_c *find_first_nonfb(symbol_c *symbol) {
+ if (NULL == singleton_) singleton_ = new print_getter_c();
+ if (NULL == singleton_) ERROR;
+ if (NULL == symbol) ERROR;
+
+ singleton_->last_fb = NULL;
+ singleton_->first_non_fb_identifier = NULL;
+ return (symbol_c *)symbol->accept(*singleton_);
+ }
+
+ /* returns true if a strcutured variable (e.g. fb1.fb2.strcut1.real) contains a structure or array */
+ /* eg:
+ * fb1.fb2.fb3.real returns FALSE
+ * fb1.fb2.struct1.real returns TRUE
+ * struct1.real returns TRUE
+ */
+ static bool contains_complex_type(symbol_c *symbol) {
+ if (NULL == symbol) ERROR;
+ if (!get_datatype_info_c::is_type_valid(symbol->datatype)) ERROR;
+
+ symbol_c *first_non_fb = (symbol_c *)find_first_nonfb(symbol);
+ return is_complex_type(first_non_fb->datatype);
+ }
+
+
+ /* returns the datatype of the variable returned by find_first_nonfb() */
+ /* eg:
+ * fb1.fb2.fb3.real returns ??????
+ * fb1.fb2.struct1.real returns datatype of struct1
+ * struct1.real returns datatype of struct1
+ */
+ static search_var_instance_decl_c::vt_t first_nonfb_vardecltype(symbol_c *symbol, symbol_c *scope) {
+ if (NULL == symbol) ERROR;
+ if (!get_datatype_info_c::is_type_valid(symbol->datatype)) ERROR;
+
+ symbol_c *first_non_fb = (symbol_c *)find_first_nonfb(symbol);
+ if (NULL != singleton_->last_fb) {
+ scope = singleton_->last_fb->datatype;
+ symbol = singleton_->first_non_fb_identifier;
+ }
+
+ search_var_instance_decl_c search_var_instance_decl(scope);
+
+ return search_var_instance_decl.get_vartype(symbol);
+ }
+
+
+ /*********************/
+ /* B 1.4 - Variables */
+ /*********************/
+ void *visit(symbolic_variable_c *symbol) {
+ if (!get_datatype_info_c::is_type_valid (symbol->datatype)) ERROR;
+ if (!get_datatype_info_c::is_function_block(symbol->datatype)) {
+ first_non_fb_identifier = symbol;
+ return (void *)symbol;
+ }
+ last_fb = symbol;
+ return NULL;
+ }
+
+ /*************************************/
+ /* B.1.4.2 Multi-element Variables */
+ /*************************************/
+
+ // SYM_REF2(structured_variable_c, record_variable, field_selector)
+ void *visit(structured_variable_c *symbol) {
+ symbol_c *res = (symbol_c *)symbol->record_variable->accept(*this);
+ if (NULL != res) return res;
+
+ if (!get_datatype_info_c::is_type_valid (symbol->datatype)) ERROR;
+ if (!get_datatype_info_c::is_function_block(symbol->datatype)) {
+ first_non_fb_identifier = symbol->field_selector;
+ return (void *)symbol;
+ }
+
+ last_fb = symbol;
+ return NULL;
+ }
+
+ /* subscripted_variable '[' subscript_list ']' */
+ //SYM_REF2(array_variable_c, subscripted_variable, subscript_list)
+ void *visit(array_variable_c *symbol) {
+ void *res = symbol->subscripted_variable->accept(*this);
+ if (NULL != res) return res;
+ return (void *)symbol;
+ }
+
+
+};
+
+print_getter_c *print_getter_c::singleton_ = NULL;
+
+
+
+
+
+
/* A helper class that analyses if the datatype of a variable is 'complex'. */
/* 'complex' means that it is either a strcuture or an array! */
@@ -1573,7 +1698,7 @@
s4o.print(SET_VAR);
s4o.print("(");
s4o.print(FB_FUNCTION_PARAM);
- s4o.print("->,ENO,__BOOL_LITERAL(FALSE));\n");
+ s4o.print("->,ENO,,__BOOL_LITERAL(FALSE));\n");
s4o.print(s4o.indent_spaces + "return;\n");
s4o.indent_left();
s4o.print(s4o.indent_spaces + "}\n");
@@ -1583,7 +1708,7 @@
s4o.print(SET_VAR);
s4o.print("(");
s4o.print(FB_FUNCTION_PARAM);
- s4o.print("->,ENO,__BOOL_LITERAL(TRUE));\n");
+ s4o.print("->,ENO,,__BOOL_LITERAL(TRUE));\n");
s4o.indent_left();
s4o.print(s4o.indent_spaces + "}\n");
@@ -2403,7 +2528,7 @@
s4o.print(SET_VAR);
s4o.print("(");
current_task_name->accept(*this);
- s4o.print("_R_TRIG.,CLK, *");
+ s4o.print("_R_TRIG.,CLK,, *");
symbol->single_data_source->accept(*this);
s4o.print(");}\n");
s4o.print(s4o.indent_spaces + "R_TRIG");