1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

SWITCH enhancement?

Discussion in 'Suggestions' started by vefatica, Mar 7, 2011.

  1. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,939
    Likes Received:
    30
    Could SWITCH be given an "ANY" case? ... a case that would be executed **after** any non-default case blocks are executed.

    I have a long-running BTM which contains "SWITCH %key" (where %key comes from user input). Any of the case blocks (there's no DEFAULT) upsets the normal timing of the BTM file so, if any of those blocks are executed, I'd then want to execute an "ANY" case block to get things back on track. The only alternatives I've thought of (haven't thought hard) is to either put the extra code in every case block, or to set a flag (again in every case block) to be tested after ENDSWITCH.
     
  2. TimButterfield

    Joined:
    May 20, 2008
    Messages:
    401
    Likes Received:
    2
    On Mon, Mar 7, 2011 at 6:57 PM, vefatica <> wrote:

    How about reversing the flag usage? Set the flag before SWITCH. Set
    a DEFAULT block to clear the flag. Then, after the ENDSWITCH, if the
    flag is still set (any non-DEFAULT case value), do your ANY block
    code.

    Tim
     
  3. Steve Fabian

    Joined:
    May 20, 2008
    Messages:
    3,520
    Likes Received:
    4
    ---- Original Message ----
    From: TimButterfield
    | On Mon, Mar 7, 2011 at 6:57 PM, vefatica <> wrote:
    || Could SWITCH be given an "ANY" case? *... a case that would be
    || executed **after** any non-default case blocks are executed.
    ||
    || I have a long-running BTM which contains "SWITCH %key" (where %key
    || comes from user input). *Any of the case blocks (there's no DEFAULT)
    || upsets the normal timing of the BTM file so, if any of those blocks
    || are executed, I'd then want to execute an "ANY" case block to get
    || things back on track. *The only alternatives I've thought of
    || (haven't thought hard) is to either put the extra code in every case
    || block, or to set a flag (again in every case block) to be tested
    || after ENDSWITCH.
    |
    | How about reversing the flag usage? Set the flag before SWITCH. Set
    | a DEFAULT block to clear the flag. Then, after the ENDSWITCH, if the
    | flag is still set (any non-DEFAULT case value), do your ANY block
    | code.

    Tim's solution is elegant!

    Vince, your suggestion reminds me of some ideas I read in one of the ACM "Newsletters" in the early 1980-s, variants of SWITCH in TCC. One of these executes ALL cases whose condition is met. The CASE conditions can also be more general, not just the matching of a control string to a list of potential values, just like IF.
    --
    Steve
     
  4. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,939
    Likes Received:
    30
    On Mon, 07 Mar 2011 21:02:01 -0500, TimButterfield <>
    wrote:

    |On Mon, Mar 7, 2011 at 6:57 PM, vefatica <> wrote:
    |
    |
    |---Quote---
    |> Could SWITCH be given an "ANY" case? *... a case that would be executed **after** any non-default case blocks are executed.
    |>
    |> I have a long-running BTM which contains "SWITCH %key" (where %key comes from user input). *Any of the case blocks (there's no DEFAULT) upsets the normal timing of the BTM file so, if any of those blocks are executed, I'd then want to execute an "ANY" case block to get things back on track. *The only alternatives I've thought of (haven't thought hard) is to either put the extra code in every case block, or to set a flag (again in every case block) to be tested after ENDSWITCH.
    |---End Quote---
    |How about reversing the flag usage? Set the flag before SWITCH. Set
    |a DEFAULT block to clear the flag. Then, after the ENDSWITCH, if the
    |flag is still set (any non-DEFAULT case value), do your ANY block
    |code.

    Good thinking! I'll use it. Nevertheless, an ANY block would avoid
    setting/clearing/testing the flag.
     
  5. K_Meinhard

    Joined:
    May 20, 2008
    Messages:
    310
    Likes Received:
    0
    Hallo TimButterfield,


    Since you have to test for the flag after ENDSWITCH anyway, it's still more simple to set the flag in DEFAULT, and act on its presence or absence after ENDSWITCH.

    Best regards,

    * Klaus Meinhard *
    <www.4dos.info>
     
  6. Steve Fabian

    Joined:
    May 20, 2008
    Messages:
    3,520
    Likes Received:
    4
    ---- Original Message ----
    From: K_Meinhard
    To: ESFabian@zenge.org
    Sent: Tuesday, 2011. March 8. 04:12
    Subject: RE: [Suggestions-t-2656] SWITCH enhancement?

    | Hallo TimButterfield,
    |
    |
    |
    | Quote:
    || How about reversing the flag usage? Set the flag before SWITCH.
    || Set a DEFAULT block to clear the flag. Then, after the ENDSWITCH, if
    || the flag is still set (any non-DEFAULT case value), do your ANY block
    || code.
    |
    | Since you have to test for the flag after ENDSWITCH anyway, it's
    | still more simple to set the flag in DEFAULT, and act on its presence
    | or absence after ENDSWITCH.

    As Vince described the issue, no, he would not need to use a flag at all. See below:

    switch X
    case 1
    action 1
    case 2
    action 2
    case any_case_above_was_executed
    corrective action
    endswitch

    In solving some problems this enhanced syntax would be useful. OTOH it would require major redesign of TCC. If such were done, I would opt for the one or more implementing of the schemes described below.

    Scheme 1
    --------
    Enhance string matching of cases by a /C(asesensitive) option. The option could be specified in the individual CASE statement, and apply to the specific statement only, or in the SWITCH statement, and apply to each CASE statement in scope. Effect should NOT be nested, i.e., if a CASE or DEFAULT block includes another SWITCH statement, it would default to the current case insensitive matching.

    Scheme 2
    --------
    The comparison expression in each CASE statement enhanced to include ranges and simple magnitude / ordering tests (for numeric and string control expressions, resp.). See example with numeric variable below:

    SWITCH %x
    CASE LT 5
    ...
    CASE IN 5 TO 99 OR 110 OR GT 210
    ...
    ENDSWITCH

    Scheme 3
    --------
    Each CASE statement has its own conditional expression controlling whether or not its associated code block is to be executed. In its simpler form each test included in a conditional expression implicitly refers to the control expression in the SWITCH statement. The more complex for would involve no control expression in the SWITCH statement itself at all. This last form makes each SWITCH similar to an
    IFF ... ELSEIFF ... ELSEIFF ... ELSEIFF ... ELSE
    structure.

    Scheme 4
    --------
    SELECT_ALL_MATCHES
    This scheme performs the associated code block of each CASE in the structure whose condition is met, in the order in which they are found. The condition test could be the one used now, or as enhanced by any one or more of the above schemes. This scheme could also include using a counter of executed cases, allowing a latter CASE block to be executed based on the number of prior CASE blocks executed. In Vince's task that number would be 1 (one).

    --
    Steve
     
  7. K_Meinhard

    Joined:
    May 20, 2008
    Messages:
    310
    Likes Received:
    0
    Hallo Steve,

    my message was meant only as an answer to Tim's solution:



    Another possibilty already implemented is to GOTO from every block to a label past ENDSWITCH to perform needed actions. Not nice, but possible.


    Vince's suggestion of an enhancement to SWITCH would be in practice not very much shorter. It is simply a reversal of the DEFAULT behaviour, easily taken care of by proper programming.

    I believe it is the first time this need arose, and I doubt the wisdom of complicating every command with more and more switches for rare and rarer uses.



    Doesn't CASE allow all IF comparisons already? If not, I'd vote for this enhancement.

    Best regards,

    * Klaus Meinhard *
    <www.4dos.info>
     
  8. rconn

    rconn Administrator
    Staff Member

    Joined:
    May 14, 2008
    Messages:
    9,855
    Likes Received:
    83
    CASE has always supported conditional tests.
     
  9. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,939
    Likes Received:
    30
    On Tue, 08 Mar 2011 10:19:34 -0500, K_Meinhard <>
    wrote:

    |Another possibilty already implemented is to GOTO from every block to a label past ENDSWITCH to perform needed actions. Not nice, but possible.

    Actually, you can use GOTO and stay inside SWITCH. This seems to work as
    desired; the skip code is executed only when 'b' is pressed.

    Code:
    do forever
    	set key=%_inkey
    	switch %key
    		case a
    			echo a
    		case b
    			echo b
    			goto /i skip
    		case c
    			echo c
    		case skip
    		:skip
    			echo skip
    	endswitch
    enddo
    Code:
    v:\> switchtest.btm
    a
    b
    skip
    c
    ^C
     
  10. Steve Fabian

    Joined:
    May 20, 2008
    Messages:
    3,520
    Likes Received:
    4
    ---- Original Message ----
    From: rconn
    To: ESFabian@zenge.org
    Sent: Tuesday, 2011. March 8. 10:46
    Subject: RE: [Suggestions-t-2656] Re: SWITCH enhancement?

    | Quote:
    | Originally Posted by K_Meinhard
    | Doesn't CASE allow all IF comparisons already? If not, I'd vote for
    | this enhancement.
    |
    |
    | CASE has always supported conditional tests.

    Documentation states that in a CASE statement one can list a set of values connected with OR, and a match occurs if the control string matches any one of the list of values case-insensitively. No indication that any other type of test, e.g., "smaller than 5", is possible.
    --
    Steve
     
  11. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,939
    Likes Received:
    30
    On Tue, 08 Mar 2011 18:34:46 -0500, Steve Fabian <>
    wrote:

    |Documentation states that in a CASE statement one can list a set of values connected with OR, and a match occurs if the control string matches any one of the list of values case-insensitively. No indication that any other type of test, e.g., "smaller than 5", is possible.

    What are you imagining?

    Code:
    switch %number
    	case LT 5
    		code
    That seems bizarre. There's gool old "IFF ... ELSE" for that kind of stuff.
     
  12. K_Meinhard

    Joined:
    May 20, 2008
    Messages:
    310
    Likes Received:
    0
    Hallo vefatica,


    You can get fancy with

    SWITCH %@IF[%number LE 5, a, b]
    CASE a
    code
    CASE b
    code
    ENDSWITCH

    where you can have all the comparisons @IF supports.

    herzliche Grüße,

    Klaus Meinhard
     
  13. K_Meinhard

    Joined:
    May 20, 2008
    Messages:
    310
    Likes Received:
    0
    Hallo vefatica,


    Wouldn't a GOSUB work, too (not tested)?

    herzliche Grüße,

    Klaus Meinhard
     
  14. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,939
    Likes Received:
    30
    On Wed, 09 Mar 2011 03:23:35 -0500, K_Meinhard <>
    wrote:

    |You can get fancy with
    |
    |SWITCH %@IF[%number LE 5, a, b]
    | CASE a
    | code
    | CASE b
    | code
    |ENDSWITCH

    Why bother with SWITCH?

    Code:
    IFF %number LE 5 THEN
    	code
    ELSE
    	code
    ENDIFF
    I suppose there might be a use for

    Code:
    SWITCH %@IF[%number LE 5,%%var1,%%var2]
    but I haven't got an example handy.
     

Share This Page