QB64.org Forum

Active Forums => QB64 Discussion => Topic started by: Unseen Machine on September 06, 2020, 11:29:38 am

Title: Feature request - Exit Case/Break
Post by: Unseen Machine on September 06, 2020, 11:29:38 am
Hi Folks,

I cant seem to find a command to exit a select case structure in QB64, i know in C it's break...if one does exist then please tell me what it is, if not then can a command be added?

Thanks

Unseen

Code: QB64: [Select]
  1.  
  2.   CASE 1
  3.        
  4.         '// If something happend that means  dont want to run the rest of this case then _BREAK
  5.  
Title: Re: Feature request - Exit Case/Break
Post by: FellippeHeitor on September 06, 2020, 11:31:36 am
Quick and dirty GOTO.
Title: Re: Feature request - Exit Case/Break
Post by: RhoSigma on September 06, 2020, 12:38:41 pm
How's this ?

Code: QB64: [Select]
  1.  
  2.   CASE 1
  3.  
  4.         IF NOT "something happend" THEN
  5.  
  6.             '// that means  I don't want to run this
  7.  
  8.         END IF
  9.  
  10.  

clean, readable and easy...
Title: Re: Feature request - Exit Case/Break
Post by: FellippeHeitor on September 06, 2020, 12:47:14 pm
_CONTINUE is a goto replacement for loops, I don't oppose a _BREAK be added to the language for SELECT CASE blocks, it could serve as a general alias for EXIT DO/WHILE/FOR as well. Let's see how discussion in this thread progresses.
Title: Re: Feature request - Exit Case/Break
Post by: RhoSigma on September 06, 2020, 01:06:30 pm
Sounds good Fellippe, no objections from my side either.
Title: Re: Feature request - Exit Case/Break
Post by: TempodiBasic on September 06, 2020, 02:29:34 pm
Hi Unseen

I find singular your request because I think to the great difference between SELECT CASE END SELECT of Qbasic and SWITCH of C/C++ ...
while in Qbasic multiple cases are of different data type and can be grouped in many ways
Code: QB64: [Select]
  1. DIM Scelta, Intero
  2.  
  3.     CLS
  4.     INPUT "EXIT? Please make your choice Yes/No/Don't know ", Scelta
  5.     Scelta = UCASE$(LEFT$(Scelta, 1))
  6.  
  7.     SELECT CASE Scelta
  8.         CASE "N", "D"
  9.             PRINT "You're  still here"
  10.         CASE "Y"
  11.             PRINT "You're gone"
  12.         CASE ELSE
  13.             PRINT "Error of Input"
  14.     END SELECT
  15.     SLEEP 1
  16. LOOP UNTIL Scelta = "Y"
  17.  
  18.     CLS
  19.     INPUT "EXIT? Please make your choice 1.Yes/2.No/3.Don't know ", Intero
  20.  
  21.     SELECT CASE Intero
  22.         CASE 3, 2
  23.             PRINT "You're  still here"
  24.         CASE 1
  25.             PRINT "You're gone"
  26.         CASE ELSE
  27.             PRINT "Error of Input"
  28.     END SELECT
  29.     SLEEP 1
  30. LOOP UNTIL Intero = 1
  31.  
No fallthrough rule, so why do you need of _BREAK/ EXIT SELECT?
Moreover No DEFAULT case but there is an ELSE case... so you must invert the logic of C code to translate it into Qbasic!
In C/C++ you must use
- an integer or char or enumerable variable and
- you cannot use variable for CASE values
- you cannot group many value on the same line of code
- you cannot make an evaluation on each CASE

so I am very interesting to understand in what CASE a _BREAK can be useful
I want be clear, I am not against this, but curious about its

@FellippeHeitor
WoW
Quote
_CONTINUE is a goto replacement for loops

http://qb64.org/wiki/CONTINUE (http://qb64.org/wiki/CONTINUE)
I have missed this!

Thanks to read
Title: Re: Feature request - Exit Case/Break
Post by: Unseen Machine on September 06, 2020, 04:37:54 pm
Quote
Quick and dirty GOTO.
Lol, Seriously, i never knew!!! (Hmmmmm....)(sarcasm Felippe?)
Quote
I don't oppose a _BREAK be added to the language for SELECT CASE blocks

Thats what i wanted but
Quote
it could serve as a general alias for EXIT DO/WHILE/FOR as well.
Is an even better implementation so i'd support that!
Quote
so I am very interesting to understand in what CASE a _BREAK can be useful
I want be clear, I am not against this, but curious about its
I cant remember why i wanted it but it came up when i was coding something recently so as i couldnt find a built in command i found it resonable to request it, i suppose it's just down to individual coding techniques (the way we each like to code)rather than an absolutley needed command.

Unseen
Title: Re: Feature request - Exit Case/Break
Post by: Cobalt on September 06, 2020, 05:04:14 pm
Why would you need to again? 
SELECT CASE is little more than a suped up IF\THEN.
There should be no need to 'break' out of a SELECT CASE. As it is only going to run a matching case anyway.
Title: Re: Feature request - Exit Case/Break
Post by: SMcNeill on September 06, 2020, 05:05:11 pm
Honestly, I'm not so certain I'd like to see such a command added to the language.  All a SELECT CASE is, is a series of IF.. THEN statements, which use the same base condition to check against.  Heck, when translated into the c-code, which is compiled, they're translated into IF THEN ELSE type statements.

Let's take a quick look at some QB64 code, and its translated output:

Code: QB64: [Select]
  1.     CASE "A"
  2.     CASE "B"
  3.     CASE "C"
  4.  

Code: C: [Select]
  1. if ((qbs_cleanup(qbs_tmp_base,qbs_equal(__STRING_X,qbs_new_txt_len("A",1))))||new_error){
  2. goto sc_1_end;
  3. }
  4. if ((qbs_cleanup(qbs_tmp_base,qbs_equal(__STRING_X,qbs_new_txt_len("B",1))))||new_error){
  5. goto sc_1_end;
  6. }
  7. if ((qbs_cleanup(qbs_tmp_base,qbs_equal(__STRING_X,qbs_new_txt_len("C",1))))||new_error){
  8. goto sc_1_end;
  9. }
  10. sc_1_end:;


As you can see, all those SELECT CASE statements are translated into nothing more than a series of IF statements, with a GOTO making them skip all the irrelevant sections.

Adding a _BREAK command into the code would be as simple as translating that break into another one of those GOTO statements.  (goto sc_1_end, in this case)

My issue is, if we start making commands dedicated to this type of purpose, how many other commands are we going to need to add the same functionality in other functions?

IF x = 3 then
   'do some stuff
   'if something triggers then _EXIT IF??

There's a reason why the language has GOTO in it.  Sometimes, it's simply the tool we need to make use of, without having to have customized keywords which do nothing more than replicate its functionality.



One problem I foresee, if EXIT _CASE is implemented, is how it might interact with SELECT EVERYCASE.

SELECT EVERYCASE basically translates the code the same as above, but without those GOTO statements between each IF condition.

If we have code like the following, how is it supposed to act?

Code: [Select]
SELECT EVERYCASE x$
    CASE "A"
       z = z + 1
       IF z = 3 then EXIT SELECT
       y = y + 2
    CASE "B"
    CASE "C"
END SELECT

Now, is that EXIT SELECT supposed to exit all the way to the END SELECT?  If we goto our existing label, that's where it'd jump to.

OR is it supposed to exit down to the CASE "B" statement?  If so, then all SELECT CASE statements will need to have labels added to each of them, so we can jump to the proper one.

Both options would be simple enough to implement, if folks really want to add them (personally, I don't think they're necessary), but I'd suggest if added, and if it's supposed to work as the second option (jump to the next CASE), then why not make two commands?  EXIT SELECT which jumps all the way to the end of the SELECT CASE, and an EXIT CASE, which jumps down to the next CASE statement instead.

Another thing to consider, if we're going to be jumping between CASES...  How would that work with a CASE ELSE?

Implementing any changes might not be quite as simple as it first seems, as there's a lot of little things to keep in mind and account for, with the command, to keep the program/logic flow proper.

Title: Re: Feature request - Exit Case/Break
Post by: Bert22306 on September 06, 2020, 05:15:53 pm
_CONTINUE is a goto replacement for loops, I don't oppose a _BREAK be added to the language for SELECT CASE blocks, it could serve as a general alias for EXIT DO/WHILE/FOR as well. Let's see how discussion in this thread progresses.

This kind of request begs for creating any number of unintended bugs. I'm kind of with Steve on this. Why not just EXIT (whatever)?
Title: Re: Feature request - Exit Case/Break
Post by: bplus on September 06, 2020, 07:24:51 pm
Why would you need to again? 
SELECT CASE is little more than a suped up IF\THEN.
There should be no need to 'break' out of a SELECT CASE. As it is only going to run a matching case anyway.

In case (sorry), one case is really long but there is a condition in which the long part of the case can be skipped.

To me, RhoSigma has the best workaround without having to resort to GOTO, though sometimes coding the NOT condition can be tricky.

But also I kind of like BREAK if it can also serve as an EXIT.

Ah but Steve has a point BREAK out of the Case ( in SELECT CASE that means out of SELECT also) or Break out of the whole EVERYCASE Block?  Yeah, GOTO is nice final resort :)

 
Title: Re: Feature request - Exit Case/Break
Post by: Cobalt on September 06, 2020, 08:50:43 pm
In case (sorry), one case is really long but there is a condition in which the long part of the case can be skipped.


does that not denote an IF\THEN\ELSE situation within the SELECT CASE?

Still not seeing a need to do this. maybe its just the drugs but I can't wrap my head around why this would be needed out side of poor coding technique?
Title: Re: Feature request - Exit Case/Break
Post by: FellippeHeitor on September 06, 2020, 08:51:23 pm
In any case, Unseen's request would look logical like this:
  [ This attachment cannot be displayed inline in 'Print Page' view ]  

_BREAK being a way to exit the SELECT block entirely.
Title: Re: Feature request - Exit Case/Break
Post by: FellippeHeitor on September 06, 2020, 08:55:37 pm
Also, in any case it's a glorified goto, but so are all EXIT variations and _CONTINUE.
Title: Re: Feature request - Exit Case/Break
Post by: FellippeHeitor on September 06, 2020, 09:00:39 pm
One more detail: EXIT SELECT is a thing in VB:

https://docs.microsoft.com/en-us/dotnet/visual-basic/language-reference/statements/exit-statement

We probably don't really need another keyword, just a new implementation of existing keywords.

It's probably clear I'm for it now.
Title: Re: Feature request - Exit Case/Break
Post by: Unseen Machine on September 07, 2020, 03:58:22 am
Wow, if only all my threads got such a response!

Anyway, I only asked cause I came across the need for it, admittedly it's only the once in 10 years of coding in QB64 i've had this need though so i suppose i could just use a work around.

Here's a basic view of how i came across the need for _BREAK. I had a select case with a triple For loop in it and rather than the work around of checking a variable and then exiting each for loop i needed a _BREAK.

Code: QB64: [Select]
  1.  
  2.   CASE 1
  3.     FOR k% = 0 TO 10
  4.  
  5.       FOR j% = 0 TO 10
  6.  
  7.         FOR i% = 0 TO 10
  8.  
  9.           if K% = Col% and j% = row% and i% = i& then _BREAK
  10.  
  11.         NEXT
  12.  
  13.       NEXT
  14.  
  15.     NEXT
  16.  

Obviously i could use Line labels and a GOTO (and is what i ended up doing) but thats not (as far as i am concerned) good coding practice, that maybe just a hangup i have being a OOP guy or something, i dunno.

I dont mind if the answers a NO as it's far from essential.

Unseen
Title: Re: Feature request - Exit Case/Break
Post by: Dimster on September 07, 2020, 10:17:37 am
This topic touches on a How To question for me.  If you have a Select Case within a Do Loop and you want to code one of those Cases to get you out of the Selection process and back into the Do Loop does _Continue do that? or does _Continue just skip the Case it's found in a moves onto the next Case?
Title: Re: Feature request - Exit Case/Break
Post by: FellippeHeitor on September 07, 2020, 10:23:18 am
_CONTINUE goes to the beginning the loop, regardless of whether you're inside a select case block or not.

That, of course, if the condition for looping is still true. Otherwise, the loop block is exited.
Title: Re: Feature request - Exit Case/Break
Post by: FellippeHeitor on September 07, 2020, 10:38:47 am
Steve's remarks considered, I believe we're aiming for EXIT SELECT and EXIT CASE, for when EVERYCASE is used. Does anybody have anything else to add?
Title: Re: Feature request - Exit Case/Break
Post by: Cobalt on September 07, 2020, 01:07:47 pm
I'm afraid I must disagree.

My argument is we already have a way, however despise-able it is, to jump around in a program.

This would be nothing more than an alias of GOTO.

btw what is wrong with this exactly?
Code: QB64: [Select]
  1.     SELECT CASE i&
  2.      
  3.       CASE 1
  4.         FOR k% = 0 TO 10
  5.      
  6.           FOR j% = 0 TO 10
  7.      
  8.             FOR i% = 0 TO 10
  9.      
  10.               IF K% = Col% AND j% = row% AND i% = i& THEN MatchFlag%% = -1: i% = 11: j% = 11: k% = 11
  11.      
  12.             NEXT
  13.      
  14.           NEXT
  15.      
  16.         NEXT
  17.      
  18.     END SELECT
Title: Re: Feature request - Exit Case/Break
Post by: FellippeHeitor on September 07, 2020, 01:14:29 pm
The good thing is that there's no new keyword added to the language. Just a new way to use them, which won't hurt anyone at all.

My point when I ask if anyone has anything to add at this point is anything technical regarding the implementation as it's been showcased above.
Title: Re: Feature request - Exit Case/Break
Post by: bplus on September 07, 2020, 01:19:30 pm
Yes sounds very good to me, just extending where you can apply EXIT, no new keywords.
Title: Re: Feature request - Exit Case/Break
Post by: SMcNeill on September 07, 2020, 01:51:48 pm
The good thing is that there's no new keyword added to the language. Just a new way to use them, which won't hurt anyone at all.

My point when I ask if anyone has anything to add at this point is anything technical regarding the implementation as it's been showcased above.

Only technical point is to be careful of flow into a CASE ELSE block of a SELECT EVERYCASE.  Make certain it’s working as intended.

As long as we’re implementing this, can we also get an EXIT <counter> command?

FOR I
   FOR J
       FOR K
           EXIT 2
       NEXT
   NEXT
NEXT

The above would exit 2 control blocks (K and J blocks) and flow down into the I block, after that 2nd NEXT.

Or maybe an EXIT TO label statement?  That could be useful too.


FOR I
   FOR J
       FOR K
           EXIT TO foo
       NEXT
   NEXT
foo:
NEXT
Title: Re: Feature request - Exit Case/Break
Post by: FellippeHeitor on September 07, 2020, 01:56:17 pm
Anyone willing to test the new feature, please head to the development build page and get the latest version:

https://www.qb64.org/portal/development-build/

EXIT SELECT
Can be used to exit a SELECT CASE block.

EXIT CASE
Has the same purpose of EXIT SELECT, unless when used in a SELECT EVERYCASE block. In such case, it'll skip to the next CASE evaluation.

Please try to break it. I'll be watching this thread.

PS: Anyone new to development builds, here's the changelog since v1.4 was released: https://www.qb64.org/portal/development-build-changelog/
Title: Re: Feature request - Exit Case/Break
Post by: FellippeHeitor on September 07, 2020, 01:57:16 pm
As long as we’re implementing this, can we also get an EXIT <counter> command?

I wouldn't oppose you implement it.

Quote
Or maybe an EXIT TO label statement?  That could be useful too.


FOR I
   FOR J
       FOR K
           EXIT TO foo
       NEXT
   NEXT
foo:
NEXT

But this is definitely a GOTO.
Title: Re: Feature request - Exit Case/Break
Post by: Unseen Machine on September 07, 2020, 03:16:17 pm
Quote
https://www.qb64.org/portal/development-build-changelog/

I couldnt see the _IFNOTINCLUDED function i previously requested here https://www.qb64.org/forum/index.php?topic=2733.msg119540#msg119540 (https://www.qb64.org/forum/index.php?topic=2733.msg119540#msg119540)

Did this not get implemented? Is it in the works?

Thanks for putting this together though, now i've just gotta figure out what it was i was coding when i needed it!

Unseen
Title: Re: Feature request - Exit Case/Break
Post by: FellippeHeitor on September 07, 2020, 03:22:23 pm
The trick to check if a precompiler setting is undefined was already there. You just didn't know about it. Have you started using it for your libraries?
Title: Re: Feature request - Exit Case/Break
Post by: Richard on September 08, 2020, 10:21:20 pm
Trying to "break"  exit case

Code: QB64: [Select]
  1.  
  2. a$ = CHR$(0)
  3.     CASE CHR$(0):
  4.         'EXIT SELECT
  5.         : EXIT CASE
  6.     CASE CHR$(1)
  7.         BEEP: BEEP
  8.     CASE ELSE
  9.         BEEP: BEEP: BEEP: BEEP: BEEP
  10.  
  11.  

using Dev version f3b92c3  Windows 10 x64

I thought 3 x BEEP was to be the result.


HOWEVER




Code: QB64: [Select]
  1. a$ = CHR$(0)
  2.     CASE CHR$(0):
  3.         'EXIT SELECT
  4.         : EXIT CASE
  5.     CASE CHR$(1)
  6.         BEEP: BEEP
  7.     CASE CHR$(0)
  8.         BEEP:
  9.     CASE ELSE
  10.         BEEP: BEEP: BEEP: BEEP: BEEP
  11.  
  12.  

gives 2 x BEEP which is logically correct.



Title: Re: Feature request - Exit Case/Break
Post by: SMcNeill on September 08, 2020, 10:28:54 pm
Trying to "break"  exit case

Code: QB64: [Select]
  1.  
  2. a$ = CHR$(0)
  3.     CASE CHR$(0):
  4.         'EXIT SELECT
  5.         : EXIT CASE
  6.     CASE CHR$(1)
  7.         BEEP: BEEP
  8.     CASE ELSE
  9.         BEEP: BEEP: BEEP: BEEP: BEEP
  10.  
  11.  

using Dev version f3b92c3  Windows 10 x64

I thought 3 x BEEPS was to be the result.

Shouldn’t it be a single beep?  The first case is the only one that matches, and it doesn’t beep.  The only beep that I’d think should be triggered, is the one after the END SELECT.
Title: Re: Feature request - Exit Case/Break
Post by: FellippeHeitor on September 09, 2020, 09:30:43 am
Code: QB64: [Select]
  1.  
  2. a$ = CHR$(0)
  3.     CASE CHR$(0):
  4.         'EXIT SELECT
  5.         : EXIT CASE
  6.     CASE CHR$(1)
  7.         BEEP: BEEP
  8.     CASE ELSE
  9.         BEEP: BEEP: BEEP: BEEP: BEEP
  10.  
  11.  

The above beeps once.

Code: QB64: [Select]
  1. a$ = CHR$(0)
  2.     CASE CHR$(0):
  3.         'EXIT SELECT
  4.         : EXIT CASE
  5.     CASE CHR$(1)
  6.         BEEP: BEEP
  7.     CASE CHR$(0)
  8.         BEEP:
  9.     CASE ELSE
  10.         BEEP: BEEP: BEEP: BEEP: BEEP
  11.  
  12.  

The above beeps twice.

All as expected so far.