Allow use of GLOBAL/EXTERNAL variables as control variable of FOR loop.
authorMario de Sousa <msousa@fe.up.pt>
Sun, 09 Apr 2017 23:43:04 +0100
changeset 1038 036f15e4041d
parent 1037 bf39078476e4
child 1039 52f63e622604
Allow use of GLOBAL/EXTERNAL variables as control variable of FOR loop.
stage4/generate_c/generate_c_st.cc
--- a/stage4/generate_c/generate_c_st.cc	Mon Apr 03 18:30:50 2017 +0100
+++ b/stage4/generate_c/generate_c_st.cc	Sun Apr 09 23:43:04 2017 +0100
@@ -1233,19 +1233,26 @@
 /* B 3.2.4 Iteration Statements */
 /********************************/
 void *visit(for_statement_c *symbol) {
-  s4o.print("for(");
-  symbol->control_variable->accept(*this);
-  s4o.print(" = ");
-  symbol->beg_expression->accept(*this);
-  s4o.print("; ");
+  /* Due to the way the GET/SET_GLOBAL accessor macros access VAR_GLOBAL variables,
+   * these varibles cannot be used within a C for(;;) loop.
+   * We must therefore implemnt the FOR END_FOR loop as a C while() loop
+   */
+  s4o.print("/* FOR ... */\n" + s4o.indent_spaces);
+  /* For the initialization part, we create an assignment_statement_c   */
+  /* and have this visitor visit it!                                    */ 
+  assignment_statement_c ini_assignment(symbol->control_variable, symbol->beg_expression);
+  ini_assignment.accept(*this);
+  //symbol->control_variable->accept(*this);  // this does not work for VAR_GLOBAL variables
+  //s4o.print(" = ");
+  //symbol->beg_expression->accept(*this);
+  
+  /* comparison // check for end of loop */
+  s4o.print(";\n" + s4o.indent_spaces + "while( ");
   if (symbol->by_expression == NULL) {
-    /* increment by 1 */
+    /* increment by 1 */    
     symbol->control_variable->accept(*this);
     s4o.print(" <= ");
     symbol->end_expression->accept(*this);
-    s4o.print("; ");
-    symbol->control_variable->accept(*this);
-    s4o.print("++");
   } else {
     /* increment by user defined value  */
     /* The user defined increment value may be negative, in which case
@@ -1265,19 +1272,47 @@
     symbol->control_variable->accept(*this);
     s4o.print(" >= (");
     symbol->end_expression->accept(*this);
-    s4o.print(")); ");
-    symbol->control_variable->accept(*this);
-    s4o.print(" += (");
-    symbol->by_expression->accept(*this);
-    s4o.print(")");
-  }
-  s4o.print(")");
+    s4o.print(")) ");
+  }
+  s4o.print(" ) {\n");
   
-  s4o.print(" {\n");
+  /* the body part */
   s4o.indent_right();
   symbol->statement_list->accept(*this);
+
+  /* increment part */
+  s4o.print(s4o.indent_spaces + "/* BY ... (of FOR loop) */\n");
+  s4o.print(s4o.indent_spaces); 
+  if (symbol->by_expression == NULL) {
+    /* increment by 1 */    
+    /* For the increment part, we create an add_expression_c and assignment_statement_c   */
+    /* and have this visitor vist the latter!                                             */ 
+    integer_c              integer_oneval("1");
+    add_expression_c       add_expression(symbol->control_variable, &integer_oneval);
+    assignment_statement_c inc_assignment(symbol->control_variable, &add_expression);
+    integer_oneval.const_value._int64 .set(1);                    // set the stage3 anottation we need 
+    integer_oneval.const_value._uint64.set(1);                    // set the stage3 anottation we need
+    integer_oneval.datatype = symbol->control_variable->datatype; // set the stage3 anottation we need
+    add_expression.datatype = symbol->control_variable->datatype; // set the stage3 anottation we need
+    inc_assignment.accept(*this);
+    //symbol->control_variable->accept(*this);  // this does not work for VAR_GLOBAL variables
+    //s4o.print("++");
+  } else {
+    /* increment by user defined value  */
+    /* For the increment part, we create an add_expression_c and assignment_statement_c   */
+    /* and have this visitor vist the latter!                                             */ 
+    add_expression_c       add_expression(symbol->control_variable, symbol->by_expression);
+    assignment_statement_c inc_assignment(symbol->control_variable, &add_expression);
+    add_expression.datatype = symbol->control_variable->datatype; // set the stage3 anottation we need
+    inc_assignment.accept(*this);
+    //symbol->control_variable->accept(*this);  // this does not work for VAR_GLOBAL variables
+    //s4o.print(" += (");
+    //symbol->by_expression->accept(*this);
+    //s4o.print(")");
+  }  
+  
   s4o.indent_left();
-  s4o.print(s4o.indent_spaces); s4o.print("}");
+  s4o.print(";\n" + s4o.indent_spaces + "} /* END_FOR */");
   return NULL;
 }