stage4/generate_c/generate_c_vardecl.cc
changeset 1037 bf39078476e4
parent 1035 0a58b2720976
child 1041 56ebe2a31b5b
--- a/stage4/generate_c/generate_c_vardecl.cc	Sat Mar 18 22:15:19 2017 +0000
+++ b/stage4/generate_c/generate_c_vardecl.cc	Mon Apr 03 18:30:50 2017 +0100
@@ -836,6 +836,7 @@
      *                c = 99.9;
      *
      * constructorinit_vf: initialising of member variables...
+     * TODO: FIX THIS COMMENT!!! It is wrong!!!
      *                e.g. for a constructor...
      *                class_name_c(void)
      *                : a(9), b(99), c(99.9)  { // code... }
@@ -957,6 +958,39 @@
       return NULL;
     }
 
+    /* helper function for declare_variables().
+     * Only called from one place!
+     * 
+     * If we were to follow the visitor pattern, the following code should really be placed inside the
+     *  method visit(structure_element_initialization_list_c *), but would be conditionally executed in 
+     *  a specific state/situation (which would need to be indicated through flags -> yuck). 
+     * Instead of adding the code there inside an if() statement, I (msousa) prefered to keep it separate.
+     * 
+     * To be honest I consider this a quick hack. 
+     * The time is approaching for when this class will need a general clean up.
+     */
+    void print_fb_explicit_initial_values(symbol_c *fbvar_name, symbol_c *init_values_list) {
+      structure_element_initialization_list_c *init_list = dynamic_cast<structure_element_initialization_list_c *>(init_values_list);
+      if (NULL == init_list) ERROR;
+      
+      for (int i = 0; i < init_list->n; i++) {
+        structure_element_initialization_c *init_list_elem = dynamic_cast<structure_element_initialization_c *>(init_list->elements[i]);
+        if (NULL == init_list_elem) ERROR;
+        s4o.print("\n");
+        s4o.print(s4o.indent_spaces);
+        s4o.print(INIT_VAR);
+        s4o.print("(");
+        this->print_variable_prefix();
+        fbvar_name->accept(*this);
+        s4o.print(".");
+        init_list_elem->structure_element_name->accept(*this);
+        s4o.print(",");
+        init_list_elem->value->accept(*this);
+        print_retain();
+        s4o.print(")");        
+      }
+    };
+
     /* Actually produce the output where variables are declared... */
     /* Note that located variables and EN/ENO are the exception, they
      * being declared in the located_var_decl_c,
@@ -1092,6 +1126,14 @@
       if (wanted_varformat == constructorinit_vf) {
         for(int i = 0; i < list->n; i++) {
           if (is_fb) {
+            /* If we are declaring and/or initializing a FB instance, then we
+             * simply call the FBNAME_init__() function, which will initialise the
+             * FB instance with the default values of this FB type.
+             *  For a FB instance declared as:
+             *     VAR my_fb : FB_typ; END_VAR
+             * The generated C code will look something like:
+             *   FB_TYP_init__(&data__->MY_FB,retain);
+             */
             s4o.print(nv->get());
             this->current_var_type_symbol->accept(*this);
             s4o.print(FB_INIT_SUFFIX);
@@ -1100,6 +1142,18 @@
             list->elements[i]->accept(*this);
             print_retain();
             s4o.print(");");
+            if (this->current_var_init_symbol != NULL) {
+              /* This FB instance declaration includes an explicit initialiser list
+               * e.g. VAR my_fb : FB_typ := (var1 := 42, var2 := 'hello'); END_VAR
+               *                         --------------------------------
+               * To handle this, we insert some extra code to set each of the initialised
+               * FB variables one by one...
+               * The generated C code will lokk something like:
+               * __INIT_VAR(data__->my_fb.var1, __INT_LITERAL(42), retain);
+               * __INIT_VAR(data__->my_fb.var1, __STRING_LITERAL("hello"), retain);
+               */  
+              print_fb_explicit_initial_values(list->elements[i], this->current_var_init_symbol);
+            }
           }
           else if (this->current_var_init_symbol != NULL) {
             s4o.print(nv->get());
@@ -1256,11 +1310,6 @@
 void *visit(input_declarations_c *symbol) {
   TRACE("input_declarations_c");
   if ((wanted_vartype & input_vt) != 0) {
-/*
-    // TO DO ...
-    if (symbol->option != NULL)
-      symbol->option->accept(*this);
-*/
     //s4o.indent_right();
     current_vartype = input_vt;
     if (symbol->option != NULL)
@@ -1331,7 +1380,6 @@
     }
 
     if (wanted_varformat == constructorinit_vf) {
-      /* NOTE: I (Mario) think this is dead code - never gets executed. Must confirm it before deleting it... */
       s4o.print(nv->get());
       s4o.print(INIT_VAR);
       s4o.print("(");
@@ -1401,7 +1449,6 @@
     }
 
     if (wanted_varformat == constructorinit_vf) {
-      /* NOTE: I (Mario) think this is dead code - never gets executed. Must confirm it before deleting it... */
       s4o.print(nv->get());
       s4o.print(INIT_VAR);
       s4o.print("(");