1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.millscript.millscript.action;
22
23 import org.millscript.commons.alert.alerts.Fault;
24 import org.millscript.millscript.expr.Ident;
25 import org.millscript.millscript.tools.CastLibrary;
26 import org.millscript.millscript.vm.Machine;
27 import org.millscript.millscript.vm.Ref;
28
29 /**
30 * This class represents a for loop from-to counter binding action. A from-to
31 * counter action binds a counter to a name, where the counter increases on each
32 * iteration, up to a specified value. This condition will cause the for loop to
33 * terminate when the counter reaches the end value.
34 */
35 public final class BindingFromToAction extends BindingAction {
36
37 /**
38 * This class implements the underlying iterator for the
39 * <code>from .. to ..</code> binding in a <code>for</code> loop.
40 */
41 private final class BindingFromToIterator extends ForIterator {
42
43 /**
44 * The value to stop counting at.
45 */
46 private final int toInt;
47
48 /**
49 * The current value of this iterator.
50 */
51 private int count;
52
53 /**
54 * Constructs a new from-to iterator to start counting from and stop
55 * counting at the specified values.
56 *
57 * @param f the value to start counting from
58 * @param t the value to stop counting at
59 */
60 private BindingFromToIterator( final int f, final int t ) {
61 this.count = f;
62 this.toInt = t;
63 }
64
65 /**
66 * @see org.millscript.millscript.action.ForConditionAction.ForIterator#bindAction(org.millscript.millscript.vm.Machine)
67 */
68 @Override
69 public void bindAction( final Machine mc ) {
70
71 mc.saveRef( ref );
72 if ( count > toInt ) {
73 throw new Fault( "End of range reached" ).mishap();
74 } else {
75
76 ref.value = new Integer( count++ );
77 }
78 }
79
80 /**
81 * @see org.millscript.millscript.action.ForConditionAction.ForIterator#hasNext()
82 */
83 @Override
84 public boolean hasNext() {
85
86
87 return count <= toInt;
88 }
89
90 }
91
92 /**
93 * The Ref to bind successive values to.
94 */
95 Ref ref;
96
97 /**
98 * The Ident to bind successive values to.
99 */
100 private Ident var;
101
102 /**
103 * The action that generates the starting point for the counter.
104 */
105 private Action fromAct;
106
107 /**
108 * The action that generates the end point for the counter.
109 */
110 private Action toAct;
111
112 /**
113 * Constructs a new from-to counter binding action, with the suplied name,
114 * starting point and end point actions.
115 *
116 * @param a Ident of the variable this action is bound to
117 * @param b Action which generates the starting point for the counter
118 * @param c Action which generates the end point for the counter
119 */
120 public BindingFromToAction( final Ident a, final Action b, final Action c ) {
121 var = a;
122 ref = var.getRef();
123 fromAct = b;
124 toAct = c;
125 }
126
127 /**
128 * @see org.millscript.millscript.action.ForConditionAction#getForIterator(org.millscript.millscript.vm.Machine)
129 */
130 @Override
131 ForIterator getForIterator( final Machine mc ) {
132 return new BindingFromToIterator(
133 CastLibrary.toInt( fromAct.act1( mc ) ),
134 CastLibrary.toInt( toAct.act1( mc ) )
135 );
136 }
137
138 }