Operator Step (Iteration)
Increments the iterator of a For...Next loop
For iterator [ As typename ] = start_value To end_value [ Step step_value ]
typename
stp, step_value
Operator For, Operator Next and Operator Step can be overloaded in user-defined type definitions to allow objects of that type to be used as iterators and step values in For...Next loops.
Operator Step is called to increment the iterator immediately after all statements in the For...Next body are executed, if any.
The first version of Operator Step is used if no step value is given in the For...Next statement. If a step value is given, the second version is used and is passed the step value.
A more practical example demonstrating file iteration based on cha0s' file iteration class.
Another example working with strings:
Iterating with fractions:
Syntax
Usage
For iterator [ As typename ] = start_value To end_value [ Step step_value ]
[ ...statements... ]
NextParameters
typename
stp, step_value
a typename object used as an incremental value
iteratora typename object used as an iterator
end_valuea typename object used as a loop-terminating value
start_valuea typename object used to copy construct or assign to the iterator initially
Description
Operator For, Operator Next and Operator Step can be overloaded in user-defined type definitions to allow objects of that type to be used as iterators and step values in For...Next loops.
Operator Step is called to increment the iterator immediately after all statements in the For...Next body are executed, if any.
The first version of Operator Step is used if no step value is given in the For...Next statement. If a step value is given, the second version is used and is passed the step value.
Example
'' Example Type
Type T
'' value is set by the constructor
value As Double
Declare Constructor( ByVal x As Double = 0 )
Declare Operator For( ByRef stp As T )
Declare Operator Step( ByRef stp As T )
Declare Operator Next( ByRef cond As T, ByRef stp As T ) As Integer
End Type
Constructor T ( ByVal x As Double )
Print "T iterator constructed with value " & x
value = x
End Constructor
Operator T.for( ByRef stp As T )
End Operator
Operator T.step( ByRef stp As T )
Print " incremented by " & stp.value & " in step."
value += stp.value
End Operator
Operator T.next( ByRef cond As T, ByRef stp As T ) As Integer
'' iterator's moving from a high value to a low value (step >= 0)
If( stp.value < 0 ) Then
Return( value >= cond.value )
Else
'' iterator's moving from a low value to a high value (step < 0)
Return( value <= cond.value )
End If
End Operator
'' Example Usage. It looks like we are working with numbers, but the iterators
'' have overloaded constructors. The 10, 1, and -1 are all of type T.
For i As T = 10 To 1 Step -1
Print i.value;
Next i
Type T
'' value is set by the constructor
value As Double
Declare Constructor( ByVal x As Double = 0 )
Declare Operator For( ByRef stp As T )
Declare Operator Step( ByRef stp As T )
Declare Operator Next( ByRef cond As T, ByRef stp As T ) As Integer
End Type
Constructor T ( ByVal x As Double )
Print "T iterator constructed with value " & x
value = x
End Constructor
Operator T.for( ByRef stp As T )
End Operator
Operator T.step( ByRef stp As T )
Print " incremented by " & stp.value & " in step."
value += stp.value
End Operator
Operator T.next( ByRef cond As T, ByRef stp As T ) As Integer
'' iterator's moving from a high value to a low value (step >= 0)
If( stp.value < 0 ) Then
Return( value >= cond.value )
Else
'' iterator's moving from a low value to a high value (step < 0)
Return( value <= cond.value )
End If
End Operator
'' Example Usage. It looks like we are working with numbers, but the iterators
'' have overloaded constructors. The 10, 1, and -1 are all of type T.
For i As T = 10 To 1 Step -1
Print i.value;
Next i
A more practical example demonstrating file iteration based on cha0s' file iteration class.
'' a class which iterates through files
Type FileIter
As String pathName, fileName
Declare Constructor( ByRef pathName As String )
Declare Operator For()
Declare Operator Step()
Declare Operator Next( ByRef endCond As FileIter) As Integer
End Type
Constructor FileIter( ByRef pathName As String )
this.pathName = pathName
End Constructor
Operator FileIter.for( )
fileName = Dir(pathName & "/*.*")
End Operator
Operator FileIter.step( )
fileName = Dir("")
End Operator
Operator FileIter.next( ByRef endCond As FileIter ) As Integer
Return(fileName <> endCond.pathName)
'' the c'tor sets the path name and so we check against that
End Operator
'' example code
'' change it to any directory
For i As FileIter = "./" To ""
Print i.fileName
Next
Type FileIter
As String pathName, fileName
Declare Constructor( ByRef pathName As String )
Declare Operator For()
Declare Operator Step()
Declare Operator Next( ByRef endCond As FileIter) As Integer
End Type
Constructor FileIter( ByRef pathName As String )
this.pathName = pathName
End Constructor
Operator FileIter.for( )
fileName = Dir(pathName & "/*.*")
End Operator
Operator FileIter.step( )
fileName = Dir("")
End Operator
Operator FileIter.next( ByRef endCond As FileIter ) As Integer
Return(fileName <> endCond.pathName)
'' the c'tor sets the path name and so we check against that
End Operator
'' example code
'' change it to any directory
For i As FileIter = "./" To ""
Print i.fileName
Next
Another example working with strings:
Type CharIterator
'' used to build a step var
Declare Constructor( ByVal r As ZString Ptr )
'' implicit step versions
Declare Operator For ( )
Declare Operator Step( )
Declare Operator Next( ByRef end_cond As CharIterator ) As Integer
'' explicit step versions
Declare Operator For ( ByRef step_var As CharIterator )
Declare Operator Step( ByRef step_var As CharIterator )
Declare Operator Next( ByRef end_cond As CharIterator, ByRef step_var As CharIterator ) As Integer
'' give the current "value"
Declare Operator Cast( ) As String
Private:
'' data
value As String
'' This member isn't necessary - we could use
'' the step variable on each iteration -
'' but we choose this method, since we have
'' to compare strings otherwise. See below.
is_up As Integer
End Type
Constructor CharIterator( ByVal r As ZString Ptr )
value = *r
End Constructor
Operator CharIterator.cast( ) As String
Operator = value
End Operator
'' implicit step versions
''
'' In this example, we interpret implicit step
'' to always mean 'up'
Operator CharIterator.for( )
Print "implicit step"
End Operator
Operator CharIterator.step( )
value[0] += 1
End Operator
Operator CharIterator.next( ByRef end_cond As CharIterator ) As Integer
Return this.value <= end_cond.value
End Operator
'' explicit step versions
''
'' In this example, we calculate the direction
'' at FOR, but since the step var is passed to
'' each operator, we have the choice to also calculate
'' it "on-the-fly". For strings such as this, repeated comparison
'' may penalize, but if you're working with simpler types,
'' then you may prefer to avoid the overhead of
'' an 'is_up' variable.
Operator CharIterator.for( ByRef step_var As CharIterator )
Print "explicit step"
is_up = (step_var.value = "up")
End Operator
Operator CharIterator.step( ByRef step_var As CharIterator )
If( is_up ) Then
value[0] += 1
Else
value[0] -= 1
End If
End Operator
Operator CharIterator.next( ByRef end_cond As CharIterator, ByRef step_var As CharIterator ) As Integer
If( this.is_up ) Then
Return this.value <= end_cond.value
Else
Return this.value >= end_cond.value
End If
End Operator
For i As CharIterator = "a" To "z"
Print i; " ";
Next
Print "done"
For i As CharIterator = "a" To "z" Step "up"
Print i; " ";
Next
Print "done"
For i As CharIterator = "z" To "a" Step "down"
Print i; " ";
Next
Print "done"
For i As CharIterator = "z" To "a" Step "up"
Print i; " ";
Next
Print "done"
'' used to build a step var
Declare Constructor( ByVal r As ZString Ptr )
'' implicit step versions
Declare Operator For ( )
Declare Operator Step( )
Declare Operator Next( ByRef end_cond As CharIterator ) As Integer
'' explicit step versions
Declare Operator For ( ByRef step_var As CharIterator )
Declare Operator Step( ByRef step_var As CharIterator )
Declare Operator Next( ByRef end_cond As CharIterator, ByRef step_var As CharIterator ) As Integer
'' give the current "value"
Declare Operator Cast( ) As String
Private:
'' data
value As String
'' This member isn't necessary - we could use
'' the step variable on each iteration -
'' but we choose this method, since we have
'' to compare strings otherwise. See below.
is_up As Integer
End Type
Constructor CharIterator( ByVal r As ZString Ptr )
value = *r
End Constructor
Operator CharIterator.cast( ) As String
Operator = value
End Operator
'' implicit step versions
''
'' In this example, we interpret implicit step
'' to always mean 'up'
Operator CharIterator.for( )
Print "implicit step"
End Operator
Operator CharIterator.step( )
value[0] += 1
End Operator
Operator CharIterator.next( ByRef end_cond As CharIterator ) As Integer
Return this.value <= end_cond.value
End Operator
'' explicit step versions
''
'' In this example, we calculate the direction
'' at FOR, but since the step var is passed to
'' each operator, we have the choice to also calculate
'' it "on-the-fly". For strings such as this, repeated comparison
'' may penalize, but if you're working with simpler types,
'' then you may prefer to avoid the overhead of
'' an 'is_up' variable.
Operator CharIterator.for( ByRef step_var As CharIterator )
Print "explicit step"
is_up = (step_var.value = "up")
End Operator
Operator CharIterator.step( ByRef step_var As CharIterator )
If( is_up ) Then
value[0] += 1
Else
value[0] -= 1
End If
End Operator
Operator CharIterator.next( ByRef end_cond As CharIterator, ByRef step_var As CharIterator ) As Integer
If( this.is_up ) Then
Return this.value <= end_cond.value
Else
Return this.value >= end_cond.value
End If
End Operator
For i As CharIterator = "a" To "z"
Print i; " ";
Next
Print "done"
For i As CharIterator = "a" To "z" Step "up"
Print i; " ";
Next
Print "done"
For i As CharIterator = "z" To "a" Step "down"
Print i; " ";
Next
Print "done"
For i As CharIterator = "z" To "a" Step "up"
Print i; " ";
Next
Print "done"
Iterating with fractions:
Type fraction
'' Used to build a step var
Declare Constructor( ByVal n As Integer, ByVal d As Integer )
'' Implicit step versions
Declare Operator For ( )
Declare Operator Step( )
Declare Operator Next( ByRef end_cond As fraction ) As Integer
'' Explicit step versions
Declare Operator For ( ByRef step_var As fraction )
Declare Operator Step( ByRef step_var As fraction )
Declare Operator Next( ByRef end_cond As fraction, ByRef step_var As fraction ) As Integer
'' Give the current "value"
Declare Operator Cast( ) As Double
Declare Operator Cast( ) As String
Private:
As Integer num, den
End Type
Constructor fraction( ByVal n As Integer, ByVal d As Integer )
this.num = n : this.den = d
End Constructor
Operator fraction.cast( ) As Double
Operator = num / den
End Operator
Operator fraction.cast( ) As String
Operator = num & "/" & den
End Operator
'' Some fraction functions
Function gcd( ByVal n As Integer, ByVal m As Integer ) As Integer
Dim As Integer t
While m <> 0
t = m
m = n Mod m
n = t
Wend
Return n
End Function
Function lcd( ByVal n As Integer, ByVal m As Integer ) As Integer
Return (n * m) / gcd( n, m )
End Function
''
'' Implicit step versions
''
'' In this example, we interpret implicit step
'' to mean 1
''
Operator fraction.for( )
Print "implicit step"
End Operator
Operator fraction.step( )
Var lowest = lcd( this.den, 1 )
Var mult_factor = this.den / lowest
Dim As fraction step_temp = fraction( 1, 1 )
this.num *= mult_factor
this.den *= mult_factor
step_temp.num *= lowest
step_temp.den *= lowest
this.num += step_temp.num
End Operator
Operator fraction.next( ByRef end_cond As fraction ) As Integer
Return This <= end_cond
End Operator
''
'' Explicit step versions
''
Operator fraction.for( ByRef step_var As fraction )
Print "explicit step"
End Operator
Operator fraction.step( ByRef step_var As fraction )
Var lowest = lcd( this.den, step_var.den )
Var mult_factor = this.den / lowest
Dim As fraction step_temp = step_var
this.num *= mult_factor
this.den *= mult_factor
mult_factor = step_temp.den / lowest
step_temp.num *= mult_factor
step_temp.den *= mult_factor
this.num += step_temp.num
End Operator
Operator fraction.next( ByRef end_cond As fraction, ByRef step_var As fraction ) As Integer
If(( step_var.num < 0 ) Or ( step_var.den < 0 ) ) Then
Return This >= end_cond
Else
Return This <= end_cond
End If
End Operator
For i As fraction = fraction(1,1) To fraction(4,1)
Print i; " ";
Next
Print "done"
For i As fraction = fraction(1,4) To fraction(1,1) Step fraction(1,4)
Print i; " ";
Next
Print "done"
For i As fraction = fraction(4,4) To fraction(1,4) Step fraction(-1,4)
Print i; " ";
Next
Print "done"
For i As fraction = fraction(4,4) To fraction(1,4)
Print i; " ";
Next
Print "done"
'' Used to build a step var
Declare Constructor( ByVal n As Integer, ByVal d As Integer )
'' Implicit step versions
Declare Operator For ( )
Declare Operator Step( )
Declare Operator Next( ByRef end_cond As fraction ) As Integer
'' Explicit step versions
Declare Operator For ( ByRef step_var As fraction )
Declare Operator Step( ByRef step_var As fraction )
Declare Operator Next( ByRef end_cond As fraction, ByRef step_var As fraction ) As Integer
'' Give the current "value"
Declare Operator Cast( ) As Double
Declare Operator Cast( ) As String
Private:
As Integer num, den
End Type
Constructor fraction( ByVal n As Integer, ByVal d As Integer )
this.num = n : this.den = d
End Constructor
Operator fraction.cast( ) As Double
Operator = num / den
End Operator
Operator fraction.cast( ) As String
Operator = num & "/" & den
End Operator
'' Some fraction functions
Function gcd( ByVal n As Integer, ByVal m As Integer ) As Integer
Dim As Integer t
While m <> 0
t = m
m = n Mod m
n = t
Wend
Return n
End Function
Function lcd( ByVal n As Integer, ByVal m As Integer ) As Integer
Return (n * m) / gcd( n, m )
End Function
''
'' Implicit step versions
''
'' In this example, we interpret implicit step
'' to mean 1
''
Operator fraction.for( )
Print "implicit step"
End Operator
Operator fraction.step( )
Var lowest = lcd( this.den, 1 )
Var mult_factor = this.den / lowest
Dim As fraction step_temp = fraction( 1, 1 )
this.num *= mult_factor
this.den *= mult_factor
step_temp.num *= lowest
step_temp.den *= lowest
this.num += step_temp.num
End Operator
Operator fraction.next( ByRef end_cond As fraction ) As Integer
Return This <= end_cond
End Operator
''
'' Explicit step versions
''
Operator fraction.for( ByRef step_var As fraction )
Print "explicit step"
End Operator
Operator fraction.step( ByRef step_var As fraction )
Var lowest = lcd( this.den, step_var.den )
Var mult_factor = this.den / lowest
Dim As fraction step_temp = step_var
this.num *= mult_factor
this.den *= mult_factor
mult_factor = step_temp.den / lowest
step_temp.num *= mult_factor
step_temp.den *= mult_factor
this.num += step_temp.num
End Operator
Operator fraction.next( ByRef end_cond As fraction, ByRef step_var As fraction ) As Integer
If(( step_var.num < 0 ) Or ( step_var.den < 0 ) ) Then
Return This >= end_cond
Else
Return This <= end_cond
End If
End Operator
For i As fraction = fraction(1,1) To fraction(4,1)
Print i; " ";
Next
Print "done"
For i As fraction = fraction(1,4) To fraction(1,1) Step fraction(1,4)
Print i; " ";
Next
Print "done"
For i As fraction = fraction(4,4) To fraction(1,4) Step fraction(-1,4)
Print i; " ";
Next
Print "done"
For i As fraction = fraction(4,4) To fraction(1,4)
Print i; " ";
Next
Print "done"
Dialect Differences
- Only available in the -lang fb dialect.
See also