xHarbour
xHarbour — это бесплатный многоплатформенный расширенный компилятор Clipper , предлагающий несколько графических терминалов (GT), включая драйверы консоли, графические интерфейсы и гибридные консоли/GUI. xHarbour обратно совместим с Clipper и поддерживает множество расширений синтаксиса языка, значительно расширенные библиотеки времени выполнения и обширную поддержку третьих сторон.
Как и большинство динамических языков, xHarbour также доступен как язык сценариев (автономное приложение, подключаемая библиотека, движок MS ActiveScript [Windows Script Host, HTML, ASP]), использующий интерпретатор, написанный на языке xHarbour.
xHarbour Usenet Группа новостей comp.lang.xharbour — это активное сообщество для обсуждения вопросов, связанных с xHarbour.
Встроенные типы данных
[ редактировать ]xHarbour имеет 6 скалярных типов: Nil , String , Date , Logical , Number , Pointer и 4 сложных типа: Array , Object , CodeBlock и Hash . Скаляр содержит одно значение, например строку, число или ссылку на любой другой тип. Массивы представляют собой упорядоченные списки скаляров или комплексных типов, индексированные по номеру, начиная с 1. Хэши или ассоциативные массивы представляют собой неупорядоченные коллекции значений любого типа, индексированные соответствующим ключом, который может иметь любой скалярный или комплексный тип.
Литеральное (статическое) представление скалярных типов:
- НОЛЬ: НОЛЬ
- Строка: «привет», «привет», [привет] или E «привет\n»
- Дата: ctod("2005-03-17")
- Логические: .Т., .Ф.
- Число: 1, 1.1, -1, 0xFF
Сложные типы также могут быть представлены как литеральные значения:
- Множество:
{ "String", 1, { "Nested Array" }, .T., FunctionCall(), @FunctionPointer() }
- Кодовый Блок:
{ |Arg1, ArgN| Arg1 := ArgN + OuterVar + FunctionCall() }
- Хэш:
{ "Name" => "John", 1 => "Numeric key", "Name2" => { "Nested" => "Hash" } }
Хэши могут использовать любой тип, включая другие хеши, в качестве ключа для любого элемента. Хэши и массивы могут содержать любой тип в качестве значения любого члена, включая вложенные массивы и хеши.
Кодовые блоки могут иметь ссылки на переменные процедуры/функции>метода, в котором они были определены. Такие кодовые блоки могут быть возвращены как значение или с помощью аргумента, передаваемого ПО ССЫЛКЕ . В таком случае кодовый блок «переживет» процедуру, в которой он был определен, и любые переменные, на которые он ссылается, будут DETACHED переменной.
Отсоединенные переменные сохраняют свое значение до тех пор, пока существует ссылающийся на них кодовый блок. Такие значения будут использоваться совместно с любым другим кодовым блоком, который может иметь доступ к тем же переменным. Если кодовый блок не пережил содержащую его подпрограмму и будет оцениваться в течение срока действия подпрограммы, в которой он определен, изменения в его отдельных переменных посредством его оценки будут отражены обратно в его родительской подпрограмме.
Кодовые блоки можно оценивать любое количество раз с помощью функции Eval( BlockExp ).
Переменные
[ редактировать ]Все типы могут быть присвоены именованным переменным. Идентификаторы именованных переменных имеют длину от 1 до 63 символов, начинаются с [AZ|_] и далее состоят из символов [AZ|0–9|_] длиной до 63 символов. Именованные переменные не чувствительны к регистру.
Переменные имеют одну из следующих областей:
- LOCAL : Виден только внутри процедуры, которая его объявила. Значение теряется при выходе из процедуры.
- STATIC : Виден только внутри процедуры, которая его объявила. Значение сохраняется для последующих вызовов процедуры. Если переменная STATIC объявлена до определения какой-либо процедуры/функции/метода, имеет область действия MODULE и видна в любой подпрограмме, определенной в том же исходном файле, она будет сохранять свое существование в течение всего срока службы приложения.
- GLOBAL Видна в любой подпрограмме, определенной в том же исходном модуле, где объявлена переменная GLOBAL, а также в любой подпрограмме любого другого исходного модуля, который явно объявляет ее посредством объявления GLOBAL EXTERNAL . Объявления GLOBAL и GLOBAL EXTERNAL должны быть объявлены до определения любой процедуры/функции/метода.
- PRIVATE : Виден внутри подпрограммы, которая его объявила, и всех подпрограмм, вызванных этой подпрограммой.
- PUBLIC : Виден всем подпрограммам в одном приложении.
LOCAL , STATIC и GLOBAL разрешаются во время компиляции и, таким образом, работают намного быстрее, чем переменные PRIVATE и PUBLIC , которые являются динамическими объектами, доступ к которым осуществляется посредством таблицы символов времени выполнения . По этой же причине LOCAL , STATIC и GLOBAL переменные не доступны компилятору макросов, и любой код макроса, который пытается ссылаться на них, будет генерировать ошибку во время выполнения.
Из-за динамической природы переменных PRIVATE и PUBLIC их можно создавать и уничтожать во время выполнения, к ним можно обращаться и изменять с помощью макросов времени выполнения, а также к ним можно обращаться и изменяться с помощью кодовых блоков, создаваемых на лету.
Структуры управления
[ редактировать ]Базовые структуры управления включают в себя все стандартные структуры управления dBase и Clipper , а также дополнительные, вдохновленные языками программирования C или Java :
Петли
[ редактировать ][DO] WHILE ConditionExp ... [LOOP] [EXIT] END[DO]
FOR Var := InitExp TO EndExp [STEP StepExp] ... [LOOP] [EXIT] NEXT
FOR EACH Var IN CollectionExp ... [HB_EnumIndex()] [LOOP] [EXIT] NEXT
- ... . представляет собой последовательность одного или нескольких операторов xHarbour и квадратных скобок [] обозначает необязательный синтаксис.
- HB_EnumIndex () может быть дополнительно использован для получения текущего индекса итерации (на основе 1).
- Оператор LOOP перезапускает текущую итерацию структуры охватывающего цикла, и если охватывающий цикл представляет собой цикл FOR или FOR EACH , он увеличивает итератор, переходя к следующей итерации цикла.
- Оператор EXIT немедленно прекращает выполнение структуры охватывающего цикла.
- Оператор NEXT закрывает структуру управления и переходит к следующей итерации структуры цикла.
В FOR инструкции выражение присваивания вычисляется перед первой итерацией цикла. Выражение TO оценивается и сравнивается со значением управляющей переменной перед каждой итерацией, и цикл завершается, если его значение превышает числовое значение управляющей переменной. Необязательное выражение STEP оценивается после каждой итерации перед принятием решения о выполнении следующей итерации.
В FOR EACH переменная Var будет иметь значение (скалярное или комплексное) соответствующего элемента в значении коллекции. Выражением коллекции может быть массив (любого типа или комбинации типов), хэш-таблица или тип объекта.
ЕСЛИ заявления
[ редактировать ]IF CondExp ... [ELSEIF] CondExp ... [ELSE] ... END[IF]
... представляет 0 или более утверждений .
Выражения условия должны иметь ЛОГИЧЕСКОЕ значение.
Операторы DO CASE
[ редактировать ]DO CASE CASE CondExp ... [CASE CondExp] ... [OTHERWISE] ... END[CASE ]
Вышеуказанная конструкция логически эквивалентна:
IF CondExp ... ELSEIF CondExp ... [ELSEIF CondExp] ... [ELSE] ... END[IF]
Операторы SWITCH
[ редактировать ]xHarbour поддерживает конструкцию SWITCH, основанную на реализации метода switch() на языке C.
SWITCH SwitchExp CASE LiteralExp ... [EXIT]
[CASE LiteralExp] ... [EXIT] [DEFAULT] ... END
- LiteralExp должен быть числовым выражением, разрешаемым во время компиляции, и может включать в себя операторы, если такие операторы включают статическое значение времени компиляции.
- Необязательный оператор EXIT и если он присутствует, выполнение структуры SWITCH завершится при достижении оператора EXIT, в противном случае оно продолжится с первого оператора , эквивалентен оператору Cbreak , расположенного ниже следующего оператора CASE (проваливается).
Операторы BEGIN SEQUENCE
[ редактировать ]BEGIN SEQUENCE ... [BREAK] [Break([Exp])] RECOVER [USING Var] ... END[SEQUENCE]
или:
BEGIN SEQUENCE ... [BREAK] [Break()] END[SEQUENCE]
Структура BEGIN SEQUENCE позволяет корректно прерывать любую последовательность, даже при пересечении вложенных процедур/функций. Это означает, что вызываемая процедура/функция может выдать оператор BREAK или выражение Break(), чтобы принудительно развернуть любую вложенную процедуру/функцию вплоть до первой внешней структуры BEGIN SEQUENCE либо после соответствующего оператора END. или предложение RECOVER, если оно присутствует. Оператор Break может опционально передавать выражение любого типа, которое может быть принято оператором RECOVER, чтобы обеспечить дальнейшую обработку восстановления.
xHarbour Кроме того, объект ошибок поддерживает canDefault
, canRetry
и canSubstitute
Properties, что позволяет обработчикам ошибок выполнить некоторые приготовления, а затем запросить операцию Retry , Resume или вернуть значение для замены выражения, вызывающего состояние ошибки.
Операторы TRY [CATCH] [FINALLY]
[ редактировать ]TRY ... [BREAK] [Break([Exp])] [Throw([Exp])] CATCH [Var] ... END
TRY ... [BREAK] [Break([Exp])] [Throw([Exp])] CATCH [Var] ... FINALLY ... END
или:
TRY ... [BREAK] [Break([Exp])] [Throw([Exp])] FINALLY ... END
Конструкция TRY очень похожа на конструкцию BEGIN SEQUENCE, за исключением того, что она автоматически интегрирует обработку ошибок, поэтому любая ошибка будет перехвачена и восстановлена с помощью оператора CATCH или в противном случае перенаправлена внешнему обработчику CATCH. Раздел FINALLY гарантированно будет выполнен до выполнения разделов TRY или CATCH прямого потока с помощью RETURN, BREAK или THROW.
Процедуры/функции
[ редактировать ][STATIC] PROCEDURE SomeProcedureName [STATIC] PROCEDURE SomeProcedureName() [STATIC] PROCEDURE SomeProcedureName( Param1 [, ParamsN] )
INIT PROCEDURE SomeProcedureName EXIT PROCEDURE SomeProcedureName
[STATIC] FUNCTION SomeProcedureName [STATIC] FUNCTION SomeProcedureName() [STATIC] FUNCTION SomeProcedureName( Param1 [, ParamsN] )
Процедуры/функции в xHarbour можно указать с помощью ключевых слов PROCEDURE
, или FUNCTION
. Правила именования такие же, как и для переменных (до 63 символов без учета регистра). И процедуры, и функции могут быть уточнены квалификатором области STATIC, чтобы ограничить их использование областью модуля, где он определен.
Необязательные квалификаторы INIT . или EXIT помечают процедуру, которая будет автоматически вызываться непосредственно перед вызовом процедуры запуска приложения или сразу после выхода из приложения соответственно Параметры , передаваемые в процедуру/функцию, появляются в подпрограмме как локальные переменные и могут принимать любой тип, включая ссылки.
Изменения переменных аргументов не отражаются в соответствующих переменных, передаваемых вызывающей процедурой/функцией/методом, если они не передаются явно ПО ССЫЛКЕ с использованием префикса @ .
PROCEDURE не имеет возвращаемого значения и, если используется в контексте выражения, выдаст значение NIL .
FUNCTION может возвращать любой тип с помощью оператора RETURN в любом месте тела своего определения.
Ниже приведен пример определения процедуры и вызова функции:
x := Cube( 2 )
FUNCTION Cube( n )
RETURN n ** 3
Поддержка базы данных
[ редактировать ]xHarbour расширяет подход сменных драйверов базы данных Clipper (RDD). Он предлагает несколько RDD, таких как DBF, DBFNTX, DBFCDX, DBFDBT и DBFFPT. В xHarbour в одном приложении можно использовать несколько RDD, а новые логические RDD можно определять из комбинации других RDD. Архитектура RDD допускает наследование, так что данный RDD может расширять функциональность других существующих RDD. Сторонние RDD, такие как RDDSQL, RDDSIX, RMDBFCDX, Advantage Database Server и Mediator , служат примером некоторых особенностей архитектуры RDD.
xHarbour также предлагает поддержку ODBC посредством синтаксиса ООП и поддержку ADO посредством OLE.
Макрооператор (компилятор времени выполнения)
[ редактировать ]Одной из наиболее мощных функций языков xBase является оператор MACRO «&». Реализация оператора макроса в xHarbour позволяет компилировать во время выполнения любое допустимое выражение xHarbour. Такое скомпилированное выражение может использоваться как ЗНАЧЕНИЕ, т. е. правая часть Присвоения, но такое скомпилированное выражение может использоваться для разрешения ЛЕВОЙ стороны присваивания, т. е. ЧАСТНЫХ, или ПУБЛИЧНЫХ переменных, или ПОЛЯ БД.
Кроме того, оператор макроса может компилировать и выполнять вызовы функций, выполнять назначения или даже список аргументов, а результат макроса может использоваться для разрешения любого из вышеуказанных контекстов в скомпилированном приложении. IOW, любое приложение xHarbour может быть расширено и/или изменено во время выполнения для компиляции и выполнения дополнительного кода по требованию.
Реализация этой функции в xHarbour настолько полна, что интерпретатор xHarbour, xbScript, активно использует ее для компиляции сценариев xHarbour.
Синтаксис:
&( ... )
Текстовое значение выражения '...' будет скомпилировано, а результатом будет значение, полученное в результате выполнения скомпилированного кода.
&SomeId
это короткая форма для &( SomeId ).
&SomeId.postfix
— это короткая форма &( SomeId + «постфикс»).
Пример кода
[ редактировать ]Привет, мир!
[ редактировать ]Типичная программа « Привет, мир » будет такой:
? "Hello, world!"
Или:
QOut( "Hello, world!" )
Или:
Alert( "Hello, world!" )
Или, заключенный в явную процедуру:
PROCEDURE Main()
? "Hello, world!"
RETURN
ОТКРЫТЬ
[ редактировать ] #include "hbclass.ch"
PROCEDURE Main()
LOCAl oPerson := Person( "Dave" )
oPerson:Eyes := "Invalid"
oPerson:Eyes := "Blue"
Alert( oPerson:Describe() )
RETURN
CLASS Person
DATA Name INIT ""
METHOD New() CONSTRUCTOR
ACCESS Eyes INLINE ::pvtEyes
ASSIGN Eyes( x ) INLINE IIF( ValType( x ) == 'C' .AND. x IN "Blue,Brown,Green", ::pvtEyes := x, Alert( "Invalid value" ) )
// Sample of IN-LINE Method definition
INLINE METHOD Describe()
LOCAL cDescription
IF Empty( ::Name )
cDescription := "I have no name yet."
ELSE
cDescription := "My name is: " + ::Name + ";"
ENDIF
IF ! Empty( ::Eyes )
cDescription += "my eyes' color is: " + ::Eyes
ENDIF
ENDMETHOD
PRIVATE:
DATA pvtEyes
ENDCLASS
// Sample of normal Method definition.
METHOD New( cName ) CLASS Person
::Name := cName
RETURN Self
Сценарии
[ редактировать ]xHarbour также доступен в качестве интерпретируемого языка в некоторых вариантах скриптовых движков.
- Автономный переводчик : портативный, автономный переводчик.
xBaseScript
. - ActiveScript : OLE DLL, совместимая с Microsoft ActiveScript, которая поддерживает сценарии xHarbour в:
- Хост сценариев Windows (WSH).
- Internet Explorer, сценарии на стороне клиента HTML.
- IIS и любой другой ASP-совместимый сервер.