Fix code generation of FOR loops. Now handles negative values of BY correctly.
authorMario de Sousa <msousa@fe.up.pt>
Sat, 29 Oct 2011 19:30:47 +0100
changeset 387 db368e53133c
parent 386 606443ffd589
child 388 17eaad42ba88
Fix code generation of FOR loops. Now handles negative values of BY correctly.
stage4/generate_c/generate_c_st.cc
--- a/stage4/generate_c/generate_c_st.cc	Sat Oct 29 18:56:25 2011 +0100
+++ b/stage4/generate_c/generate_c_st.cc	Sat Oct 29 19:30:47 2011 +0100
@@ -1207,24 +1207,49 @@
   s4o.print(" = ");
   symbol->beg_expression->accept(*this);
   s4o.print("; ");
-  symbol->control_variable->accept(*this);
-  s4o.print(" != ");
-  symbol->end_expression->accept(*this);
-  s4o.print("; ");
-  symbol->control_variable->accept(*this);
-  if (symbol->by_expression != NULL) {
-    s4o.print(" += ");
+  if (symbol->by_expression == NULL) {
+    /* 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
+     * the expression to determine whether we have reached the end of the loop
+     * changes from a '<=' to a '>='.
+     * Since the increment value may change during runtime (remember, it is
+     * an expression, so may contain variables), choosing which test
+     * to use has to be done at runtime.
+     */
+    s4o.print("((");
     symbol->by_expression->accept(*this);
-  } else {
-    s4o.print("++");
-  }
-  s4o.print(") {\n");
+    s4o.print(") > 0)? (");
+    symbol->control_variable->accept(*this);
+    s4o.print(" <= (");
+    symbol->end_expression->accept(*this);
+    s4o.print(")) : (");
+    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(" {\n");
   s4o.indent_right();
   symbol->statement_list->accept(*this);
   s4o.indent_left();
   s4o.print(s4o.indent_spaces); s4o.print("}");
   return NULL;
 }
+
 void *visit(while_statement_c *symbol) {
   s4o.print("while (");
   symbol->expression->accept(*this);
@@ -1235,6 +1260,7 @@
   s4o.print(s4o.indent_spaces); s4o.print("}");
   return NULL;
 }
+
 void *visit(repeat_statement_c *symbol) {
   s4o.print("do {\n");
   s4o.indent_right();
@@ -1245,6 +1271,7 @@
   s4o.print(")");
   return NULL;
 }
+
 void *visit(exit_statement_c *symbol) {
   s4o.print("break");
   return NULL;