twinbasic / twinbasic

284 stars 23 forks source link

Function of Loop statement does not execute after continue Do #1075

Closed FullValueRider closed 2 years ago

FullValueRider commented 2 years ago

Describe the bug I've been experiencing some issues with never ending loops using the Iterator class I've written (IterItems). The tests for the class work fine.

The code below demonstrates the issue

Sub TestFunctionOnLoopStatement()
    Dim myCounter As Long = 0
    Do
        myCounter += 1
        Debug.Print myCounter,
        If myCounter < 10 Then
            Continue Do
        End If
    Loop While LoopEnd
End Sub

Public Function LoopEnd() As Boolean
Debug.Print
    Debug.Print "I get printed once, not 10 times."
    Return False
End Function

NoLoopFunction

Expected behavior The 'Continue Do' should ensure that the loop terminating test is run. So the 'Continue Do' statement should check to see if the loop statement contains the While or Until qualifier and if yes execute the code that follows. I'd be perfectly happy if the 'Continue Do' was complemented by a 'Continue Loop' so that the programmer could direct code to where the loop terminating condition is located.

Desktop (please complete the following information):

Additional context This issue means I have to encapsulate code in a 'If Endif' for those occasions where an 'Continue Do' would be cleaner. This is perhaps more significant for me than it would first seem as for some weeks now I've been using my Iterator class (which uses do loop) in place of For Next loops as it avoids me having to use a custom IEnumVariant, can iterate backwards as well as forwards, iterates linear containers (including strings) and provides a couple of other useful functionalities that facilitate working to multiple items that need to be enumerated.

As an example here is some code for Advent of Code Day10 Part 2 which shows the iterator in use.

Public Sub Part02()

        Initialise
        Dim myScoring As Hkvp = Hkvp.Deb.AddPairs(Split(") ] } >"), Array(1, 2, 3, 4))
        Dim myScores As Seq = Seq.Deb

        Dim myResult As Long = 0
        Dim myString As IterItems = IterItems(s.Data).MoveToEnd
        Do
            Dim myStack As Seq = Seq.Deb
            Dim myChar As IterItems = IterItems(myString.Item)
            Do
                Dim myC As String = myChar.Item
                If s.Openers.HoldsKey(myC) Then
                    myStack.Push myC
                Else
                    Dim myS As String = s.Openers.Item(myStack.Last)
                    If myS = myC Then
                        myStack.Pop
                    Else
                        'we have found a broken chunk
                        myStack.Clear
                        Exit Do
                    End If
                End If

            Loop While myChar.MoveNext

            If myStack.IsNotQueryable Then
                Continue Do  ' This is where I found the problem as the mystring.moveprev is not executed
            End If

            myResult = 0
            Dim myCompletionchar As IterItems = IterItems(myStack).MoveToEnd
            Do
                myResult *= 5
                myResult += myScoring.Item(s.Openers.Item(myCompletionchar.Item))

            Loop While myCompletionchar.MovePrev
            myScores.Add myResult

        Loop While myString.MovePrev

        Fmt.Dbg "The answer to Day {0} part 2 is {1}.  Found is {2}", VBA.Mid$(InputData, 4, 2), "xxxxxxxxx", myResult

    End Sub
WaynePhillipsEA commented 2 years ago

Fixed in BETA 90, thanks