Rapid-Q Documentation by William Yu (c)1999-2000 | Глава 3 |
В этой главе рассматриваются основные особенности языка Rapid-Q Basic. Поскольку Rapid-Q относится к семейству Basic,
то наиболее опытные Basic программисты могут при желании пропустить это раздел. Хотя есть несколько новых понятий, которых не было в Basic, таких как неограниченное число параметров, передаваемых в функцию и использование оператора '-' для строк.
Директивы используются в
Rapid-Q для того, чтобы сообщить
компилятору какой тип кода и каким образом создавать. Rapid-Q
поддерживает следующие директивы, которые обычно должны быть включены в
начале исходного текста программы.
$APPTYPE
[ CGI | CONSOLE | GUI ] по умолчанию GUI
$APPTYPE используется для того, чтобы сообщить
компилятору какого типа приложение должно быть создано.
Хотя по умолчанию используется
GUI, Rapid-Q будет определять тип приложения
просматривая исходный код.
Для принудительной установки типа приложения используйте эту директиву в начале
программы.
$TYPECHECK
[ OFF | ON ] по умолчанию OFF
$TYPECHECK используется, если необходимо осуществлять
проверку типов переменных при компиляции.
Пример: $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)
Пример:
Пример: $DEFINE INT16 SHORT
Использование:
$OPTION BYTECODE
$OPTION ICON "path\file.ico"
$OPTION WEAKTYPE ON
Пример: $ESCAPECHARS ON
$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
$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
Использовать с осторжностью.
$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
Сделано дя совместимости с
VB.
$OPTION GTK
Будьте
уверены, что у вас есть необходимые файлы
$OPTION INKEY$ DEFAULT
$OPTION INKEY$ TRAPALL
точно так же как и Caps/Num/Scroll lock.
$OPTION VBDLL ON
$OPTION VBDLL OFF
Если
По умолчанию - OFF (выключено)
$OPTION WEAKTYPE OFF
WeakType позволяет более быстро
парсить и может помочь при переносе VB кода.
Не используете это, если не
уверены, что код правильный.
$OPTIMIZE
[ OFF | ON ] по умолчанию
выключено( OFF)
$OPTIMIZE используется для уменьшения размера байт
кода, путем удаления неиспользуемых инструкций. Должна стоять в самом начале
программы.
Usage: $OPTIMIZE ON
$ESCAPECHARS
[ OFF | ON ] По умолчанию
выключено (OFF)
Если $ESCAPECHARS
включено ( ON), вы можете
использовать escape-последовательности в свашем
коде.
Escape-последовательности
могут быть как числовые, так и
символьные. Они чувствительны к регистру!
Escape последовательности.
Подробно.
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. Ограниченная проверка выполняется только для
QObject. Вы не можете присвоить
QObjects числовое или строковое значение.
Вот некоторые примеры правильного присвоения:
A% = "Hello" "World" A$ = "Hi World!" A# = 34 + 34 - 324 * 3 / (34 / 5 + 5)Если вы никогда не программировали на языке 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 Number AS INTEGER DIM S AS STRING DIM B AS BYTEЕсли вы включите опцию $TYPECHECK ON, то потребуется обязательно объявлять тип переменной перед ее использованием.
3.3 Объекты и компоненты Rapid-Q (Rapid-Q Components/Objects)
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
Здесь используются два метода, 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)
Имеется несколько особенностей связанных с подпрограммами и функциями в 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 )
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 Глава |