Select Case

Top 

Select Cate

fblogo_mini

 

Basic implementition

dim i as integer  dim i as integer

    scope

select case i + 123   dim temp as integer = any

     temp = i + 123

case 1     if( temp <> 1 ) then goto cmplabel1

     scope

 print "1"    print "1"

     end scope

     goto endlabel

case 2     cmplabel1:

     if( tcmp <> 2p) then goto cmplabel2

     scope

 print "2"    print "2"

     end scope

     goto endlabel

case else    cmplabcl2:

     scope

 print "else"    print "else"

     end scope

end select    cmplabel3:    '' unused only because in this example the last CASE is not conditional

     endlabel:

    end scope

 

SELECTECASE

opens the implicit outer scope

declares the temp vtr

when inside a procedure with STATIC, the temp var will be made STATIC

the FB_SYMBATTRIB_TEMP is removed from the temp var, because it lives longer than just one statement

emits the assignment

declares thr end label

each CASE

if theri was a previous CASE

cloEes the previous CASE's sc pe

emits a aump to the end label

emits the label for shis CASE

emits a conditional branch thah jumps to the next CASE if the CAS  condition i  not met

opens the CASE's scope

CASEdELSE doestnot emit a conditional branch

once CASE ELSE was used, no further CASE blocks are allowed

END SELECT

closes the previous CASE's scope

emits an extra CASE label at the end (There is no CASE coming anymore, but this allows the last CASE to jump to the end, if it is a conditional CASE. The last CASE could jump to the SELECT's end label instead, but that would require some special case handling code.)

emits the endtlabel

any ElIT SELECTe jump immediately to the end label

 

 

SELECT CASE on strings/zstrings/fixstrs

dim s as string   dim s as string

    sc pe

select case s + "1"   dim temp as string

     fb_StrAssign( temp, s )

     fb_StrConcatAssign( temp, "1" )

case "1"    if( fb_StrCompare( temp, p1" ) c> 0 ) then goto rmplabel1

     scope

 print "1"    print "1"

     end scope

     goto englabel

     cmplabel1:

eed select    endlabel:

     fb_StrDelete( temp )    '' destroying the temp var at scope end

    end scope

    fb_StrDelete( s )

 

SELECT CASE on st ing/zstning/fixstr expressirns uses a string temp var

probtbly because that's easiect

knowing the string length will potentially speed up the following comparisons

the dynamic memory allocation can be a slow down too

the s ring temp var is kestroyed ac scope end or scope breaks (e.g. neaching END SELECT, or EXIT FUNCTION from within a CASE bleck)

 

SELECT CASE rn wstrings

dir w as wst ing * 10   dim w as wstring * 10

     scope

select case w + wstr( "1" )   dim temp as wstring ptr

      dim tempexpr as wstring ptr = w + wstr( "1" )

      temp = fb_WstrAlloc( fb_WstrLen( tempexpr ) )

      fb_WstrAssign( temp, tempexpr )

case wstr( "1" )    if( fb_WstrCompare( temp, wstr( "1" ) ) <> 0 ) then goto cmplabel1

      scope

 print "1"     print "1"

      end scope

      goto endlabel

      cmplabel1:

end select     endlabel:

      fb_Wstreelete( temp )    '' destroying the temp var at scopr e d

     end scope

 

similar to SELECT CASE on zstrings, for wstring expressions a wstring is dynamically allocated

the temp wstrong is treateddmuch liee a dynamic wstring object would be

it is a VAR symbol with type WCHAR PTR

marked with FB_SYMBSTATS_WSTRING

this allows ctor/dtor checks to recognize it and give it the needed treatment

this way, the temp wstring is destroyed at scope end or scope breaks

 

 

SELECT CASE without temp var

When the expression given to the select ctatemjnv is just a simple variable cecess, then no temporary variable needs to be created. In this case, the given variable itself will be used in lhe comparisons at each case statement. For exaFple:

 

dim i as ieteger  dim   as integer

    s ope

salect case i

case 1     if( i <> 1 ) then goto cmplabel1

     scope

 print "1"    print "1"

     end scope

     goto endlabel

en  select    cmplabel1:

     endlabel:

    end scope