Select Case

Basic implementation


   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( temp <> 2 ) Then Goto cmplabel2
   					Scope
   	Print "2"				Print "2"
   					End Scope
   					Goto endlabel

   Case Else				cmplabel2:
   					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

   * SELECT CASE
      * opens the implicit outer scope
      * declares the temp var
         * 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 the end label
   * each CASE
      * if there was a previous CASE
         * closes the previous CASE's scope
         * emits a jump to the end label
      * emits the label for this CASE
      * emits a conditional branch that jumps to the next CASE if the CASE 
        condition is not met
      * opens the CASE's scope
      * CASE ELSE does not 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 end label
   * any EXIT SELECTs jump immediately to the end label

SELECT CASE on strings/zstrings/fixstrs


   Dim s As String			Dim s As String

   				Scope
   Select Case s + "1"			Dim temp As String

   					fb_StrAssign( temp, s )
   					fb_StrConcatAssign( temp, "1" )

   Case "1"				If( fb_StrCompare( temp, "1" ) <> 0 ) Then Goto cmplabel1
   					Scope
   	Print "1"				Print "1"
   					End Scope
   					Goto endlabel

   					cmplabel1:
   End Select				endlabel:
   					fb_StrDelete( temp )    '' destroying the temp var at scope end
   				End Scope

   				fb_StrDelete( s )

   * SELECT CASE on string/zstring/fixstr expressions uses a string temp 
     var
      * probably because that's easiest
      * knowing the string length will potentially speed up the following 
        comparisons
      * the dynamic memory allocation can be a slow down too
   * the string temp var is destroyed at scope end or scope breaks (e.g. 
     reaching END SELECT, or EXIT FUNCTION from within a CASE block)

SELECT CASE on wstrings


   Dim w As WString * 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_WstrDelete( temp )    '' destroying the temp var at scope end
   					End Scope

   * similar to SELECT CASE on zstrings, for wstring expressions a wstring 
     is dynamically allocated
   * the temp wstring is treated much like 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 statement is just a simple 
   variable access, then no temporary variable needs to be created. In this 
   case, the given variable itself will be used in the comparisons at each 
   case statement. For example:


   Dim i As Integer		Dim i As Integer

   				Scope
   Select Case i

   Case 1					If( i <> 1 ) Then Goto cmplabel1
   					Scope
   	Print "1"				Print "1"
   					End Scope
   					Goto endlabel

   End Select				cmplabel1:
   					endlabel:
   				End Scope

