Rapid-Q Documentation by William Yu (c)1999-2000 Глава 3


3. Rapid-Q  Руководство (Language Guide)

В этой главе рассматриваются  основные особенности языка Rapid-Q  Basic.  Поскольку Rapid-Q относится к семейству Basic,

то наиболее опытные Basic программисты могут при желании пропустить это раздел. Хотя есть несколько новых понятий, которых не было в Basic, таких как неограниченное число параметров, передаваемых в функцию и использование оператора '-' для строк.


   3.1 Директивы Rapid-Q ( Rapid-Q Directives )


Директивы используются в
Rapid-Q для того, чтобы сообщить компилятору какой тип кода и каким образом создавать. Rapid-Q поддерживает следующие директивы, которые обычно должны быть включены  в начале  исходного текста программы.

   $APPTYPE

    [ CGI | CONSOLE | GUI ]     по умолчанию GUI
    $APPTYPE
 используется для того, чтобы сообщить компилятору какого типа  приложение должно быть создано.
Хотя по умолчанию используется GUI, Rapid-Q будет определять тип приложения просматривая исходный код.
Для принудительной установки типа приложения используйте эту директиву в начале программы.

    Пример:   $APPTYPE CONSOLE

   $TYPECHECK

   [ OFF | ON ]     по умолчанию OFF
   $TYPECHECK используется, если необходимо осуществлять проверку типов переменных при компиляции.

ON -
все переменные должны быть объявлены перед их применением
OFF
- обычное правило для Basic, когда переменные можно не объявлять.
Устанавливать проверку типов в On или в Off можно в любой момент, вы можете проверять только часть кода, а затем проверку отключить.

Пример: $TYPECHECK ON

   $INCLUDE

[ FileName ]

    Использование  $INCLUDE  дает тот же эффект, как и вставка тектса вызываемого файла в ту позицию, где находится эта директива.
$INCLUDE  может использоваться в любом месте вашей программы, за исключением SUB или FUNCTION. Обычно $INCLUDE  включают в начате текста программы. Если имя файла заключено в кавычки " FileName", то файл ищется в текущей директории, и в указанных путях для include файлов. Если имя файла заключено в угловые скобки, то файл будет искаться в текущей директории, в указанных путях для include файлов, а также  в путях, указанных в окружении. (в строке Path в файле autoexec)

    Пример:
    $INCLUDE "RAPIDQ.INC"
    $INCLUDE <RAPIDQ.INC>


    $RESOURCE

    Handle AS FileName
Большинство Windows языков программирования поддерживают файлы ресурсов.  В Rapid-Q эта поддержка имеет свои особенности. Файлы ресурсов - это просто коллекция графических файлов. Не поддерживаются такие вещи, как строки ресурсов. С другой стороны, что здорово в Rapid-Q, так это то, что они встраиваются в ваше приложение.Если вы используете10 различных битмапов, вам не надо включать всех из в zip файл дистрибутива вашей программы, потому что они уже встроены в exe файл.
Если имя файла заключено в кавычки " FileName", то файл ищется в текущей директории, и в указанных путях для include файлов. Если имя файла заключено в угловые скобки, то файл будет искаться в текущей директории, в указанных путях для include файлов, а также  в путях, указанных в окружении. (в строке Path в файле autoexec)

Пример:
    $RESOURCE RES_BMP1 AS "CLOUDS.BMP"
    $RESOURCE RES_BMP1 AS <CLOUDS.BMP>


    $DEFINE

    NewDefinition   [OldDefinition]

Если вы хотите создать новые или переопределить существующие ключевые слова - используйте эту директиву.
Нельзя создать последовательность лексем которые будут переопределены (You cannot construct a series of tokens to be redefined.).
Нельзя переопределить операторы или знаки пунктуации. $DEFINE нельзя использовать для определения функции (как в С)
Параметр OldDefinition используется опционально, вы можете записать $DEFINE NEWDEF

    Пример: $DEFINE INT16 SHORT

    $UNDEF

    DefName [, DefName]
   
Для отмены директивы $DEFINE используте директиву $UNDEF.   Можно использовать несколько образцов, разделенных запятыми, в одной строке
    Пример: $UNDEF INT16, INT32

    $IFDEF

    Definition
   
Эта директива определяет, что некоторая часть кода будет или не будет скомпилирована. Он используется совместно с директивой $DEFINE. Если определение было сделано, то код внутри блока  $IFDEF...($ELSE)...$ENDIF будет скомпилирован, в противном случае - нет.

    Использование:
    $IFDEF INT16
    ' если INT16 было определено -  компилировать эту порцию текста
    $ELSE
    ' иначе, если INT16 не было определено - компилировать эту порцию
    $ENDIF

    $IFNDEF

    Definition
    $IFNDEF  имеет противоположный эффект по отношению к  $IFDEF.

    Пример:
    $IFNDEF INT16
    '
если INT16 не было определено - компилировать эту порцию
    $ELSE
    '
иначе,если INT16 было определено -  компилировать эту порцию текста
    $ENDIF

$OPTION

    OptionName [Parameters]
BYREF, BYTECODE, DECIMAL, DIM, EXPLICIT, GTK, ICON, INKEY$, и WEAKTYPE  являются допустимыми именами. ( OptionNames)
    Пример:
    $OPTION BYREF
    Изменяет способ передачи параметров, принятый по умолчанию
 По умолчанию Rapid-Q  передает переменные по значению.(byVal)
Использовать с осторжностью.

    $OPTION BYTECODE
    Компилирует только в байт код.

    $OPTION DECIMAL ","
    $OPTION DECIMAL 64
    Изменяет знак десятичной точки по умолчанию. По умолчанию таким знаком является точка

    $OPTION DIM BYTE
    $OPTION DIM WORD
    $OPTION DIM DWORD
    $OPTION DIM SHORT
    $OPTION DIM INTEGER
    $OPTION DIM LONG
    $OPTION DIM SINGLE
    $OPTION DIM DOUBLE
    $OPTION DIM STRING
    $OPTION DIM VARIANT
    Изменяет тип по умолчанию для необъявленных переменных.
    По умолчанию все необъявленные переменные имеют тип DOUBLE,
    если не сопровождаются суффиксом.

    $OPTION EXPLICIT
    То же самое, что  TYPECHECK ON
    Сделано дя совместимости с VB.

    $OPTION GTK
   
Использовать GTK взамен
XFORMS
       Будьте уверены, что у вас есть необходимые файлы

    $OPTION ICON "path\file.ico"
    Изменяет иконку по умолчанию для вашего исполняемого фалйа.

    $OPTION INKEY$ DEFAULT
    $OPTION INKEY$ TRAPALL
   
Позволяет
INKEY$ перехватывать или пропускать некоторые расширенные символы.

    TRAPALL будет перехватывать  Shift/Ctrl/Alt/Menu
    точно так же как и Caps/Num/Scroll lock.

    $OPTION VBDLL ON
    $OPTION VBDLL OFF
   
Определяет, каким образом будут обрабатываться (
are handled) DLL.
    Если
VBDLL ON (включено) -  ваши объявления DLL будут подражать VB, так что ваш код может использоваться одинаково в обоих языках.
    По умолчанию -
OFF (выключено)

    $OPTION WEAKTYPE ON
    $OPTION WEAKTYPE OFF
    WeakType по умолчанию выключено (OFF)
    WeakType позволяет более быстро парсить и может помочь при переносе VB кода.
    Не используете это, если не уверены, что код правильный.


    $OPTIMIZE

    [ OFF | ON ]    по умолчанию выключено( OFF)
    $OPTIMIZE  используется для уменьшения размера байт кода, путем удаления неиспользуемых инструкций. Должна стоять в самом начале программы.
    Usage: $OPTIMIZE ON

    $ESCAPECHARS

    [ OFF | ON ]    По умолчанию выключено (OFF)
    Если $ESCAPECHARS включено ( ON), вы можете использовать  escape-последовательности в свашем коде.

Escape-последовательности могут  быть как числовые, так и символьные.  Они чувствительны к регистру!

     Пример: $ESCAPECHARS ON
    Escape последовательности.
    Подробно.

 

  \a        Alarm bell
  \b        Backspace
  \f        Form feed
\n New line
\r Carriage return
\t Horizontal Tab
\v Vertical Tab
\\ Backslash
\" Double quote
\### ### is any number 0..255
\xHH HH is a hexidecimal value 00..FF
 

     Пример:
    PRINT "\""
    Напечатает "

    PRINT "\x41"
    Напечатает A

    PRINT "\t\65\66\67\t\68\69\70
    Напечатает ABC       DEF

    PRINT "Hey\r\n";
    напечатает Hey с новой строки.

    $MACRO   (Макрос)
---------------------------------------------------------------------------------------------------------


Внимание!

Макросы нормально работающие в короткой программе, могут вызывать ошибку при компиляции большой программы.
При этом создается файл с расширением .
pp (preprocessed) который уже будет компилироваться нормально.
То есть для компиляции нужно сделать некий батничек.

--------------------------------------------------------------------------------------------------------

    MacroName[(Parameters, ...)] MacroDefinition
Макрос
просто заменяет одну последовательность символов другой. Он может обрабатываться подобно функции, если вы снабдите его параметрами. Rapid-Q допускает вложенные макросы (только в прямом порядке во избежание рекурсии), вставку лексем, используя ##, и даже перезагрузку макросов. Вы также можете переопределять операторы и спецсимволы, за исключением кавычек. Определение макроса может занимать несколько строк при использовании двоеточия как разделителя строк.  Директива  $MACRO является глобальной, если она предшествует  директивам $INCLUDE, т.е. включаемые файлы имеют доступ к этому макросу.   $MACRO является локальным (на уровне включаемого файла) если он  входит в это файл. So if A depends on B and B has some $MACRO directives, then those $MACRO directives only affect B and A has no access to them unless redeclared in module A.
    Примечание:
   
Если вы включаете $MACRO директиву, вы заставляете Rapid-Q дополнительно обрабатывать (to preprocess) ваш код, что несколько удлиняет процесс компиляции. Обычно Rapid-Q осуществляет однопроходную компиляцию.
   Пример:
    $MACRO ~ ,
   
    Переопределяет символ запятой
    попробуйте:  ? STRING$(10 ~ "A")

    $MACRO strcat(a,b) a=a+b
    Реализует функцию STRCAT
    strcat(a$,"abc") преобразуется  в a$=a$+"abc"

Примечание: Параметры должны быть односимвольными.
strcat(a1,b) a1=a1+b не будет работать.

    $MACRO VARID(x) V##x пример вставки токенов (лексема, знак)
    DEFINT VARID(1)  преобразуется в  DEFINT V1

    $MACRO TWO_PI (2*PI)
    $MACRO PI 3.14159
    Встроенный  Macros (только в прямом направлении).
    Не может включать самого себя как параметр.
    Это предотвращает бесконечную рекусию

    $MACRO ADD(a,b,c,d) ADD(a,b)+ADD(c,d)
    $MACRO ADD(x,y) x+y
    $MACRO ADD(x,y,z) x+y+z
    Пример перегрузки макроса.



    3.2  Переменные и присвоения значений (Variables and Assignments)

  Переменные хранятся в основной памяти и находятся там все время, пока программа выполняется.
В Rapid-Q проверка типов весьма нестрога. Это означает, что вы можете присвоить строковое значение переменной типа integer.
 Результат будет неопределен, но в большинстве случаев будет присвоен 0.
Если присвоить число строковой переменной, то результатом будет пустая строка. Проверка типов выполняется на уровне интерпретатора, но чтобы окна предупреждения не всплывали постоянно, проверка полностью отключена.
(Type checking is really done at the interpreter level in Rapid-Q, but since you don't want error messages popping up everywhere, I have disabled the check entirely.)
Это означает, что вы должны быть очень внимательны при присвоении значений переменным, т.к вы не будете получать никаких предупреждений от
Rapid-Q. Ограниченная проверка выполняется только для   QObject. Вы не можете присвоить  QObjects числовое или строковое значение.
Вот некоторые примеры правильного присвоения:
         A% = "Hello"  "World"

         A$ = "Hi World!"

         A# = 34 + 34 - 324 * 3 / (34 / 5 + 5)

Если вы никогда не программировали на  языке Basic, вы возможно не знаете, что означают все эти символы после А.

Поскольку большинство реализация зыка
Basic не заставляют вас определять тип  переменных перед использованием, вы можете определять тип, используя эти символы.
         ?, ??, ???, %, &, !, #, $

    Они представляют  BYTE (?), WORD (??), DWORD (???), SHORT (%), LONG (&) or INTEGER, SINGLE (!), DOUBLE (#), and STRING ($), соответственно. если вы не поставит никакого символа , переменной в Rapid-Q автоматически будет присвоен тип DOUBLE.  В других языках это может быть другой тип. для удобства приведена таблица типов переменных, применяемых в Rapid-Q.

Type ID Size Range
Byte ? 1 0..255
Word ?? 2 0..65535
Dword ??? 4 only Linux version for now..
Short % 2 -32768..32767
Integer & 4 -2147483648..2147483647
Long  & 4 -2147483648..2147483647
Single ! 4 1.5 x 1045..3.4 x 1038
Double # 5 5.0 x 10324..1.7 x 10308

Если вам не нравится такой способ , вы можете использовать DIM для объявления переменных
            DIM Number AS INTEGER
            DIM S AS STRING
            DIM B AS BYTE
Если вы включите опцию $TYPECHECK ON, то потребуется обязательно объявлять тип переменной перед ее использованием.
Это хороший стиль, но избегайте при этом подобного кода:

            DIM Num$ AS INTEGER

    3.3  Объекты и компоненты Rapid-Q  (Rapid-Q Components/Objects)


Компоненты пользовательского интерфейса Rapid-Q  являются некоторой оболочкой (wrapper code) Windows API компонентов (или под Linux - другой используемой   GUI API ) , и позволяют использовать  все возможности API  более простым образом.
Например, чтобы создать окно приложения, используя чистый
Windows API, необходимо написать около страницы кода.
В
Rapid-Q весь  этод код включен в компонент, называемый QFORM. Вместо того, чтобы регистрировать класс окна, отрисовывать его и обрабатывать все обратные вызовы (handle all the callbacks),  в Rapid-Q вы можете просто написать:
             DIM Form AS QFORM
             Form.ShowModal

По сравнению с C/C++ программами это более просто и легче для понимания. Имеется большой набор компонентов в Rapid-Q, таких как
QBUTTON, QIMAGE, QFILESTREAM, etc. некоторые компоненты не поддерживаются, или поддерживаются ограниченно. Компоненты могут создаваться точно так же, как и переменные, используя оператор DIM. Каждый компонент имеет  свойства (properties), методы (methods)  и события ( events).  Например Left, Top, (лево, верх) Width (ширина) , и Height (высота) являются свойствами всех видимых ( visible) компонентов, которые определяют из местоположение на окне родительской формы. Они имеют тип Integer.  Другое свойство- Caption  (заголовок), имеет строковый тип.  Для  компонента QFORM  это свойство определяет заголовок (title) формы, для  QBUTTON
 (кнопка)  - определяет текст на кнопке. Для таких компонентов, как QFILESTREAM свойства Caption не существует (так же как и Left, Top и т.п., так как QFILESTREAM  не является видимым компонентом. Этот компонент имеет собственные свойства.
Полное руководство по свойствам, методам и событиям всех компонентов, представлено в разделе 
Appendix.
Вот небольшой пример, как присваивать значения свойствам компонентов.


                 DIM Form AS QFORM
                 Form.Caption = "My Application"
                 Form.Left = 100
                 Form.Top = 100

Будьте внимательны, некоторые свойства предназначены только для чтения (Read-Only), а другие только для записи (Write-Only).
Пример Read-Only свойства -это  ITEMCOUNT компонента QLISTBOX.. Пример Write-Only  свойства - это ICON  компонента QFORMкоторый применяется для указания местоположения иконки, используемой по умолчанию. Чтение Read-Only
свойства или запись
Write-Only свойства дает  неопределенный результат, что может привести к ошибке при компиляции или к краху программы.

    3.4   Методы и события компонента (Component Methods & Events)

Методы - это те действия, которые можно производить с объектом. В действительности, это просто процедуры и функции, которые привязаны к данному объекту.
Вот пример метода:
              DIM Form AS QFORM
              Form.Center
              Form.ShowModal


   Здесь используются два метода, Center, и  ShowModal. Метод Center это подпрограмма ( SUBROUTINE)  без параметров. Она заставляет расположиться форму по центру экрана. ShowModal  это на самом деле функция  (FUNCTION), но мы игнорируем возвращаемую величину в нашем случае. Этот метод используется чтобы показать форму на экране и ждать действий пользователя.
Примечание: В отличие от некотоых других реализаций
Basic функция может быть вызвана, как процедура (SUBROUTINE ) в Rapid-Q,
вы можете просто игнорировать возвращаемое значение. Это напоминает С\С++.
Другие методы могут требовать некоторых дополнительных параметров, а некоторые - неограниченного числа параметров. Вы можете также создавать собственные методы для компонентов, но эти  возможности мы рассмотрим позже.
Таким образом методы - это функции, которые выполняют специфические для данного компонента задачи.

Теперь рассмотрим события (
events).  Было бы не просто описывать этот предмет в терминах передачи сообщений Windows и обратных реакций (callbacks), но к счастью мы можем  рассматривать этот вопрос на более высоком  уровне. Когда что-нибудь происходит с течением времени, например пользователь нажимает на кнопку мыши или клавишу и т.п. Rapid-Q может реагировать на эти события и выполнять какие-нибудь действия в ответ. Например вызвать процедуру или функцию - ответную  функцию ( CALLBACK function).
Для каждого события вы можете написать подпрограмму, которая будет являться реакцией на это событие.

       SUB ButtonClicked
          PRINT "Button was clicked"
       END SUB

       DIM Button AS QBUTTON
       DIM Form AS QFORM

       Button.Parent = Form                 ' Свойство (Property)
       Button.OnClick = ButtonClicked       ' Событие (Event)
       Form.ShowModal                       ' Метод (Method)

Просто, не так ли? Когда происходит событие "OnClick" программа переходит на выполнение процедуры ButtonClicked.
Это законченный пример, вы можете откомпилировать его и запустить.

    3.5 Rapid-Q Подпрограммы и функции  ( Subroutines & Functions )

Имеется несколько особенностей связанных с подпрограммами и функциями в Rapid-Q. Во-первых , и самое важное то, что все параметры передаются по значению (исключения  для  типов objects, variants, udts, и arrays ).  Чтобы передать параметр по ссылке, вы должны перед ним вставить символ @. Второе - то, что можно передать только 10 параметров (25 для вызова API функций).  Нет никакой разницы - создаете вы SUB или FUNCTION (по сравнению с остальными Basic языками, вроде Qbasic/Power Basic)

    FUNCTION FindMax (X AS INTEGER, Y AS INTEGER) AS INTEGER
      IF X > Y THEN
        FindMax = X      '' Return value is X
      ELSE
        FindMax = Y      '' Return value is Y
      END IF
    END FUNCTION
Этот код также верен, как и следующий.
    FUNCTION FindMax (X%, Y%) AS INTEGER
      IF X% > Y% THEN
        FindMax = X%      '' Return value is X
      ELSE
        FindMax = Y%      '' Return value is Y
      END IF
    END FUNCTION
Однако,  вы не можете использовать просто FindMax% без добавления AS INTEGER  в конце.

Для передаче параметра по ссылке, добавьте @ перед переменной:

    SUB StrCat (Source AS STRING, Text AS STRING)
        Source = Source + Text
    END SUB

    A$ = "Hello"
    StrCat(@A$, " World!")
    PRINT A$                '-- Должно напечатать: Hello World!
Или можно вставить ключевое слово BYREF в строку с параметрами:
    SUB StrCat (BYREF Source AS STRING, Text AS STRING)
        Source = Source + Text
    END SUB

    A$ = "Hello"
    StrCat(A$, " World!")
    PRINT A$                '-- Должно напечатать: Hello World!
Есть и другой подход (устаревший и поддержваемый по причине совместимости)
    SUB Strcat (A$, B$)
       A$ = A$ + B$
    END SUB

    A$ = "Hello"
    Strcat(A$, " world!")
    A$ = STACK.STR(0)
    PRINT A$
Stack содержит массив числовых или строковых переменных. Для доступа к  нужному параметру укажите его номер (отсчет идет слева направо), начиная с 0.  Вы можете также передавать параметры типа QObject, но они не могут быть возвращаемой величиной.
    SUB (Button AS QButton)
        Button.Left = 100
    END SUB
Все компоненты/QObject передаются по ссылке.

    3.6  Область видимости переменных ( Rules of Scope )

Переменные могут быть определены как в основной программе (глобальные переменные) , так и внутри процедуры или функции (локальные переменные). Если при этом имена переменных совпадают, то компилятор должен следовать каким-то правилам, чтобы определить с какой переменной он имеет дело, с локальной или глобальной.

Rapid-Q не похож на другой  BASIC в этом случае. Поскольку  Rapid-Q  это простой однопроходный (сверху вниз) компилятор, то он больше похож на Pascal
   Что это значит:
       SUB Test
          DIM I AS INTEGER
          I = 100
          PRINT I
       END SUB

       DIM I AS INTEGER
       I = 10

       SUB Test2
         PRINT I
       END SUB

       Test    '' Call Subroutine Результат 100
       Test2	'' Результат 10
Для SUB Test ЛОКАЛЬНАЯ переменная I существует только  в блоке  этой процедуры Test до END SUB. Переменная I в main program существует до конца этой программы. Это означает, что SUB Test2 может использовать глобальную переменную I, потому что она находится в области видимости этой переменной. Вы однако можете переопределить переменную  I в SUB Test2, в этом случае локальная переменная I будет использоваться вместо глобальной переменной I 

Возможна другая ситуация с видимостью имен переменных.

       DIM I AS INTEGER

       SUB Scope (I AS INTEGER)
         DIM I AS INTEGER
         PRINT I
       END SUB

       PRINT I
Фактически строка  DIM I AS INTEGER бесполезна, так как переменная I перекрывается  параметром I. Rapid-Q выдаст предупреждающее сообщение, но не прервет компиляцию.


Prev Глава Up Содержание Next Глава