Addition of loops in stdlambda
2 Things are added: Do loops and for loops. Do loops work by running an infinite loop through a jump operation until a statement is true. For loops work by running the loop n times. Do-Loop syntax is the same as VBAs For-Loops are the same too, only that putting a word behind "next" will do nothing useful. Just write "next" at the end for that loop. Both loops need all their variables defined before the loop. If not, an error occures where the variable-name will be pushed onto stack instead of its value. I added some new subs to work with these two loops. I did not change anything major in the operation-creation. Only exception to that is how for loops are interpreted, as they requiere more inline creation of tokens. (for example it needs i = i + 1 to increment its index, otherwise it would run infinetly. Mind the line 1082. This is a proof of concept, feedback would be nice.
To test:
Public Sub Test()
Dim doloop As stdLambda
Set doloop = stdLambda.CreateMultiline(Array( _
"let i = 0", _
"let x = 0", _
"do until i > 10", _
"let x = 2 + i", _
"let i = i + 1", _
"loop"))
Debug.Print doloop.Run()
Dim doloop2 As stdLambda
Set doloop2 = stdLambda.CreateMultiline(Array( _
"let i = 0", _
"let x = 0", _
"do while i =< 10", _
"let x = 2 + i", _
"let i = i + 1", _
"loop"))
Debug.Print doloop2.Run()
Dim forloop As stdLambda
Set forloop = stdLambda.CreateMultiline(Array( _
"let i = 0", _
"let x = 0", _
"for i = 1 To 10", _
"let x = 2 + i", _
"next"))
Debug.Print forloop.Run()
Dim forloop2 As stdLambda
Set forloop2 = stdLambda.CreateMultiline(Array( _
"let i = 0", _
"let x = 0", _
"for i = 1 To 10 Step +2", _
"let x = 2 + i", _
"next"))
Debug.Print forloop2.Run()
Dim forloop3 As stdLambda
Set forloop3 = stdLambda.CreateMultiline(Array( _
"let i = 0", _
"let x = 0", _
"for let i = 1 To 10", _
"let x = 2 + i", _
"next"))
Debug.Print forloop3.Run()
Dim forloop4 As stdLambda
Set forloop4 = stdLambda.CreateMultiline(Array( _
"let i = 0", _
"let x = 0", _
"for let i = 1 To 10 Step +2", _
"let x = 2 + i", _
"next"))
Debug.Print forloop4.Run()
End Sub
Was this generated with AI? lol
Needs more testing, expressions can be embedded within the for loop, currently token stream gets messed up. Example:
Dim lambda As stdLambda
Set lambda = stdLambda.CreateMultiline(Array( _
"let x = $1", _
"For i = 0 to If x > 10 Then 10 Else 20 End Step 2", _
" let x = x / 2", _
"next" _
))
Debug.Print lambda.Run(9)
Debug.Print lambda.Run(10)
Debug.Print lambda.Run(11)
or even
Dim lambda As stdLambda
Set lambda = stdLambda.CreateMultiline(Array( _
"let x = $1", _
"let i = 0", _
"For i = 0 to (10+2) Step +2", _
" let x = x / 2", _
"next" _
))
Debug.Print lambda.Run(9)
Debug.Print lambda.Run(10)
Debug.Print lambda.Run(11)
and the following infinite loops:
Dim lambda As stdLambda
Set lambda = stdLambda.CreateMultiline(Array( _
"let x = $1", _
"let i = 0", _
"For i = 0 to 10+2 Step +2", _
" let x = x / 2", _
"next" _
))
Debug.Print lambda.Run(9)
Debug.Print lambda.Run(10)
Debug.Print lambda.Run(11)
Also not a fan that you have to define the variable first else it will fail. I.E.
Dim forloop As stdLambda
Set forloop = stdLambda.CreateMultiline(Array( _
"let i = 0", _
"let x = 0", _
"for i = 1 To 10", _
" let x = 2 + i", _
"next"))
Debug.Print forloop.Run()
Works but
Dim forloop As stdLambda
Set forloop = stdLambda.CreateMultiline(Array( _
"let x = 0", _
"for i = 1 To 10", _
" let x = 2 + i", _
"next"))
Debug.Print forloop.Run()
fails...
Ultimately syntax should be:
for {var} = {expr} to {expr} Step {expr}
{block}
next
Was this generated with AI? lol
ouch. Did you also test the do loop or am i to assume that that one works?
Im sorry if my pull requests are a mess, im new to this. I updated the code for the points mentioned for you. Here are the used tests for this request.
' Very creative names i know
Public Sub Testing()
Dim i As Long
For i = 0 To 20
Debug.Print i & "-------------------------------"
Debug.Print "TestForLoop " & i & ": " & TestForLoop(i)
Debug.Print "TestIfInUbound " & i & ": " & TestIfInUbound(i)
Debug.Print "TestParantInUbound " & i & ": " & TestParantInUbound(i)
Debug.Print "TestExprInUbound " & i & ": " & TestExprInUbound(i)
Debug.Print "TestForLoopPredeclared " & i & ": " & TestForLoopPredeclared(i)
Debug.Print "TestFunctionInForLoop " & i & ": " & TestFunctionInForLoop(i)
' Debug.Print "TestFunctionInForLoop2 " & i & ": " & TestFunctionInForLoop2(i)
Debug.Print "TestFunctionInDoLoop " & i & ": " & TestFunctionInDoLoop(i)
Debug.Print "TestFunctionInDoLoopWithWhileAtEnd " & i & ": " & TestFunctionInDoLoopWithWhileAtEnd(i)
Debug.Print "TestFunctionInDoLoopExit " & i & ": " & TestFunctionInDoLoopExit(i)
Next i
End Sub
Function TestForLoop(index As Long)
Static Lambda As stdLambda
If Lambda Is Nothing Then Set Lambda = stdLambda.CreateMultiline(Array( _
"for i = 1 To $1", _
" let x = 2 + i", _
"next"))
TestForLoop = Lambda.Run(index)
End Function
Function TestIfInUbound(index As Long)
Static Lambda As stdLambda
If Lambda Is Nothing Then Set Lambda = stdLambda.CreateMultiline(Array( _
"let x = $1", _
"For i = 0 to If x > 10 Then 10 Else 20 End Step +2", _
" let x = x / 2", _
"next" _
))
TestIfInUbound = Lambda.Run(index)
End Function
Function TestParantInUbound(index As Long)
Static Lambda As stdLambda
If Lambda Is Nothing Then Set Lambda = stdLambda.CreateMultiline(Array( _
"let x = $1", _
"let i = 0", _
"For i = 0 to (10+2) Step +2", _
" let x = x / 2", _
"next" _
))
TestParantInUbound = Lambda.Run(index)
End Function
Function TestExprInUbound(index As Long)
Static Lambda As stdLambda
If Lambda Is Nothing Then Set Lambda = stdLambda.CreateMultiline(Array( _
"let x = $1", _
"let i = 0", _
"For i = 0 to 10+2 Step +2", _
" let x = x / 2", _
"next" _
))
TestExprInUbound = Lambda.Run(index)
End Function
Function TestForLoopPredeclared(index As Long)
Static Lambda As stdLambda
If Lambda Is Nothing Then Set Lambda = stdLambda.CreateMultiline(Array( _
"let i = 0", _
"let x = 0", _
"for i = 1 To $1", _
" let x = 2 + i", _
"next"))
TestForLoopPredeclared = Lambda.Run(index)
End Function
Function TestFunctionInForLoop(index As Long)
Static Lambda As stdLambda
If Lambda Is Nothing Then Set Lambda = stdLambda.CreateMultiline(Array( _
"let x = 0", _
"fun fib(v)", _
" if v<=1 then", _
" v", _
" else ", _
" fib(v-2) + fib(v-1)", _
" end", _
"end", _
" ", _
"for i = 1 To 10", _
" let x = x + fib($1)", _
"next"))
TestFunctionInForLoop = Lambda.Run(index)
End Function
' This will not work, as x is not defined previously
' meaning the moment lambda tries to do let x = x + duuble($1) it will view the second x as "x", since it wasnt initialised before
Function TestFunctionInForLoop2(index As Long)
Static Lambda As stdLambda
If Lambda Is Nothing Then Set Lambda = stdLambda.CreateMultiline(Array( _
"fun duuble(v)", _
" let v * 2", _
"end", _
" ", _
"For i = 1 To $1", _
" let x = x + duuble($1)", _
"next"))
TestFunctionInForLoop2 = Lambda.Run(index)
End Function
Function TestFunctionInDoLoop(index As Long)
Static Lambda As stdLambda
If Lambda Is Nothing Then Set Lambda = stdLambda.CreateMultiline(Array( _
"let x = 1", _
"let i = 0", _
"fun duuble(v)", _
" let v * 2", _
"end", _
" ", _
"Do While i < $1", _
" let i = i + 1", _
" let x = x + duuble($1)", _
"loop"))
TestFunctionInDoLoop = Lambda.Run(index)
End Function
Function TestFunctionInDoLoopWithWhileAtEnd(index As Long)
Static Lambda As stdLambda
If Lambda Is Nothing Then Set Lambda = stdLambda.CreateMultiline(Array( _
"let x = 1", _
"let i = 0", _
"fun duuble(v)", _
" let v * 2", _
"end", _
" ", _
"Do", _
" let i = i + 1", _
" let x = x + duuble($1)", _
"loop While i < $1"))
TestFunctionInDoLoopWithWhileAtEnd = Lambda.Run(index)
End Function
' This will not work at the moment, as i dont know thow to find the index to jump to depending on where it is at the moment
Function TestFunctionInDoLoopExit(index As Long)
Static Lambda As stdLambda
If Lambda Is Nothing Then Set Lambda = stdLambda.CreateMultiline(Array( _
"let x = 1", _
"let i = 0", _
"Do", _
" let i = i + 1", _
"if $1 > 10 then Exit do end", _
" let x = x * 2", _
"loop While i < $1"))
TestFunctionInDoLoopExit = Lambda.Run(index)
End Function
Thanks for the extensive tests, I'm not ignoring this PR, will look at it hopefully this next week. Just have a lot going on at the moment! ๐
No need to apologise either! There is only one way to learn and that's by doing ๐
Hi @Almesi I will try to get to this PR soon, recently there were pretty large scale changes to the stdLambda VM which have boosted speed significantly, and it's re-reminded me of how the VM works. So while it's fresh I think looking at this PR makes a lot of sense! But I will have to make some changes to your PR as the VM upgrade was pretty major๐