Basic реализация
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: '' не используется только потому, что в этом примере последний CASE не обусловлен
endlabel:
end scope
- SELECT CASE
- открывает неявную внешнюю область видимости
- объявляет временную переменную
- когда внутри процедуры STATIC, временная
переменная будет STATIC
- FB_SYMBATTRIB_TEMP удален из временной переменной, потому что он живет
дольше, чем всего один оператор
- выдает назначение
- объявляет о завершении метки
- каждый CASE
- если была предыдущая CASE
- закрывает предыдущую область видимости CASE
- издает переход в конец метки
- издает метку для этого CASE
- Выдает условный переход, который переходит к следующему CASE, если условие
CASE не соблюдается
- Открывает область видимости CASE
- CASE ELSE не выделяет условный переход
- Как только CASE ELSE был использован, никакие дальнейшие блоки CASE не
допускаются
- END SELECT
- закрывает предыдущую область видимости CASE
- выпускает дополнительную метку CASE в конце (Нет никакого CASE больше, но
это позволяет последнему CASE переходить до конца, если это - условный CASE.
Последний CASE мог перейти к метке конца SELECT вместо этого, но это потребует
некоторого кода обработки особого случая.)
- выдает конечную метку
- Любой EXIT SELECT прыгает сразу до конечной метки
SELECT CASE на 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 ) '' удаляет временную переменную в конце области видимости
end scope
fb_StrDelete( s )
- SELECT CASE на string/zstring/fixstr выражениях использует
строковую временную переменную
- вероятно, потому что это просто
- зная длину строки потенциально ускоряются следующие сравнения
- динамическое распределение памяти может быть слишком медленным вниз
- строковая временная переменная уничтожается в конце области видимости
или при преждевременном выходе из нее (например, достигая END SELECT,
или EXIT FUNCTION в блоке CASE)
SELECT CASE на 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 ) '' удаляет временную переменную в конце области видимости
end scope
- подобно SELECT CASE на zstrings, для wstring выражений wstring
динамично выделяется
- временный wstring рассматривается во многом так же , как динамический
объект wstring
- это VAR символ с типом WCHAR PTR
- отмечается с FB_SYMBSTATS_WSTRING
- это позволяет проверкам ctor/dtor распознавать его и правильно обрабатывать
- таким образом, временный wstring разрушается в конце области видимости
или преждевременном выходе из нее
SELECT CASE без временной переменной
Это тогда , когда переменная будет вместо более сложного
выражения, SELECT CASE не будет использовать временную переменную, но вместо
этого отложит символ из данного выражения и доступ, в случае сравнения
выражений.???