PDA

View Full Version : Conditional Branching



fgasoi
13-01-2010, 18:40
How (if at all) does thinBasic support conditional branching (e.g. as a result of an IF/THEN/ELSE process)? I can find no references to branches or labels in the help files or in the forum.

ErosOlmi
13-01-2010, 19:11
Ciao fgasoi and welcome to thinBasic community forum.

I'm sorry but I cannot completely understand your request.
thinBasic supports a lot of kind of conditional branching but I'm not sure I 100% understand what you mean by "conditional branching".

Anyhow here some examples of my "conditional branching" understanding:
IF/THEN/ELSE/ELSEIF/END IF (http://www.thinbasic.com/public/products/thinBasic/help/html/index.html?if.htm)
SELECT CASE/END SELECT (http://www.thinbasic.com/public/products/thinBasic/help/html/index.html?select.htm)

Than there are simple single statements IIF$() and IIF()

But please, confirm me if this is what you was asking.

Thanks
Eros

fgasoi
13-01-2010, 23:46
Eros - thanks for the reply but this is not quite what I meant. In the IF/THEN/ELSE structure, what I am looking for is a "goto" function invoked as a result of the conditional test. In other words, IF a = x, THEN goto :label1 ELSE goto :label2 ENDIF. Is there anything like this, and if not, how could this be circumvented?

F. Gasoi



Ciao fgasoi and welcome to thinBasic community forum.

I'm sorry but I cannot completely understand your request.
thinBasic supports a lot of kind of conditional branching but I'm not sure I 100% understand what you mean by "conditional branching".

Anyhow here some examples of my "conditional branching" understanding:
IF/THEN/ELSE/ELSEIF/END IF (http://www.thinbasic.com/public/products/thinBasic/help/html/index.html?if.htm)
SELECT CASE/END SELECT (http://www.thinbasic.com/public/products/thinBasic/help/html/index.html?select.htm)

Than there are simple single statements IIF$() and IIF()

But please, confirm me if this is what you was asking.

Thanks
Eros

ErosOlmi
14-01-2010, 00:02
Ok, sorry now I got it.

No, thinBasic has no GOTO or GOSUB by design in order to avoid the so called "spaghetti code" typical of many BASICs. We wanted a clean source code structured language. In any case consider thinBasic is always evolving.

How to circumvent it depends on the situations. There can be many ways to avoid using GOTO.
If you can give here some GOTO examples I can try to show how to solve them, for example using SELECT CASE/CASE/END SELECT (http://www.thinbasic.com/public/products/thinBasic/help/html/select.htm) that is a very clean and easy to read/write construct.

Ciao
Eros

Michael Clease
14-01-2010, 11:30
It is Possible to GOSUB by using the CALL keyword



If mytest = %TRUE THEN CALL mysubroutine

SUB mySubroutine()

MsgBox 0, "Test"

END SUB


or Better still you can pass data.



If mytest = %TRUE THEN CALL mysubroutine("Test")

Sub Makebox(Message As String)

MsgBox 0, Message

End Sub



you can also use alias to rename CALL to GOSUB

ALIAS CALL GOSUB

Mike

fgasoi
16-01-2010, 18:13
Thing is, you must return from a CALL. I am looking for a mechanism which permits execution of one of multiple threads as a result of a logical test. I guess this does not exist - what you have to do is make each thread a sub which then returns to the point from which you started, which then executes a STOP. No easy way to skip over a code segment as a result of a logical test?

Petr Schreiber
16-01-2010, 19:05
If you prefer writing longer noodles of code,

then I would simply recommend to stick to advice Eros gave you and use IF/END IF, and nest it as you wish.

Example #1


' -- "Branching"

Uses "Console"

' -- The following is starting point of TB program
Function TBMain()
Dim reply As String
Dim factHungry, factHasFridge, factHasFood As Long

Console_PrintLine("*** Expert system for hungry programmer ***")
factHungry = GetInput("Are you hungry (y/n)?")

If factHungry = %TRUE Then
factHasFridge = GetInput("Do you have fridge (y/n)?")

If factHasFridge = %TRUE Then
factHasFood = GetInput("Do you have food there (y/n)?")

If factHasFood = %TRUE Then
PostSolution("Eat food from fridge")
Else
PostSolution("Go out and buy some food")
End If
Else
PostSolution("Go out and buy some food, only in amount you can eat immediately")
End If

Else
PostSolution("Ok, then this ... expert system ... is not for you!")
End If

PostSolution("Program has no advice for you...weird, should not happen :)")

End Function

Function GetInput(sText As String) As Long
Local sReply As String
Console_Print sText
sReply = Trim$(LCase$(Console_ReadLine), Any $CRLF)

While ((sReply <> "y") And (sReply <> "n"))
Print "Answer y or n please...: "
sReply = LCase$(Console_ReadLine)
Wend

Function = IIf(sReply = "y", %TRUE, %FALSE)
End Function

Sub PostSolution(sText As String)
PrintL "Solution: "+sText
PrintL "Press any key to quit..."
WaitKey
Stop
End Sub


It is also not true that after returning from CALL program stops. Only if there is nothing else to do.

Maybe a better advice could be given to you if you could tell us what problem do you want to code.

Example #2

No easy way to skip over a code segment as a result of a logical test?
I think this is exactly what IF/END IF was created for.

Another example, you can directly manipulate some variables to see how it branches:


Uses "Console"

Function TBMain()
' -- Change the following conditions and execute
Dim SomeCondition1 As Long = %TRUE
Dim SomeCondition2 As Long = %TRUE
Dim SomeCondition3 As Long = %TRUE
Dim myValueToBaseBranchingUpon As Long = 1


' -- SIMPLE IF/END IF
If SomeCondition1 = %TRUE Then
PrintL "SomeCondition1 was true, so I execute this part..."
PrintL
' -- Feel free to add code here
End If

If SomeCondition2 = %TRUE Then
PrintL "SomeCondition2 was true, so I execute this part..."
PrintL
' -- Feel free to add code here
End If

If SomeCondition3 = %TRUE Then
PrintL "SomeCondition3 was true, so I execute this part..."
PrintL
' -- Feel free to add code here
End If

' -- SIMPLE SELECT CASE
Select Case myValueToBaseBranchingUpon
Case 1
PrintL "I am in section #1"

Case 2
PrintL "I am in section #2"

Case 3
PrintL "I am in section #3"

Case Else
PrintL "Not sure what to do... but the value of variable I based decision on was: "
PrintL SelectExpression

End Select

PrintL
PrintL "Press any key to continue..."
WaitKey

End Function


Example #3
Emulating GOTO


<... code here ...>

if something = true then GOTO labelA

<... code here ...>

labelA:
<... code here ...>


simply becomes:


<... code here ...>

if not(something = true) then
<... code here ...>
end if

<... code here ...>


Emulating GOSUB


if something = true then Gosub ProcA
if somethingelse = true then Gosub ProcB

ProcA:
<... code here ...>
return

ProcB:
<... code here ...>
return


becomes:


if something = true then ProcA()
if somethingelse = true then ProcB()

sub ProcA()
<... code here ...>
end sub

sub ProcB()
<... code here ...>
end sub



Petr

P.S. If you come from 80's BASICs background, maybe you could read article in ThinBASIC Journal, #1 (http://community.thinbasic.com/index.php?topic=1865.msg13758#msg13758), called "Legacy BASIC code and ThinBasic"

Michael Hartlef
16-01-2010, 19:38
I think it is worth mentioning that a GOTO in thinBAsic can't be implemented because of the way the interpreter is working. At least how I understand it after reading Eros statemanets about how the parsing works.
ThinBasic is interpreting the code at runtime, so a label that is defined further up in a script will be unknown at the calling point. Only labels that were defined before a GOTO could be called.

ErosOlmi
16-01-2010, 20:30
I think it is worth mentioning that a GOTO in thinBAsic can't be implemented because of the way the interpreter is working. At least how I understand it after reading Eros statemanets about how the parsing works.
ThinBasic is interpreting the code at runtime, so a label that is defined further up in a script will be unknown at the calling point. Only labels that were defined before a GOTO could be called.


Michael,

the problem is not that because thinBasic always make a first script passing parsing in order to resolve all needed dependencies. In fact you can call any function before defining it because thinBasic already knows it is a function.

The fact thinBasic does not allow GOTO is by choice: I do not like it, that's the point.
I have battled many years in my young programming career reading old code developed by others full of GOTO and I can assure it is a nightmare, an absolute nightmare trying to maintain such a code especially when programmers have abused of GOTOs. So I promised to myself I would have avoided any GOTO in my programming life. That's all.

I will not talk about GOSUB because it is just a construction of poor languages that usually do not have functions or subs or callbacks.
GOSUB can easily be substituted by functions allowing also to avoid (as much as possible) global variables.

Ciao
Eros

Michael Hartlef
16-01-2010, 21:12
Sorry,

I should not talk when I just have half knowledge. :oops: