Problem with switch selection

Started by Roland Stowasser, August 31, 2024, 10:47:47 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Roland Stowasser

Hi Charles,

in demos/Basics/Switch.o2bas the results do not match the expected values:
Expected:    'RESULTS:   0:A  1:A  2:A  3:C  4:B
Actually:      'RESULTS:   0:C  1:C  2:A  3:C  4:B

0 and 1 go to the else branch. Is there a solution? I know I can do it with an if .. else workaround.

Charles Pegge

Hi Roland,

I've reworked this example to get clearer results which are as expected:
Do you agree with these results?



  '==============
  'C STYLE SWITCH
  '==============

  uses console

  int i
  for i=0 to 4
  print "i=" i tab
  switch i

    case 0
    case 1
    case 2
      print "case 2 "
      break
    case 4
      print "case 4 "
      break
    case else
    print "case else "

  end switch
  print cr
  next

  wait

/*
RESULTS:
========
with 'break's
i=0      case else
i=1      case else
i=2      case 2
i=3      case else
i=4      case 4

without 'break's
i=0     case else
i=1     case else
i=2     case 2 case else
i=3     case else
i=4     case 4 case else
*/

Roland Stowasser

Hi Charles,

I suppose if switch should behave like C with fall through then the original results of  switch.o2bas (A,A,A,C,B) are correct.

Unfortunately my knowledge of C is very bad, but I have tried to code similar like the original switch.o2bas

switch.c:

#include <stdio.h>
int main()
{
    int i = 0;
    for(i = 0; i < 5; i++)
    {
        switch(i)
        {
            case 0:
            case 1:
            case 2:
               printf("%s\n", "A");
               break;
            case 4:
               printf("%s\n", "B");
               break;   
            default:
               printf("%s\n", "C");
            break;
        }

    }
    return 0;
}

If I coded this correctly, then the result compiled with Tcc would indeed be: A,A,A,C,B. But maybe switch is intended as an alternative to select case?

Charles Pegge

#3
select is simply switch with automatic breaks for each case. So OxygenBasic 'switch' should be compatible with C usage:

I made this example closer to C:
  '==============
  'C STYLE SWITCH
  '==============

  uses console

  int i
  for ( i=0; i<=4 ; i++ ) {
  print "i=" i tab
  switch i {

    case 0
    case 1
    case 2
      print "case 2 "
      break
    case 4
      print "case 4 "
      break
    default
    print "default "

  }'end switch
  print cr
  } 'next

  wait

/*
RESULTS:
========
with 'break's
i=0      default
i=1      default
i=2      case 2
i=3      default
i=4      case 4

without 'break's
i=0     default
i=1     default
i=2     case 2 default
i=3     default
i=4     case 4 default
*/




Roland Stowasser

Thanks Charles, for the info. I was not sure because of the comment at the end of the original Switch.o2bas. But you made the results clear in your previous posts.

Charles Pegge

#5
Yes, I see my original 'expected' results were not correct but the actual results were correct.


There is an example (one of yours Roland?) demonstrating the usefulness of switch

demos\WinGUI\DialogFindReplace.o2bas


In this instance, switch bit is specified so that multiple flag bits can be processed in one block.

  $ filename "t.exe"
  'uses RTL32
  uses MinWin
  uses DialogFindReplace

  #lookahead ' for procedures

  '=========
  'MAIN CODE
  '=========
 
  dim cmdline as asciiz ptr, inst as sys
  &cmdline=GetCommandLine
  inst=GetModuleHandle 0
  '
  'WINDOWS
  '-------
  '
  WinMain inst,0,cmdline,SW_NORMAL
  end

  '

  dim as sys hDlgFr

  '--------------------------------------------------------------------
  Function WinMain(sys inst, prevInst, asciiz*cmdline, sys show) as sys
  '====================================================================


  WndClass wc
  MSG      wm

  sys hwnd, wwd, wht, wtx, wty, tax

  wc.style = CS_HREDRAW or CS_VREDRAW
  wc.lpfnWndProc = @WndProc
  wc.cbClsExtra =0
  wc.cbWndExtra =0   
  wc.hInstance =inst
  wc.hIcon=LoadIcon 0, IDI_APPLICATION
  wc.hCursor=LoadCursor 0,IDC_ARROW
  wc.hbrBackground = GetStockObject WHITE_BRUSH
  wc.lpszMenuName =null
  wc.lpszClassName = strptr "Demo"

  RegisterClass @wc
 
  Wwd = 320 : Wht = 200
  Tax = GetSystemMetrics SM_CXSCREEN
  Wtx = (Tax - Wwd) /2
  Tax = GetSystemMetrics SM_CYSCREEN
  Wty = (Tax - Wht) /2
 
  hwnd = CreateWindowEx 0,wc.lpszClassName,"OXYGEN BASIC",WS_OVERLAPPEDWINDOW,Wtx,Wty,Wwd,Wht,0,0,inst,0
  ShowWindow hwnd,SW_SHOW
  UpdateWindow hwnd
  '
  sys bRet
  '
  '
  while bRet := GetMessage @wm, 0, 0, 0
    if bRet = -1
      'show an error message
      exit do
    elseif not IsDialogMessage hDlgFr,@wm
      TranslateMessage @wm
      DispatchMessage @wm
    end if
  wend

  End Function



  dim as rect crect 'for WndProc and TimerProc

  '------------------------------------------------------------------
  function WndProc ( sys hWnd, wMsg, wParam, lparam ) as sys callback
  '==================================================================

    static sys         hdc
    static String      txt="Find and Replace Test", frs=""
    static PaintStruct Paintst
    static sys         DlgFrMsg, flags
    static char        f[100],r[100]
 
    '==========
    select wMsg
    '==========
       
      '--------------
      case WM_CREATE
      '=============

      GetClientRect  hWnd,&cRect
      DlgFrMsg=RegisterWindowMessage FINDMSGSTRINGA
      hDlgFr=FindReplaceDialog(f,r,96,hwnd,flags)

      '-------------- 
      case WM_DESTROY
      '===============
         
      PostQuitMessage 0
       
      '------------
      case WM_PAINT
      '============


      'TEXT
      'http://msdn.microsoft.com/en-us/library/dd144821(v=VS.85).aspx

      'DRAWING AND PAINTING
      'http://msdn.microsoft.com/en-us/library/dd162760(v=VS.85).aspx

      GetClientRect  hWnd,&cRect
      hDC=BeginPaint hWnd,&Paintst
      'style
      '0x20 DT_SINGLELINE
      '0x04 DT_VCENTER
      '0x01 DT_CENTER
      '0x25

       SetBkColor   hdc,yellow
       SetTextColor hdc,red
       DrawText hDC,strptr txt,-1,&cRect,0x25
       EndPaint hWnd,&Paintst
       
      '--------------   
      case WM_KEYDOWN
      '==============

      '============           
      Select wParam
      '============

Case 27 : SendMessage hwnd, WM_CLOSE, 0, 0            'ESCAPE
        Case 82 : hDlgFr=FindReplaceDialog(f,r,96,hwnd,flags) 'R

      End Select
     

      '------------   
      case DlgFrMsg
      '============

      FINDREPLACE* fr
      @fr=lparam
      frs=fr.lpstrFindWhat

      switch bit fr.flags
      '
      case FR_DIALOGTERM
        hDlgFr = 0
        fr.lpstrFindWhat=""
        fr.lpstrReplaceWith=""
        fr.flags=0
        frs="Press R for Find/Replace Dialog"
      case FR_MATCHCASE
         frs+=" MATCHCASE"
      case FR_WHOLEWORD
         frs+=" WHOLEWORD"
      case FR_FINDNEXT
         frs+=" FINDNEXT"
      case FR_REPLACE
         frs+=" REPLACE"
      case FR_REPLACEALL
         frs+=" REPLACEALL"
      end select
      '
      txt=frs
      InvalidateRect hWnd, @crect

      '--------       
      case else
      '========
         
        function=DefWindowProc hWnd,wMsg,wParam,lParam
       
    end select

  end function ' WndProc