Adding support for ouput variables in functions
authorlbessard
Thu, 25 Sep 2008 10:26:10 +0200
changeset 145 72ae82e65dbc
parent 144 0ee0055a8ffe
child 146 eef5e62048c7
Adding support for ouput variables in functions
stage4/generate_c/generate_c.cc
stage4/generate_c/generate_c_st.cc
stage4/generate_c/generate_c_vardecl.cc
--- a/stage4/generate_c/generate_c.cc	Thu Sep 25 10:25:30 2008 +0200
+++ b/stage4/generate_c/generate_c.cc	Thu Sep 25 10:26:10 2008 +0200
@@ -569,8 +569,8 @@
   vardecl = new generate_c_vardecl_c(&s4o,
   				      generate_c_vardecl_c::finterface_vf,
   				      generate_c_vardecl_c::input_vt |
-				      generate_c_vardecl_c::output_vt |
-				      generate_c_vardecl_c::inoutput_vt);
+				        generate_c_vardecl_c::output_vt |
+				        generate_c_vardecl_c::inoutput_vt);
   vardecl->print(symbol->var_declarations_list);
   delete vardecl;
   s4o.indent_left();
@@ -580,6 +580,13 @@
   /* (B) Function local variable declaration */
     /* (B.1) Variables declared in ST source code */
   s4o.indent_right();
+  vardecl = new generate_c_vardecl_c(&s4o,
+                generate_c_vardecl_c::foutputdecl_vf,
+                generate_c_vardecl_c::output_vt |
+                generate_c_vardecl_c::inoutput_vt);
+  vardecl->print(symbol->var_declarations_list);
+  delete vardecl;
+  
   vardecl = new generate_c_vardecl_c(&s4o, generate_c_vardecl_c::localinit_vf, generate_c_vardecl_c::private_vt);
   vardecl->print(symbol->var_declarations_list);
   delete vardecl;
@@ -602,6 +609,14 @@
   /* (C) Function body */
   generate_c_SFC_IL_ST_c generate_c_code(&s4o, symbol);
   symbol->function_body->accept(generate_c_code);
+  
+  vardecl = new generate_c_vardecl_c(&s4o,
+                generate_c_vardecl_c::foutputassign_vf,
+                generate_c_vardecl_c::output_vt |
+                generate_c_vardecl_c::inoutput_vt);
+  vardecl->print(symbol->var_declarations_list);
+  delete vardecl;
+  
   s4o.print(s4o.indent_spaces + "return ");
   symbol->derived_function_name->accept(*this);
   s4o.print(";\n");
--- a/stage4/generate_c/generate_c_st.cc	Thu Sep 25 10:25:30 2008 +0200
+++ b/stage4/generate_c/generate_c_st.cc	Thu Sep 25 10:26:10 2008 +0200
@@ -72,6 +72,8 @@
 
     symbol_c* current_array_type;
 
+    bool current_param_is_pointer;
+
   public:
     generate_c_st_c(stage4out_c *s4o_ptr, symbol_c *scope, const char *variable_prefix = NULL)
     : generate_c_typedecl_c(s4o_ptr) {
@@ -80,6 +82,7 @@
       search_varfb_instance_type = new search_varfb_instance_type_c(scope);
       this->set_variable_prefix(variable_prefix);
       current_array_type = NULL;
+      current_param_is_pointer = false;
     }
 
     virtual ~generate_c_st_c(void) {
@@ -136,11 +139,16 @@
 /*********************/
 void *visit(symbolic_variable_c *symbol) {
   unsigned int vartype = search_varfb_instance_type->get_vartype(symbol);
-  if (vartype == search_var_instance_decl_c::external_vt || vartype == search_var_instance_decl_c::located_vt) {
+  if (!current_param_is_pointer && (vartype == search_var_instance_decl_c::external_vt || vartype == search_var_instance_decl_c::located_vt)) {
     s4o.print("*(");
     generate_c_base_c::visit(symbol);
     s4o.print(")");
   }
+  else if (current_param_is_pointer && vartype != search_var_instance_decl_c::external_vt && vartype != search_var_instance_decl_c::located_vt) {
+    s4o.print("&(");
+    generate_c_base_c::visit(symbol);
+    s4o.print(")");
+  }
   else {
     generate_c_base_c::visit(symbol);
   }
@@ -155,10 +163,14 @@
   TRACE("direct_variable_c");
   /* Do not use print_token() as it will change everything into uppercase */
   if (strlen(symbol->value) == 0) ERROR;
-  s4o.print("*(");
+  if (!current_param_is_pointer) {
+    s4o.print("*(");
+  }
   this->print_variable_prefix();
   s4o.printlocation(symbol->value + 1);
-  s4o.print(")");
+  if (!current_param_is_pointer) {
+    s4o.print(")");
+  }
   return NULL;
 }
 
@@ -595,6 +607,7 @@
           break;
         case function_param_iterator_c::direction_out:
         case function_param_iterator_c::direction_inout:
+          current_param_is_pointer = true;
           if (param_value == NULL) {
             /* no parameter value given, so we pass a previously declared temporary variable. */
             std::string *temp_var_name = temp_var_name_factory.new_name();
@@ -603,6 +616,7 @@
           } else {
             param_value->accept(*this);
           }
+          current_param_is_pointer = false;
           break;
         case function_param_iterator_c::direction_extref:
           /* TODO! */
--- a/stage4/generate_c/generate_c_vardecl.cc	Thu Sep 25 10:25:30 2008 +0200
+++ b/stage4/generate_c/generate_c_vardecl.cc	Thu Sep 25 10:26:10 2008 +0200
@@ -401,12 +401,14 @@
      *                __plc_pt_c<INT, 8*sizeof(INT)> START_P::loc = __plc_pt_c<INT, 8*sizeof(INT)>("I2");
      */
     typedef enum {finterface_vf,
-                    local_vf,
-		    localinit_vf,
-		    init_vf,
-		    constructorinit_vf,
-		    globalinit_vf
-		   } varformat_t;
+                  foutputdecl_vf,
+                  foutputassign_vf,
+                  local_vf,
+		              localinit_vf,
+		              init_vf,
+		              constructorinit_vf,
+		              globalinit_vf
+		             } varformat_t;
 
 
   private:
@@ -513,7 +515,7 @@
           s4o.print("\n" + s4o.indent_spaces);
           this->current_var_type_symbol->accept(*this);
           if ((current_vartype & (output_vt | inoutput_vt)) != 0)
-            s4o.print(" &");
+            s4o.print(" *__");
           else
             s4o.print(" ");
           list->elements[i]->accept(*this);
@@ -527,6 +529,36 @@
         }
       }
 
+      if (wanted_varformat == foutputdecl_vf) {
+        for(int i = 0; i < list->n; i++) {
+          if ((current_vartype & (output_vt | inoutput_vt)) != 0) {
+            s4o.print(s4o.indent_spaces);
+            this->current_var_type_symbol->accept(*this);
+            s4o.print(" ");
+            list->elements[i]->accept(*this);
+            s4o.print(";\n");
+          }
+        }
+      }
+
+      if (wanted_varformat == foutputassign_vf) {
+        for(int i = 0; i < list->n; i++) {
+          if ((current_vartype & (output_vt | inoutput_vt)) != 0) {
+            s4o.print(s4o.indent_spaces + "if (__");
+            list->elements[i]->accept(*this);
+            s4o.print(" != NULL) {\n");
+            s4o.indent_right();
+            s4o.print(s4o.indent_spaces + "*__");
+            list->elements[i]->accept(*this);
+            s4o.print(" = ");
+            list->elements[i]->accept(*this);
+            s4o.print(";\n");
+            s4o.indent_left();
+            s4o.print(s4o.indent_spaces + "}\n");
+          }
+        }
+      }
+
       if (wanted_varformat == constructorinit_vf) {
         for(int i = 0; i < list->n; i++) {
           if (is_fb) {