[vala/wip/genie: 715/716] genie: Extend "for" syntax



commit 247e932144b7f0df3ebdd947fd959a5b087f9dea
Author: vlad1777d <naumovvladislav mail ru>
Date:   Sun Apr 30 14:19:49 2017 +0300

    genie: Extend "for" syntax
    
    https://bugzilla.gnome.org/show_bug.cgi?id=781966

 tests/genie/for/for_with_ellipsis.gs |  501 ++++++++++++++++++++++++++++++++++
 vala/valagenieparser.vala            |  216 +++++++++++++--
 2 files changed, 695 insertions(+), 22 deletions(-)
---
diff --git a/tests/genie/for/for_with_ellipsis.gs b/tests/genie/for/for_with_ellipsis.gs
new file mode 100644
index 0000000..68208b8
--- /dev/null
+++ b/tests/genie/for/for_with_ellipsis.gs
@@ -0,0 +1,501 @@
+/* --pkg="gee=0.8" needed
+Old syntax: "for var i = 1 to 10", "for var i = 1 ... 10"
+New syntax: "for i in 1 to 10", "for i in 1...10"
+*/
+
+init
+       
+       old_syntax_int_up ()
+       old_syntax_int_down ()
+       old_syntax_var_up ()
+       old_syntax_var_down ()
+       old_syntax_int_up_ellipsis ()
+       old_syntax_int_down_ellipsis ()
+       old_syntax_var_up_ellipsis ()
+       old_syntax_var_down_ellipsis ()
+       old_syntax_int_up_zero_times ()
+       old_syntax_int_down_zero_times ()
+       old_syntax_var_up_zero_times ()
+       old_syntax_var_down_zero_times ()
+       
+       new_syntax_int_up ()
+       new_syntax_int_down ()
+       new_syntax_var_up ()
+       new_syntax_var_down ()
+       new_syntax_int_up_ellipsis ()
+       new_syntax_int_down_ellipsis ()
+       new_syntax_var_up_ellipsis ()
+       new_syntax_var_down_ellipsis ()
+       new_syntax_int_up_zero_times ()
+       new_syntax_int_down_zero_times ()
+       new_syntax_var_up_zero_times ()
+       new_syntax_var_down_zero_times ()
+       
+       new_syntax_up ()
+       new_syntax_down ()
+       new_syntax_up_ellipsis ()
+       new_syntax_down_ellipsis ()
+       new_syntax_up_zero_times ()
+       new_syntax_down_zero_times ()
+
+
+
+
+def old_syntax_int_up ()
+       
+       var array_1 = new list of int
+       
+       for a: int = 4 to 8
+               array_1.add (a)
+       
+       len_1: int = array_1.size
+       assert len_1 == 5
+       
+       assert array_1 [0] == 4
+       assert array_1 [1] == 5
+       assert array_1 [2] == 6
+       assert array_1 [3] == 7
+       assert array_1 [4] == 8
+
+
+def old_syntax_int_down ()
+       
+       var array_1 = new list of int
+       
+       for a: int = 8 downto 4
+               array_1.add (a)
+       
+       len_1: int = array_1.size
+       assert len_1 == 5
+       
+       assert array_1 [0] == 8
+       assert array_1 [1] == 7
+       assert array_1 [2] == 6
+       assert array_1 [3] == 5
+       assert array_1 [4] == 4
+
+
+def old_syntax_var_up ()
+       
+       var array_1 = new list of int
+       
+       for var a = 4 to 8
+               array_1.add (a)
+       
+       len_1: int = array_1.size
+       assert len_1 == 5
+       
+       assert array_1 [0] == 4
+       assert array_1 [1] == 5
+       assert array_1 [2] == 6
+       assert array_1 [3] == 7
+       assert array_1 [4] == 8
+
+
+def old_syntax_var_down ()
+       
+       var array_1 = new list of int
+       
+       for var a = 8 downto 4
+               array_1.add (a)
+       
+       len_1: int = array_1.size
+       assert len_1 == 5
+       
+       assert array_1 [0] == 8
+       assert array_1 [1] == 7
+       assert array_1 [2] == 6
+       assert array_1 [3] == 5
+       assert array_1 [4] == 4
+
+
+def old_syntax_int_up_ellipsis ()
+       
+       var array_1 = new list of int
+       
+       for a: int = 4 ... 8
+               array_1.add (a)
+       
+       len_1: int = array_1.size
+       assert len_1 == 5
+       
+       assert array_1 [0] == 4
+       assert array_1 [1] == 5
+       assert array_1 [2] == 6
+       assert array_1 [3] == 7
+       assert array_1 [4] == 8
+
+
+def old_syntax_int_down_ellipsis ()
+       
+       var array_1 = new list of int
+       
+       for a: int = 8 ... 4
+               array_1.add (a)
+       
+       len_1: int = array_1.size
+       assert len_1 == 5
+       
+       assert array_1 [0] == 8
+       assert array_1 [1] == 7
+       assert array_1 [2] == 6
+       assert array_1 [3] == 5
+       assert array_1 [4] == 4
+
+
+def old_syntax_var_up_ellipsis ()
+       
+       var array_1 = new list of int
+       
+       for var a = 4 ... 8
+               array_1.add (a)
+       
+       len_1: int = array_1.size
+       assert len_1 == 5
+       
+       assert array_1 [0] == 4
+       assert array_1 [1] == 5
+       assert array_1 [2] == 6
+       assert array_1 [3] == 7
+       assert array_1 [4] == 8
+
+
+def old_syntax_var_down_ellipsis ()
+       
+       var array_1 = new list of int
+       
+       for var a = 8 ... 4
+               array_1.add (a)
+       
+       len_1: int = array_1.size
+       assert len_1 == 5
+       
+       assert array_1 [0] == 8
+       assert array_1 [1] == 7
+       assert array_1 [2] == 6
+       assert array_1 [3] == 5
+       assert array_1 [4] == 4
+
+
+def old_syntax_int_up_zero_times ()
+       
+       var array_1 = new list of int
+       
+       for a: int = 8 to 4
+               array_1.add (a)
+       
+       len_1: int = array_1.size
+       assert len_1 == 0
+
+
+def old_syntax_int_down_zero_times ()
+       
+       var array_1 = new list of int
+       
+       for a: int = 4 downto 8
+               array_1.add (a)
+       
+       len_1: int = array_1.size
+       assert len_1 == 0
+
+
+def old_syntax_var_up_zero_times ()
+       
+       var array_1 = new list of int
+       
+       for var a = 8 to 4
+               array_1.add (a)
+       
+       len_1: int = array_1.size
+       assert len_1 == 0
+
+
+def old_syntax_var_down_zero_times ()
+       
+       var array_1 = new list of int
+       
+       for var a = 4 downto 8
+               array_1.add (a)
+       
+       len_1: int = array_1.size
+       assert len_1 == 0
+
+
+
+
+def new_syntax_int_up ()
+       
+       var array_1 = new list of int
+       
+       for a: int in 4 to 8
+               array_1.add (a)
+       
+       len_1: int = array_1.size
+       assert len_1 == 5
+       
+       assert array_1 [0] == 4
+       assert array_1 [1] == 5
+       assert array_1 [2] == 6
+       assert array_1 [3] == 7
+       assert array_1 [4] == 8
+
+
+def new_syntax_int_down ()
+       
+       var array_1 = new list of int
+       
+       for a: int in 8 downto 4
+               array_1.add (a)
+       
+       len_1: int = array_1.size
+       assert len_1 == 5
+       
+       assert array_1 [0] == 8
+       assert array_1 [1] == 7
+       assert array_1 [2] == 6
+       assert array_1 [3] == 5
+       assert array_1 [4] == 4
+
+
+def new_syntax_var_up ()
+       
+       var array_1 = new list of int
+       
+       for var a in 4 to 8
+               array_1.add (a)
+       
+       len_1: int = array_1.size
+       assert len_1 == 5
+       
+       assert array_1 [0] == 4
+       assert array_1 [1] == 5
+       assert array_1 [2] == 6
+       assert array_1 [3] == 7
+       assert array_1 [4] == 8
+
+
+def new_syntax_var_down ()
+       
+       var array_1 = new list of int
+       
+       for var a in 8 downto 4
+               array_1.add (a)
+       
+       len_1: int = array_1.size
+       assert len_1 == 5
+       
+       assert array_1 [0] == 8
+       assert array_1 [1] == 7
+       assert array_1 [2] == 6
+       assert array_1 [3] == 5
+       assert array_1 [4] == 4
+
+
+def new_syntax_int_up_ellipsis ()
+       
+       var array_1 = new list of int
+       
+       for a: int in 4 ... 8
+               array_1.add (a)
+       
+       len_1: int = array_1.size
+       assert len_1 == 5
+       
+       assert array_1 [0] == 4
+       assert array_1 [1] == 5
+       assert array_1 [2] == 6
+       assert array_1 [3] == 7
+       assert array_1 [4] == 8
+
+
+def new_syntax_int_down_ellipsis ()
+       
+       var array_1 = new list of int
+       
+       for a: int in 8 ... 4
+               array_1.add (a)
+       
+       len_1: int = array_1.size
+       assert len_1 == 5
+       
+       assert array_1 [0] == 8
+       assert array_1 [1] == 7
+       assert array_1 [2] == 6
+       assert array_1 [3] == 5
+       assert array_1 [4] == 4
+
+
+def new_syntax_var_up_ellipsis ()
+       
+       var array_1 = new list of int
+       
+       for var a in 4 ... 8
+               array_1.add (a)
+       
+       len_1: int = array_1.size
+       assert len_1 == 5
+       
+       assert array_1 [0] == 4
+       assert array_1 [1] == 5
+       assert array_1 [2] == 6
+       assert array_1 [3] == 7
+       assert array_1 [4] == 8
+
+
+def new_syntax_var_down_ellipsis ()
+       
+       var array_1 = new list of int
+       
+       for var a in 8 ... 4
+               array_1.add (a)
+       
+       len_1: int = array_1.size
+       assert len_1 == 5
+       
+       assert array_1 [0] == 8
+       assert array_1 [1] == 7
+       assert array_1 [2] == 6
+       assert array_1 [3] == 5
+       assert array_1 [4] == 4
+
+
+def new_syntax_int_up_zero_times ()
+       
+       var array_1 = new list of int
+       
+       for a: int in 8 to 4
+               array_1.add (a)
+       
+       len_1: int = array_1.size
+       assert len_1 == 0
+
+
+def new_syntax_int_down_zero_times ()
+       
+       var array_1 = new list of int
+       
+       for a: int in 4 downto 8
+               array_1.add (a)
+       
+       len_1: int = array_1.size
+       assert len_1 == 0
+
+
+def new_syntax_var_up_zero_times ()
+       
+       var array_1 = new list of int
+       
+       for var a in 8 to 4
+               array_1.add (a)
+       
+       len_1: int = array_1.size
+       assert len_1 == 0
+
+
+def new_syntax_var_down_zero_times ()
+       
+       var array_1 = new list of int
+       
+       for var a in 4 downto 8
+               array_1.add (a)
+       
+       len_1: int = array_1.size
+       assert len_1 == 0
+
+
+
+
+def new_syntax_up ()
+       
+       var array_1 = new list of int
+       
+       var c = 18 - 14
+       
+       for a in c to 8
+               array_1.add (a)
+       
+       len_1: int = array_1.size
+       assert len_1 == 5
+       
+       assert array_1 [0] == 4
+       assert array_1 [1] == 5
+       assert array_1 [2] == 6
+       assert array_1 [3] == 7
+       assert array_1 [4] == 8
+
+
+def new_syntax_down ()
+       
+       var array_1 = new list of int
+       
+       c: int = 8
+       
+       for a in c downto 4
+               array_1.add (a)
+       
+       len_1: int = array_1.size
+       assert len_1 == 5
+       
+       assert array_1 [0] == 8
+       assert array_1 [1] == 7
+       assert array_1 [2] == 6
+       assert array_1 [3] == 5
+       assert array_1 [4] == 4
+
+
+def new_syntax_up_ellipsis ()
+       
+       var array_1 = new list of int
+       
+       var c = 18 - 14
+       
+       for a in c ... 8
+               array_1.add (a)
+       
+       len_1: int = array_1.size
+       assert len_1 == 5
+       
+       assert array_1 [0] == 4
+       assert array_1 [1] == 5
+       assert array_1 [2] == 6
+       assert array_1 [3] == 7
+       assert array_1 [4] == 8
+
+
+def new_syntax_down_ellipsis ()
+       
+       var array_1 = new list of int
+       
+       for a in 8 ... 4
+               array_1.add (a)
+       
+       len_1: int = array_1.size
+       assert len_1 == 5
+       
+       assert array_1 [0] == 8
+       assert array_1 [1] == 7
+       assert array_1 [2] == 6
+       assert array_1 [3] == 5
+       assert array_1 [4] == 4
+
+
+def new_syntax_up_zero_times ()
+       
+       var array_1 = new list of int
+       
+       for a in 4 downto 8
+               array_1.add (a)
+       
+       len_1: int = array_1.size
+       assert len_1 == 0
+
+
+def new_syntax_down_zero_times ()
+       
+       var array_1 = new list of int
+       
+       for a in 8 to 4
+               array_1.add (a)
+       
+       len_1: int = array_1.size
+       assert len_1 == 0
diff --git a/vala/valagenieparser.vala b/vala/valagenieparser.vala
index df4f66e..ed08cd7 100644
--- a/vala/valagenieparser.vala
+++ b/vala/valagenieparser.vala
@@ -1674,26 +1674,33 @@ public class Vala.Genie.Parser : CodeVisitor {
                return expr;
        }
 
-
-       Statement get_for_statement_type () throws ParseError {
+       Statement parse_for_statement () throws ParseError {
        
                var begin = get_location ();
-               bool is_foreach = false;
+               bool to_downto_met = false;
+               bool in_met = false;
                                                                                
                while (current () != TokenType.EOL && current () != TokenType.DO) {
                        next ();
+
                        if (accept (TokenType.IN)) {
-                               is_foreach = true;
-                               break;
+                               in_met = true;
+                       }
+                       if (accept (TokenType.TO) || accept (TokenType.DOWNTO) || accept 
(TokenType.ELLIPSIS)) {
+                               to_downto_met = true;
                        }
                }
-                                       
+
                rollback (begin);
-                                       
-               if (is_foreach) {
-                       return parse_foreach_statement ();
-               } else {
-                       return parse_for_statement ();
+
+               if (to_downto_met && in_met) {
+                       return parse_for_statement_with_in_operator_and_range ();
+               }
+               else if (in_met) {
+                       return parse_for_statement_with_in_operator_and_iterator ();
+               }
+               else {
+                       return parse_for_statement_with_var_operator_and_range ();
                }
 
        }
@@ -1756,7 +1763,7 @@ public class Vala.Genie.Parser : CodeVisitor {
                                        stmt = parse_do_statement ();
                                        break;
                                case TokenType.FOR:
-                                       stmt = get_for_statement_type ();
+                                       stmt = parse_for_statement ();
                                        break;
                                case TokenType.BREAK:
                                        stmt = parse_break_statement ();
@@ -1879,7 +1886,7 @@ public class Vala.Genie.Parser : CodeVisitor {
                case TokenType.CASE:      return parse_switch_statement ();
                case TokenType.WHILE:    return parse_while_statement ();
                case TokenType.DO:              return parse_do_statement ();
-               case TokenType.FOR:        return get_for_statement_type ();
+               case TokenType.FOR:        return parse_for_statement ();
                case TokenType.BREAK:    return parse_break_statement ();
                case TokenType.CONTINUE:  return parse_continue_statement ();
                case TokenType.RETURN:  return parse_return_statement ();
@@ -2101,15 +2108,21 @@ public class Vala.Genie.Parser : CodeVisitor {
                return new DoStatement (body, condition, get_src (begin));
        }
 
-
-       Statement parse_for_statement () throws ParseError {
+       /** Parses "for" statement of such view:  "for var i = 1 to 10"
+        *    (or: "for i: int = 1 to 10", "for i = 1 to 10")
+        */
+       Statement parse_for_statement_with_var_operator_and_range () throws ParseError {
                var begin = get_location ();
                Block block = null;
                Expression initializer = null;
                Expression condition = null;
                Expression iterator = null;
+               Expression int_start_expr = null;    // for dynamic analysis
                bool is_expr;
                string id;
+               int int_amount = 0;    // for static analysis
+               int int_start = 0;
+               int int_end = 0;
 
                expect (TokenType.FOR);
 
@@ -2145,12 +2158,18 @@ public class Vala.Genie.Parser : CodeVisitor {
                        if (variable_type != null) {
                                type_copy = variable_type.copy ();
                        }
-                       var local = parse_local_variable (type_copy, id);
 
+                       var local = parse_local_variable (type_copy, id);
                        block.add_statement (new DeclarationStatement (local, local.source_reference));
                }
                
-               
+               prev ();
+               if (accept (TokenType.INTEGER_LITERAL)) {    // for static analysis
+                       int_start = int.parse (get_last_string());
+                       int_amount += 1;
+                       prev ();
+               }
+               next ();
                
                if (accept (TokenType.TO)) {
                        /* create expression for condition and incrementing iterator */         
@@ -2160,10 +2179,8 @@ public class Vala.Genie.Parser : CodeVisitor {
                        var right = parse_primary_expression ();
 
                        condition = new BinaryExpression (BinaryOperator.LESS_THAN_OR_EQUAL, left, right, 
to_src);
-                       
                        iterator = new PostfixExpression (left, true, to_src);
-               } else {
-                       expect (TokenType.DOWNTO);
+               } else if (accept (TokenType.DOWNTO)) {
                        var downto_begin = get_location ();
                        var downto_src = get_src (downto_begin);
                        /* create expression for condition and decrementing iterator */
@@ -2171,8 +2188,42 @@ public class Vala.Genie.Parser : CodeVisitor {
                        var right = parse_primary_expression ();
 
                        condition = new BinaryExpression (BinaryOperator.GREATER_THAN_OR_EQUAL, left, right, 
downto_src);
-
                        iterator = new PostfixExpression (left, false, downto_src);
+               } else {
+                       expect (TokenType.ELLIPSIS);
+                       var ellipsis_begin = get_location ();
+                       var ellipsis_src_ref = get_src (ellipsis_begin);
+                       /* create expression for condition and decrementing iterator */
+                       var left = new MemberAccess (null, id, ellipsis_src_ref);
+                       Expression right = null;
+                       if (accept (TokenType.INTEGER_LITERAL)) {    // for static analysis
+                               prev ();
+                               right = parse_primary_expression ();
+                               int_end = int.parse (get_last_string());
+                               int_amount += 1;
+                       } else {
+                               right = parse_primary_expression ();
+                       }
+
+                       if (int_amount >= 2) {    // static analysis attempt
+                               if (int_start <= int_end) {
+                                       condition = new BinaryExpression (BinaryOperator.LESS_THAN_OR_EQUAL, 
left, right, ellipsis_src_ref);
+                                       iterator = new PostfixExpression (left, true, ellipsis_src_ref);
+                               } else {
+                                       condition = new BinaryExpression 
(BinaryOperator.GREATER_THAN_OR_EQUAL, left, right, ellipsis_src_ref);
+                                       iterator = new PostfixExpression (left, false, ellipsis_src_ref);
+                               }
+                       } else {    // dynamic analysis
+                               var first_lesser_second = new BinaryExpression 
(BinaryOperator.LESS_THAN_OR_EQUAL, int_start_expr, right, ellipsis_src_ref);
+
+                               var condition_if_increasing = new BinaryExpression 
(BinaryOperator.LESS_THAN_OR_EQUAL, left, right, ellipsis_src_ref);
+                               var condition_if_decreasing = new BinaryExpression 
(BinaryOperator.GREATER_THAN_OR_EQUAL, left, right, ellipsis_src_ref);
+                               condition = new ConditionalExpression (first_lesser_second, 
condition_if_increasing, condition_if_decreasing, ellipsis_src_ref);
+
+                               var iterator_if_increasing = new PostfixExpression (left, true, 
ellipsis_src_ref);
+                               var iterator_if_decreasing = new PostfixExpression (left, false, 
ellipsis_src_ref);
+                               iterator = new ConditionalExpression (first_lesser_second, 
iterator_if_increasing, iterator_if_decreasing, ellipsis_src_ref);
+                       }
                }
 
                if (!accept (TokenType.EOL)) {
@@ -2196,7 +2247,10 @@ public class Vala.Genie.Parser : CodeVisitor {
                }
        }
 
-       Statement parse_foreach_statement () throws ParseError {
+       /** Parses "for" statement of such view: "for i in array_4"
+        *     (or "for var i in array_4", or "for i: int in array_4")
+        */
+       Statement parse_for_statement_with_in_operator_and_iterator () throws ParseError {
                var begin = get_location ();
                DataType type = null;
                string id = null;
@@ -2222,6 +2276,124 @@ public class Vala.Genie.Parser : CodeVisitor {
                return new ForeachStatement (type, id, collection, body, src);
        }
 
+       /** Parses "for" statement of such view: "for i in 1 to 10"
+        *  (or "for var i in 1 to 10", or "for i: int in 1 to 10")
+        */
+       Statement parse_for_statement_with_in_operator_and_range() throws ParseError {
+               var begin = get_location ();
+               expect (TokenType.FOR);
+
+               Expression initializer = null;
+               Expression condition = null;
+               Expression iterator = null;
+               Expression variable = null;
+               SourceReference variable_src = null;
+               DataType variable_type = null;
+               string variable_id = null;
+               int int_amount = 0;    // for static analysis
+               int to_downto_dots = 1;    // to -> 1; downto -> -1; three dots -> 0
+               int int_start = 0;    // for static check
+               int int_end = 0;    // just declaration, it'll change later
+               Expression int_start_expr = null;
+               Expression int_end_expr = null;
+               var block = new Block (get_src (begin));
+
+               var int_type_symbol = new UnresolvedSymbol (null, "int", get_src (begin));
+               variable_type = new UnresolvedType.from_symbol (int_type_symbol, get_src (begin));  // 
default value
+
+               if (accept (TokenType.VAR)) {
+                       variable_src = get_src ( get_location () );
+                       variable = parse_primary_expression ();    // uses  parse_simple_name (); for simple 
names, returns MemberAccess
+                       variable_id = get_last_string ();
+               } else {
+                       variable_src = get_src ( get_location () );    // needed to build initializer
+                       variable = parse_primary_expression ();
+                       variable_id = get_last_string ();
+                       if (accept (TokenType.COLON)) {
+                               variable_type = parse_type (true, true);
+                       }
+               }
+
+               expect (TokenType.IN);
+
+               var before_int = get_location ();    // int_start
+               if ( accept (TokenType.INTEGER_LITERAL) ) {
+                       rollback (before_int);
+                       int_start_expr = parse_primary_expression ();
+                       int_start = int.parse (get_last_string());
+                       int_amount += 1;
+               }
+               else {
+                       int_start_expr = parse_primary_expression ();
+               }
+
+               var to_begins = get_location ();
+               var to_src = get_src (to_begins);
+               if (accept (TokenType.TO)) {
+                       to_downto_dots = 1;
+               } else if (accept (TokenType.DOWNTO)) {
+                       to_downto_dots = -1;
+               } else {
+                       expect (TokenType.ELLIPSIS);
+                       to_downto_dots = 0;
+               }
+
+               before_int = get_location ();    // int_end
+               if ( accept (TokenType.INTEGER_LITERAL) ) {
+                       rollback (before_int);
+                       int_end_expr = parse_primary_expression ();
+                       int_end = int.parse (get_last_string());
+                       int_amount += 1;
+               } else {
+                       int_end_expr = parse_primary_expression ();
+               }
+
+               if (to_downto_dots == 1) {
+                       condition = new BinaryExpression (BinaryOperator.LESS_THAN_OR_EQUAL, variable, 
int_end_expr, to_src);
+                       iterator = new PostfixExpression (variable, true, to_src);
+               } else if (to_downto_dots == -1) {
+                       condition = new BinaryExpression (BinaryOperator.GREATER_THAN_OR_EQUAL, variable, 
int_end_expr, to_src);
+                       iterator = new PostfixExpression (variable, false, to_src);
+               } else {    // to_downto_dots == 0
+                       if (int_amount >= 2) {    // static analysis attempt
+                               if (int_start <= int_end) {
+                                       condition = new BinaryExpression (BinaryOperator.LESS_THAN_OR_EQUAL, 
variable, int_end_expr, to_src);
+                                       iterator = new PostfixExpression (variable, true, to_src);
+                               } else {
+                                       condition = new BinaryExpression 
(BinaryOperator.GREATER_THAN_OR_EQUAL, variable, int_end_expr, to_src);
+                                       iterator = new PostfixExpression (variable, false, to_src);
+                               }
+                       } else {    // dynamic analysis
+                               var first_lesser_second = new BinaryExpression 
(BinaryOperator.LESS_THAN_OR_EQUAL, int_start_expr, int_end_expr, to_src);
+
+                               var condition_if_increasing = new BinaryExpression 
(BinaryOperator.LESS_THAN_OR_EQUAL, variable, int_end_expr, to_src);
+                               var condition_if_decreasing = new BinaryExpression 
(BinaryOperator.GREATER_THAN_OR_EQUAL, variable, int_end_expr, to_src);
+                               condition = new ConditionalExpression (first_lesser_second, 
condition_if_increasing, condition_if_decreasing, to_src);
+
+                               var iterator_if_increasing = new PostfixExpression (variable, true, to_src);
+                               var iterator_if_decreasing = new PostfixExpression (variable, false, to_src);
+                               iterator = new ConditionalExpression (first_lesser_second, 
iterator_if_increasing, iterator_if_decreasing, to_src);
+                       }
+               }
+
+               initializer = new Assignment (variable, int_start_expr, AssignmentOperator.SIMPLE, 
variable_src);
+               var initializer_2 = new MemberInitializer(variable_id, initializer);    // hack: this instead 
of "initializer" corrected error
+               var variable_class = new LocalVariable (variable_type.copy(), variable_id, initializer_2 as 
Expression, get_src (begin) ); 
+               block.add_statement (new DeclarationStatement (variable_class, 
variable_class.source_reference));
+
+               if (!accept (TokenType.EOL)) {
+                       expect (TokenType.DO);
+               }
+
+               var src = get_src (begin);
+               var body = parse_embedded_statement ();
+               var statement = new ForStatement (condition, body, src);
+               statement.add_initializer (initializer);
+               statement.add_iterator (iterator);
+               block.add_statement (statement);
+               return block;
+       }
+
        Statement parse_break_statement () throws ParseError {
                var begin = get_location ();
                expect (TokenType.BREAK);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]