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