Fix code generation of FOR loops. Now handles negative values of BY correctly.
--- 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;