к оглавлению

Формат исходного текста программы Clarion

Формат оператора

Язык Clarion является языком "ориентированным на операторы". Такие языки исходят из того факта, что исходный код существует в виде ASCII файлов, каждая строка программы соответствует записи файла. Поэтому вместо знаков препинания можно воспользоваться разделителями записи (символами “возврат каретки” и “перевод строки”).

В общем, формат оператора в языке Clarion следующий:

метка ОПЕРАТОР[(параметры)] [,АТРИБУТ[(параметры)]] ...

Атрибуты задают характеристики элемента и используются только в операторах объявления данных. Исполняемые операторы имеют вид стандартного обращения к процедуре, за исключением операторов присваивания (A = B) и управляющих структур (таких как IF, CASE и LOOP).

Метка оператора должна начинаться в первой колонке строки исходного текста. Оператор без метки не может начинаться с первой колонки. Оператор заканчивается символом конца строки. Не помещающийся в строку оператор может быть продолжен на другой строке с помощью вертикальной черты ( | ). Для размещения нескольких операторов на одной строке используется ; (точка с запятой).

Будучи ориентированным на операторы, язык Clarion исключает многие из символов пунктуации, обязательных в других языках для идентификации меток и разделения операторов. Блок операторов начинается обозначением составного оператора и заканчивается оператором END (или точкой).

Смотри также: Имена переменных и метки операторов, Структуры, Уточнение имени переменной, Зарезервированные слова, Специальные символы

 

Имена переменных и метки операторов

Операторы языка в исходном модуле можно разделить на две основные категории: операторы объявления данных и исполняемые операторы, или просто “данные” и “код”.

Операторы объявления данных резервируют области памяти, которыми при выполнении программы манипулируют исполняемые операторы. Указание метки обязательно для данных объявленных в программе. С помощью метки можно сослаться на любую переменную, структуру данных, процедуру и подпрограмму.

Метка указывает конкретное место в программе. Любой исполняемый оператор может идентифицироваться меткой. Это позволяет использовать в качестве точки перехода оператор GOTO. Даже если на нее нет ссылок, метка увеличивает на 10 байт размер исполняемого оператора.

Метка оператора PROCEDURE является именем процедуры. Использование метки оператора PROCEDURE в качестве исполняемого оператора вызывает выполнение этой процедуры. Метка оператора PROCEDURE используется в выражении или списке параметров другой процедуры для того, чтобы представить значение, возвращаемое процедурой.

Правила образования допустимых меток в Clarion:

 

Структуры

Когда операторы объявления данных вложены в другие операторы объявления данных, то получаются составные структуры данных. В языке Clarion существует много составных структур данных: APPLICATION, WINDOW, REPORT, FILE, RECORD, GROUP, VIEW, QUEUE и т.д. Такие составные структуры должны заканчиваться точкой (.) или оператором END. Операторы IF, CASE, EXECUTE, LOOP, BEGIN и ACCEPT представляют собой исполняемые управляющие структуры. Они также должны заканчиваться точкой или оператором END (оператор LOOP может неявно заканчиваться операторами WHILE или UNTIL).

 

Уточнение имени переменной

У переменных, объявленных внутри составных структур данных (GROUP, QUEUE, FILE, RECORD и т.д.) могут быть совпадающие имена, если только они не содержатся в одной и той же структуре. Для того чтобы точно указать поле, имеющее имя, которое совпадает с именем поля в другой структуре, и обеспечить уникальность имени, можно использовать атрибут PRE этой структуры, так как он описан в документации (Префикс:ИмяПеременной). Тем не менее, использование для этой цели атрибута PRE необязательно и его можно опустить.

К любой переменной в составной структуре данных можно обратиться, присоединяя к имени переменной спереди имя структуры через точку (ИмяСтруктуры.ИмяПременной). Такой способ уточнения имени следует использовать для любых полей в структурах, для которых не указан атрибут PRE. Для ссылок на переменные внутри любых структур, кроме структуры CLASS и поименованных переменных-указателей, вместо точки можно использовать двоеточие (:) (ИмяСтруктуры:ИмяПеременной) (это служит только для обеспечения совместимости с предыдущими версиями Clarion для Windows).

Для уточнения имени переменной, которая находится во вложенной составной структуре, следует спереди присоединить имя каждой структуры предыдущего уровня (если она имеет имя). Если же у какой-либо из вложенных структур отсутствует имя, то эта часть из уточнения имени опускается. Это похоже на анонимные структуры UNION в C++. Это означает, что в случае структуры GROUP (без атрибута PRE), в которой структура GROUP имеет имя, на отдельные поля записи нужно ссылаться таким образом: ВнешнееИмяГруппы.ВнутреннееИмяГруппы.ИмяПоля. Если внутренняя структура GROUP не имеет имени, ссылка на поля осуществляется так: ВнешнееИмяГруппы.ИмяПоля. Существует одно исключение из этого правила: метка структуры RECORD внутри FILE может быть опущена и поэтому, обращаться к полям внутри файла можно так: ИмяФайла.ИмяПоля вместо ИмяФайла.ИмяЗаписи.ИмяПоля.

Такой синтаксис уточнения имен используется также для ссылок на все элементы структур CLASS – и на элементы данных и методы. Для того чтобы обратиться к методу – элементу структуры CLASS, укажите НазваниеКласса.ИмяМетода в любом месте, где допустимо обращение к процедуре. Чтобы сослаться на элемент структуры GROUP, имеющей атрибут DIM, необходимо специфицировать номер элемента в массиве на уровне, где появляется атрибут DIM.

Пример:

MasterFile FILE,DRIVER('TopSpeed')

Record RECORD

AcctNumber LONG !Можно ссылаться как Masterfile.AcctNumber

END

END

Detail FILE,DRIVER('TopSpeed')

RECORD

AcctNumber LONG ! Можно ссылаться как Detail.AcctNumber

END

END

Memory GROUP,PRE(Mem)

Message STRING(30) ! Можно ссылаться как Mem:Message or Memory.Message

END

SaveQueue QUEUE

Field1 LONG ! Можно ссылаться как SaveQueue.Field1

Field2 STRING ! Можно ссылаться как SaveQueue.Field2

END

OuterGroup GROUP

Field1 LONG ! Можно ссылаться как OuterGroup.Field1

Field2 STRING ! Можно ссылаться как OuterGroup.Field2

InnerGroup GROUP

Field1 LONG ! Можно ссылаться как OuterGroup.InnerGroup.Field1

Field2 STRING ! Можно ссылаться как OuterGroup.InnerGroup.Field2

END

END

OuterGroup GROUP,DIM(5)

Field1 LONG ! Можно ссылаться как OuterGroup[1].Field1

InnerGroup GROUP,DIM(5) ! Можно ссылаться как OuterGroup[1].InnerGroup

Field1 LONG ! Можно ссылаться как OuterGroup[1].InnerGroup[1].Field1

END

END

Смотри также: PRE, CLASS, Переменные-указатели

 

Зарезервированные слова

Приведенные ниже ключевые слова являются зарезервированными и не могут использоваться в качестве меток ни в каких случаях:

ACCEPT AND BEGIN BREAK

BY CASE CHOOSE COMPILE

CYCLE DO ELSE ELSIF

END EXECUTE EXIT FUNCTION

GOTO IF INCLUDE LOOP

MEMBER NEW NOT NULL

OF OMIT OR OROF

PARENT PROCEDURE PROGRAM RETURN

ROUTINE SECTION SELF THEN

TIMES TO UNTIL WHILE

XOR

Ключевые слова, приведенные ниже, могут использоваться в качестве меток структур данных или исполняемых операторов, но не могут быть метками операторов PROCEDURE. Их можно использовать в качестве имен параметров в прототипе, только если также указан тип данных параметра:

APPLICATION CLASS CODE DATA

DETAIL FILE FOOTER FORM

GROUP HEADER ITEM ITEMIZE

JOIN MAP MENU MENUBAR

MODULE OLECONTROL OPTION QUEUE

RECORD REPORT ROW SHEET

TAB TABLE TOOLBAR VIEW

WINDOW

Замечание: SELF и PARENT не могут использоваться в качестве имен переменных в любом классе или методе интерфейса.

 

Специальные символы

Инициаторы:

! Восклицательным знаком начинается комментарий.

? Вопросительным знаком начинается метка соответствия полю, метка или, когда находится в первой колонке строки исходного текста, означает, что операторы, следующие за ним, выполняются только в режиме ОТЛАДКИ.

@ Знаком коммерческое “At” начинается шаблон.

* Звездочкой начинается имя параметра, передаваемого по адресу, в прототипе процедуры в структуре MAP.

~ Знак тильда впереди имени файла обозначает, что этот файл связывается в проект.

Терминаторы:

; Точка с запятой является разделителем исполняемых операторов.

CR/LF Комбинация символов “Возврат каретки”/“Перевод строки” также является разделителем исполняемых операторов.

. Точка завершает операторную структуру или структуру данных (заменитель оператора END).

| Вертикальная черта является символом продолжения оператора.

# Знак фунта в конце имени означает неявное объявление переменной типа LONG.

$ Знак доллара в конце имени означает неявное объявление переменной типа REAL.

" Двойные кавычки в конце имени означает неявное объявление переменной типа STRING.

Разделители:

( ) В круглые скобки заключается список параметров.

[ ] В квадратные скобки заключается список индексов массива.

' ' В одиночные кавычки заключается строковая константа.

{ } В фигурные скобки заключается коэффициент повторения символа в строковой константе, а также параметры свойства.

< > В угловые скобки заключается код ASCII символа в строковой константе или параметр в прототипе MAP, который может опускаться при обращении к процедуре.

: Двоеточие разделяет начало и конец “подстроки”

, Запятая разделяет параметры в списке.

Коннекторы:

. Десятичная точка в числовых константах или соединение имени составной структуры с именем одного из ее компонентов.

: Двоеточие соединяет префикс с меткой переменной.

$ Знак доллара соединяет метку структуры WINDOW или REPORT с меткой соответствия объекта в операторе присвоения значения свойству объекта.

Операции:

+ Символ плюс означает сложение.

- Символ минус означает вычитание.

* Звездочка обозначает умножение.

/ Слеш обозначает деление.

% Знак процента обозначает взятие остатка от деления.

^ Операция возведения в степень.

< Левая угловая скобка означает операцию “меньше”.

> Правая угловая скобка означает операцию “больше”.

= Знак равенства означает присвоение или равенство.

~ Тильда обозначает булеву операцию “логическое НЕ”.

& Амперсанд обозначает конкатенацию.

&= Амперсанд со знаком равенства обозначает назначение или равенство.

:=: Означает множественное присваивание.

 

 

Формат программы

PROGRAM (объявить программу)

PROGRAM

MAP

прототипы

[MODULE( )

прототипы

END ]

END

глобальные данные

CODE

операторы

[RETURN]

процедуры

PROGRAM Обязательный первый оператор в программном исходном модуле.

MAP Обязательное объявление глобальных процедур.

MODULE Объявление исходных модулей.

прототипы Объявление процедур.

Глобальные данные Объявляются глобальные данные, которые могут быть использованы всеми процедурами.

CODE Заканчивают секцию объявления данных и начинает секцию исполняемых операторов.

операторы Исполняемые операторы программы.

RETURN Завершает выполнение программы. Возвращает управление операционной системе.

процедуры Исходные коды процедур в программном модуле.

Оператор PROGRAM является первым обязательным оператором объявления в исходном модуле Clarion программы. Ему могут предшествовать только строки комментария. При компиляции имя файла, содержащего оператор PROGRAM, используется в качестве имен объектного (.OBJ) и исполняемого (.EXE) файлов. Оператор PROGRAM может иметь метку, но компилятором она игнорируется.

Программа, в состав которой входят процедуры, должна иметь структуру MAP. В ней объявляются прототипы процедур. Любая процедура, содержащаяся в отдельном исходном файле, должна быть объявлена в структуре внутри структуры MAP.

Данные, объявленные в программном модуле между ключевыми словами PROGRAM и CODE, являются глобальными статическими данными и могут быть доступны любой процедуре в программе.

Пример:

PROGRAM !Пример объявления программы

INCLUDE('EQUATES.CLW') !Включить стандартные метки соответствия

MAP

CalcTemp PROCEDURE !Прототип процедуры

END

CODE

CalcTemp !Обращение к процедуре

CalcTemp PROCEDURE

Fahrenheit REAL(0) !Объявление глобальных данных

Centigrade REAL(0)

Window WINDOW('Temperature Conversion'),CENTER,SYSTEM

STRING('Enter Fahrenheit Temperature: '),AT(34,50,101,10)

ENTRY(@N-04),AT(138,49,60,12),USE(Fahrenheit)

STRING('Centigrade Temperature:'),AT(34,71,80,10),LEFT

ENTRY(@N-04),AT(138,70,60,12),USE(Centigrade),SKIP

BUTTON('Another'),AT(34,92,32,16),USE(?Another)

BUTTON('Exit'),AT(138,92,32,16),USE(?Exit)

END

CODE !Начало раздела исполняемых операторов

OPEN(Window)

ACCEPT

CASE ACCEPTED()

OF ?Fahrenheit

Centigrade = (Fahrenheit - 32) / 1.8

DISPLAY(?Centigrade)

OF ?Another

Fahrenheit = 0

Centigrade = 0

DISPLAY

SELECT(?Fahrenheit)

OF ?Exit

BREAK

END

END

CLOSE(Window)

RETURN

Смотри также: MAP, MODULE, PROCEDURE, Объявление данных и распределение памяти

 

MEMBER (идентифицировать дополнительный исходный файл)

MEMBER( [ программа ] )

[MAP

прототипы

END ]

[метка] локальные данные

процедуры

MEMBER Первый обязательный оператор в модуле исходного текста, который не является программным исходным файлом.

программа Текстовая константа, содержащая имя файла с исходной программой (без расширения). Если этот параметр опущен, то данный модуль является "универсальным модулем" который можно компилировать в любую программу, добавив его в проект.

MAP Объявления локальных процедур. К объявленным здесь процедурам можно обращаться только из процедур данного MEMBER модуля.

прототипы Объявления процедур.

локальные данные Объявляются локальные статические данные, на которые можно ссылаться только в процедурах, чей исходный текст содержится в данном MEMBER модуле.

процедуры Исходные тексты процедур в MEMBER модуле.

MEMBER стоит первым оператором в исходом модуле, который не является программным исходным файлом. Ему могут предшествовать только строки комментариев. Он требуется в начале любого исходного файла, который содержит процедуры, используемые программой. Оператор MEMBER идентифицирует программу, к которой относится исходный модуль.

MEMBER модуль может содержать локальную структуру MAP (которая может содержать структуры MODULE). Процедуры объявленные в этом MAP доступны для использования другими процедурами MEMBER модуля. Исходный текст процедур, объявленных в этом MEMBER MAP, может содержаться в исходном MEMBER модуле или другом файле (если он объявлен в структуре MODULE внутри MAP).

Если в MEMBER операторе опущен параметр программа, вы должны иметь структуру MAP, в которой содержатся объявления процедур. Вам также нужно ВКЛЮЧАТЬ любые стандартные EQUATE файлы, которые используются в вашем исходном тексте.

Если исходный текст процедур, объявленных в MEMBER модуле структуры MAP, содержится в отдельном файле, то их прототипы должны быть объявлены в структуре MODULE внутри структуры MAP. Исходный файл MEMBER модуля, содержащий описание процедур, должен также содержать собственную структуру MAP, которая объявляет те же самые прототипы тех же процедур (то есть, прототипы должны быть, по крайней мере, в двух MAP структурах – в исходном модуле, содержащих их, и в исходном модуле, использующих их). Любая процедура, не объявленная в глобальной (программной) MAP структуре, должна быть объявлена в локальной(ых) структруре(ах) MAP MEMBER модуля, который содержит их исходный текст.

Данные, объявленные в MEMBER модуле, между ключевыми словами MEMBER и PROCEDURE, являются статическими локальными модульными данными и могут быть доступны только процедурам данного модуля (если не переданы как параметр).

Пример:

!Модуль Source1 содержит:

MEMBER('OrderSys') !модуль входит в программу OrderSys

MAP !объявление локальных процедур

Func1 PROCEDURE(STRING),STRING !Func1 известна только в этих двух модулях

MODULE('Source2.clw')

HistOrd2 PROCEDURE !HistOrd2 известна только в этих двух модулях

END

END

LocalData STRING(10) !Локальные данные по отношению к MEMBER модулю

HistOrd PROCEDURE !Объявление HistOrd процедуры

HistData STRING(10) !Объявление локальных данных к этой процедуре

CODE

LocalData = Func1(HistData)

Func1 PROCEDURE(RecField) !Объявление локальной процедуры

CODE

!Исполняемые операторы

! Модуль Source2 содержит:

MEMBER('OrderSys') !Модуль относится к программе OrderSys

MAP !Объявление локальных процедур

HistOrd2 PROCEDURE !HistOrd2 известна только в этих двух модулях

MODULE('Source1.clw')

Func1 PROCEDURE(STRING),STRING !Func1 известна только в этих двух модулях

END

END

LocalData STRING(10) !Объявление данных локальных к этому модулю MEMBER

HistOrd2 PROCEDURE !Объявление процедуры HistOrd2

CODE

LocalData = Func1(LocalData)

Смотри также: MAP, MODULE, PROCEDURE, CLASS, Объявление данных и распределение памяти

 

MAP (объявить прототипы процедур)

MAP

прототипы

[MODULE( )

прототипы

END ]

END

 

MAP Содержит прототипы, которые объявляют процедуры и внешние модули исходного текста, используемые в модулях PROGRAM, MEMBER или PROCEDURE.

прототипы Объявляет процедуры.

MODULE Объявляет member модуль исходного текста, который содержит определение прототипа в MODULE.

Структура MAP содержит прототипы, которые объявляют процедуры и внешние исходные модули, используемые в программном, MEMBER модуле или процедурах, которые не являются элементами структур CLASS.

Структура MAP, находящаяся в программном модуле, объявляет прототипы процедур доступные в любом месте программы. Структура MAP в MEMBER модуле объявляет прототипы процедур, которые доступны в пределах данного MEMBER модуля. Те же прототипы могут быть размещены в нескольких MEMBER модулях, чтобы сделать их явно доступными для каждого модуля. Структура MAP также может быть включена в объявление процедуры. Все прототипы процедур, объявленных локально в структуре MAP процедуры, будут доступны только внутри данной процедуры.

Структура MAP обязательна для любой нетривиальной Clarion программы, потому что в нее компилятор автоматически вставляет модуль исходного текста BUILTINS.CLW. Этот файл содержит прототипы большинства процедур внутренней библиотеки Clarion, которые являются частью языка Clarion. Этот файл обязателен потому, что в самом компиляторе (для повышения эффективности) нет этих прототипов. Поскольку прототипы в файле BUILTINS.CLW используют те же самые метки соответствия констант, описанные в файле EQUATES.CLW, этот файл также автоматически включается компилятором в каждую программу Clarion.

Пример:

!Один файл содержит:

PROGRAM !Пример программы в sample.cla

MAP !Начало объявлений в MAP

LoadIt PROCEDURE !Процедура LoadIt

END !Конец map

!В отдельном файле содержится:

MEMBER('Sample') !Объявление MEMBER модуля

MAP !Начало объявлений в локальной структуре MAP

ComputeIt PROCEDURE !Прототип процедуры

END !Конец MAP

ComputeIt Procedure

LOC:Var LONG

MAP !Локальный map

Proc1

END

Code

Proc1()

Return

Proc1 Procedure

Code

LOC:Var += 1

Return

Смотри также: PROGRAM, MEMBER, MODULE, PROCEDURE, Прототипы процедур

 

MODULE (указать исходный файл member-модуля)

MODULE(файл исходного текста)

прототип

END

MODULE Задает MEMBER модуль или внешнюю библиотеку.

файл исходного текста

Строковая константа, которая содержит имя файла, содержащем исходный текст на языке Clarion, в котором объявлены процедуры. Если исходный файл представляет собой внешнюю библиотеку, то эта строка может содержать любой уникальный идентификатор.

прототип Прототипы процедур, хранящихся в исходном файле.

Структура MODULE именует MEMBER модуль, написанный на языке Clarion или внешнюю библиотеку, и содержит прототипы процедур, содержащихся в файле исходного текста. Структура MODULE может объявляться только внутри структуры MAP, и доступна для использования в любой структуре MAP, вне зависимости от того, где содержится структура MAP в программном или в MEMBER модуле.

Пример:

!Файл "sample.clw" содержит:

PROGRAM !Пример программы в sample.clw

MAP !Начало объявлений в структуре map

MODULE('Loadit') !Исходный модуль loadit.clw

LoadIt PROCEDURE !Процедура LoadIt

END !Конец модуля

MODULE('Compute') !Исходный модуль compute.clw

ComputeIt PROCEDURE !Процедура ComputeIt

END !Конец модуля

END !Конец map

!Файл "loadit.clw" содержит:

MEMBER('Sample') !Объявляет модуль MEMBER

MAP !Начало структуры map

MODULE('Process') !Исходный модуль process.cla

ProcessIt PROCEDURE !Процедура ProcessIt

END !Конец модуля

END !Конец map

Смотри также: MEMBER, MAP, Прототипы процедур

 

PROCEDURE (определить процедуру)

метка PROCEDURE [ ( список параметров ) ]

локальные данные

CODE

операторы

[RETURN( [ значение ] ) ]

PROCEDURE Начинает секцию исходного текста, который может быть выполнен в программе.

метка Имя процедуры. При определении метода в структуре CLASS может содержать имя класса, присоединенное спереди к имени процедуры.

список параметров Разделенный запятыми список имен (и, необязательно, их типы данных), значения которых передаются в процедуру. Эти имена определяют локальные ссылки на передаваемые параметры. При определении метода в структуре CLASS может содержать имя класса (называемый SELF) как неявный первый параметр (если имя класса не присоединено спереди к имени процедуры), и всегда должен содержать тип данных и имя параметра.

локальные данные Объявляются локальные данные видимые только в этой процедуре.

CODE Завершает секцию объявления данных и начинает секцию исполняемых операторов в процедуре.

операторы Исполняемые операторы.

RETURN Завершает выполнение процедуры. Возврат в точку, из которой было обращение к процедуре и возвращение значение выражения, в котором процедура использовалась (если это предполагалось).

значение Числовая или строковая константа или переменная, которая специфицирует результат вызова процедуры.

PROCEDURE начинает секцию исходного текста, который может быть выполнен из любой точки в программе. К ней обращаются, просто указав метку оператора PROCEDURE (и, если необходимо, со списком параметров) в качестве исполняемого оператора в программной секции программы или процедуры.

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

Процедура может содержать одну или несколько подпрограмм среди исполняемых операторов. Подпрограмма – секция исполняемого кода локальная по отношению к процедуре, которая вызывается оператором DO.

При выполнении оператора RETURN, процедура заканчивается и возвращает управление в точку вызова. После последнего выполняемого оператора в процедуре, в конце исходного текста, при появлении первого оператора ROUTINE или PROCEDURE, происходит неявное выполнение оператора RETURN.

Если процедура должна возвращать значение, оператор RETURN обязателен. Имя такой процедуры может использоваться в выражениях или передаваться как параметр в другую процедуру. Ее также можно вызвать как процедуру, не возвращающую значение, если логика программы не требует возврата значения. В этом случае, если прототип процедуры не имеет атрибута PROC, компилятор сгенерирует предупреждение, которое можно без опасения проигнорировать.

Данные, объявленные в процедуре между ключевыми словами PROCEDURE и CODE являются локальными для процедуры и доступны только этой процедуре (за исключением передачи их в качестве параметров в другую процедуру). Эти данные располагаются в памяти в момент входа в процедуру и освобождаются по ее завершении. Если объем данных меньше порогового для стека значения (по умолчанию 5K), то они помещаются в стек. В противном случае, память выделяется из “кучи”.

Процедура должна иметь прототип, объявленный в структуре CLASS или MAP программного или MEMBER модуля. В случае указания прототипа процедуры в программной структуре MAP, обращение к ней возможно из любых других процедур данной программы. Если же процедура представлена прототипом в MEMBER модуле, то обращение к ней возможно только из процедур этого MEMBER модуля.

Пример:

PROGRAM !Пример программы

MAP

OpenFile PROCEDURE(FILE AnyFile)!Прототип процедуры с параметрами

ShoTime PROCEDURE !Прототип процедуры без параметров

DayString PROCEDURE,STRING !Прототип процедуры, которая возвращает значение

END

FileOne FILE,DRIVER('Clarion') !Объявление файла

RECORD !начало объявления структуры Record

Name STRING(20)

Number LONG

END !Конец объявления структуры Record

END !Конец объявления файла

TodayString STRING

TodayString = DayString()!Вызывается процедура с возвращением значения

OpenFile(FileOne) !Вызов процедуры открытия файла

ShoTime !Вызов процедуры ShoTime

!Исполняемые операторы

OpenFile PROCEDURE(FILE AnyFile)!Открывает некий файл

CODE !Начало секции исполняемых операторов

OPEN(AnyFile) !Открытие файла

IF ERRORCODE() = 2 !Если файл не найден

CREATE(AnyFile) !создать его

END

RETURN !Возврат в точку вызова

ShoTime PROCEDURE !Показать время

Time LONG !Локальная переменная

Window WINDOW,CENTER

STRING(@T3),USE(Time),AT(34,70)

BUTTON('Exit'),AT(138,92),USE(?Exit)

END

CODE !Начало секции исполняемых операторов

Time = CLOCK() !Получить системное время

OPEN(Window)

ACCEPT

CASE ACCEPTED()

OF ?Exit

BREAK

END

END

RETURN !Возврат в точку вызова

DayString PROCEDURE !Процедура DayString

ReturnString STRING(9),AUTO !Инициализация локальной переменной

CODE !Начало секции исполняемых операторов

EXECUTE (TODAY() % 7) + 1 !Определение дня недели по системной дате

ReturnString = 'Sunday'

ReturnString = 'Monday'

ReturnString = 'Tuesday'

ReturnString = 'Wednesday'

ReturnString = 'Thursday'

ReturnString = 'Friday'

ReturnString = 'Saturday'

END

RETURN(ReturnString) !Возврат результата

Смотри также: Прототипы процедур, Объявление данных и распределение памяти, Перегрузка процедур, CLASS, ROUTINE, MAP

 

CODE (начало исполняемых операторов)

CODE

Оператор CODE отделяет в программном модуле, процедуре или подпрограмме секцию объявления данных от секции исполняемых операторов (программной секции). За оператором CODE следует первый исполняемый оператор в программном модуле, процедуре или подпрограмме. Слово "Code" является зарезервированным словом и не может использоваться в качестве метки переменной или процедуры.

Пример:

PROGRAM

!Здесь объявляются глобальные данные

CODE

!Здесь находятся исполняемые операторы

OrdList PROCEDURE !объявление процедуры

!Здесь объявляются локальные данные

CODE !начало секции исполняемых операторов

!Здесь находятся исполняемые операторы

Смотри также: PROGRAM, PROCEDURE

 

DATA (начать локальную секцию данных подпрограммы)

DATA

Оператор DATA начинает секцию описания локальных данных в подпрограмме. Любая подпрограмма, содержащая секцию DATA, должна также содержать оператор CODE, чтобы завершить секцию описания данных. Переменные, объявленные в разделе данных подпрограммы, не могут иметь атрибутов STATIC или THREAD.

Пример:

SomeProc PROCEDURE

CODE

!операторы кода

DO Tally !Вызов подпрограммы

!операторы

Tally ROUTINE !Начало подпрограммы, конец программной секции

DATA

CountVar BYTE !Объявление локальной переменной

CODE

CountVar += 1 !Увеличивающий счетчик

DO CountItAgain !Вызов другой подпрограммы

EXIT !и выход из подпрограммы

Смотри также: CODE, ROUTINE

 

ROUTINE (объявить локальную подпрограмму)

метка ROUTINE

[ DATA

локальные данные

CODE ]

операторы

 

ROUTINE Объявляет начало локальной подпрограммы.

метка Имя подпрограммы. Не должна дублировать имя любой процедуры.

DATA Начало операторов объявления данных.

локальные данные Объявляет локальные данные видимые только в этой подпрограмме.

CODE Начало исполняемых операторов.

операторы Исполняемые операторы программы.

Оператор ROUTINE объявляет начало локальной подпрограммы. Она локальна по отношению к процедуре, в которой написана, и должна находиться в конце ее программной секции. Все переменные, доступные в процедуре доступны локальной подпрограмме, включая данные локальные для процедуры, для модуля и глобальные данные.

Подпрограмма может содержать свои собственные локальные данные, ограниченные самой подпрограммой, в которой они описаны. Если в подпрограмме имеется описание локальных данных, то ему должен предшествовать оператор DATA, а после описания - оператор CODE. Так как подпрограмма ROUTINE имеет собственную область имен, метки переменных могут дублировать имена переменных используемых в других подпрограммах или даже процедуре, содержащей подпрограмму.

Обращение к локальной подпрограмме производится оператором DO, за которым следует метка локальной подпрограммы. После выполнения локальной подпрограммы, управление передается оператору, следующему за оператором DO. Локальная подпрограмма заканчивается с концом исходного файла или с началом другой подпрограммой или процедурой. Для того, чтобы завершить выполнение локальной подпрограммы, может использоваться оператор EXIT (подобно оператору RETURN в процедуре).

Использование подпрограмм имеет некоторые вопросы, связанные с эффективностью, что не очевидно:

 

Пример:

SomeProc PROCEDURE

CODE

!Операторы

DO Tally !Вызов подпрограммы

!некие исполняемые операторы

Tally ROUTINE !Начало подпрограммы, конец процедуры

DATA

CountVar BYTE !Объявление локальной переменной

CODE

CountVar += 1 !Нарастающий счетчик

DO CountItAgain !Вызов другой подпрограммы

EXIT !и выход из подпрограммы

Смотри также: PROCEDURE, EXIT, DO, DATA, CODE

 

END (закончить структуру)

END

Оператор END заканчивает объявление структуры данных или составной исполняемый оператор. Функционально эквивалентен точке (.).

Принято оператор END выравнивать на ту же колонку, в которой начинается завершаемая им структура, а операторы структуры пишутся с отступом для улучшения читаемости. Обычно, оператор END используется для завершения структур состоящих из нескольких строк, тогда как точка - для структур, занимающих одну строку. Если имеются вложенные исполняемые структуры, и все они заканчиваются в одном месте, то вместо нескольких операторов END на нескольких строках используются несколько точек на одной строке.

Пример:

Customer FILE,DRIVER('Clarion') !Объявление файла

RECORD !Объявление структуры record

Name STRING(20)

Number LONG

END !Конец структуры record

END !Конец объявления файла

Archive FILE,DRIVER('Clarion') !Объявление файла

RECORD !Объявление структуры record

Name STRING(20)

Number LONG

END END !Заканчивает структуру record и файла

CODE

IF Number <> SavNumber !Начало структуры IF

DO GetNumber

END !Конец структуры IF

IF SomeCondition THEN BREAK END !Заканчивается оператором END

CASE Action !Начало структуры case

OF 1

DO AddRec

IF Number <> SavNumber !Начало структуры IF

DO SomeRoutine

END !Конец структуры IF

OF 2

DO ChgRec

OF 3

DO DelRec

END !Конец структуры case

 

Последовательность выполнения операторов

В секции CODE программы на Clarion операторы обычно выполняются по одному, в последовательности их расположения в исходном тексте. Для того чтобы изменить последовательность выполнения операторов, используются управляющие операторы и обращения к процедурам.

Обращение к процедуре изменяет последовательность выполнения программы путем перехода к вызываемой процедуре и выполнения содержащихся в ней исполняемых операторов. Когда в вызванной процедуре выполняется оператор RETURN или в ней выполнен последний оператор, управление возвращается оператору, следующему за обращением к процедуре, возвращая значение (если это предусмотрено в процедуре).

Управляющие структуры IF, CASE, LOOP, ACCEPT и EXECUTE изменяют последовательность выполнения, основываясь на вычислениях выражений. Когда значение выражения вычислено, управляющая структура, в зависимости от условий, выполняет содержащиеся в ней операторы. ACCEPT это тоже loop-тип (цикличный тип), но он не оценивает выражений.

Кроме того, ветвление происходит при выполнении операторов GOTO, DO, CYCLE, BREAK, EXIT и RETURN. Выполнение этих операторов немедленно и безусловно изменяет нормальную последовательность выполнения программы.

Процедура START начинает новый процесс выполнения, безусловно переключая выполнение на этот процесс. Однако, щелкнув мышкой в активном окне другого процесса, пользователь может активировать выполнение этого другого процесса.

Пример:

PROGRAM

MAP

ComputeTime PROCEDURE(*GROUP) !

MatchMaster PROCEDURE !Передача группы в качестве параметра

END

ParmGroup GROUP !Объявление группы

FieldOne STRING(10)

FieldTwo LONG

END

CODE !Начало исполняемых операторов

FieldTwo = CLOCK() !Выполнить сперва

ComputeTime(ParmGroup) !Выполнить затем, передав управление в процедуру

MatchMaster !Выполнить после того, как выполнится процедура

 

Обращение к процедурам

ИмяПроцедуры[(параметры)]

ВозвращаемаяПеременная = ИмяФункции [(параметры)]

ИмяПроцедуры Имя процедуры, как оно объявлено в прототипе процедуры.

параметры Необязательный список параметров, передаваемых процедуре. Список параметров может представлять собой одну или несколько переменных или выражений. Параметры разделяются запятыми и объявляются в прототипе.

ВозвращаемаяПеременная

Имя переменной, в которую заносится возвращаемое процедурой значение.

ИмяФункции Имя процедуры, возвращающей значение, как оно объявлено в прототипе процедуры.

Процедура вызывается указанием ее имени (с возможным списком параметров) в качестве оператора в секции CODE программы или процедуры. Список параметров должен соответствовать списку, объявленному в прототипе процедуры. К процедуре нельзя обращаться в выражении.

Процедура, которая возвращает значение, вызывается указанием ее имени (с возможным списком параметров) в качестве компонента выражения или в списке параметров, передаваемых в другую процедуру. Список параметров должен соответствовать списку, объявленному в прототипе процедуры. Кроме того, если возвращаемое процедурой значение не играет роли, то к ней можно обратиться указанием ее имени (с возможным списком параметров) таким же образом, как к процедуре, которая не возвращает значение, если это не является необходимым. На такое использование процедуры компилятор выдаст предупреждение, которое можно безболезненно проигнорировать (за исключением случая, когда в прототипе размещен атрибут PROC).

Если процедура является методом какого-либо класса, то ИмяПроцедуры должно начинаться с имени объекта класса, за которым через точку следует имя процедуры (имяобъекта.ИмяПроцедуры).

Пример:

PROGRAM

MAP

ComputeTime PROCEDURE(*GROUP) !Передача группы в качестве параметра

MatchMaster PROCEDURE,BYTE,PROC !Процедура возвращает значение и ей не передается

! параметров

END

ParmGroup GROUP !Объявление группы

FieldOne STRING(10)

FieldTwo LONG

END

CODE

FieldTwo = CLOCK() !Встроенная процедура вызывается как выражение

ComputeTime(ParmGroup) !Вызов процедуры ComputeTime

MatchMaster() !Обращение к функции как процедуре

Смотри также: PROCEDURE

 

Прототипы процедур

Синтаксис прототипов

имя PROCEDURE [(список параметров)] [,типы возвращаемых значений] [,соглашение о передаче параметров] [,RAW] [,NAME( )] [,TYPE]

[,DLL( )] [,PROC] [,PRIVATE] [,VIRTUAL] [,PROTECTED] [,REPLACE] [,DERIVED]

имя[(список параметров)] [,типы возвращаемых значений] [,соглашение о передаче параметров] [,RAW] [,NAME( )] [,TYPE] [,DLL( )] [, PROC] [, PRIVATE]

имя Метка оператора PROCEDURE, которая определяет начало секции исполняемых операторов.

PROCEDURE Необходимое ключевое слово.

список параметров Типы данных параметров. За типом данных каждого параметра может следовать метка, использованная для документирования параметра (и только). Каждый параметр может включать присвоение значения, используемого по умолчанию (константы) которое передается, если параметр опущен.

типы возвращаемых значений

Тип возвращаемого процедурой значения.

соглашение о передаче параметров

Задает соглашение о передаче параметров через стек по типу языка C или PASCAL.

RAW Указывает, что для параметров типа STRING или GROUP передается только их адрес в памяти (без длины передаваемой строки). Кроме того, этот атрибут изменяет поведение параметров со знаками ? и *? спереди. Этот атрибут служит только для совместимости с функциями на языках 3-го поколения и не действует для процедур, написанных на языке Clarion.

NAME Задает альтернативное, “внешнее” имя процедуры.

TYPE Указывает, что прототип является определением типа процедуры, передаваемой в качестве параметра.

DLL Указывает, что данная процедура находится во внешней библиотеке DLL.

PROC Задает, что обращение к процедуре, возвращающей значение, как к процедуре, не возвращающей значение, не вызывает предупреждающего сообщения компилятора.

PRIVATE Указывает, что к данной процедуре можно обращаться из других процедур, расположенных в том же самом программном модуле (обычно используется в классах).

VIRTUAL Указывает, что данная процедура представляет собой виртуальный метод структуры CLASS.

PROTECTED Указывает, что PROCEDURE может быть вызвана только из другой процедуры того же объекта CLASS или любого другого CLASS, напрямую полученного из текущего.

REPLACE Указывает, что процедуры "Construct" или "Destruct" в полученном объекте CLASS полностью заменяет конструктор или деструктор родительского класса.

DERIVED Указывает, что PROCEDURE является производным методом структуры CLASS, прототип которой должен совпадать с прототипом родительского класса.

Все процедуры в программе должны быть представлены прототипами в структуре MAP или CLASS. Прототип точно говорит компилятору, какую форму обращения к процедуре ожидать среди исполняемых операторов.

На предыдущей странице перечислены две допустимые формы объявления прототипов. Первая, использующая ключевое слово PROCEDURE, допустима для использования в любом месте и является предпочтительной. Вторая форма пока поддерживается только для совместимости с предыдущими версиями Clarion.

Прототип состоит из:

Дополнительно можно указать для процедуры соглашение о передаче параметров через стек по типу языка C (справа налево) или PASCAL (слева направо и совместимыми с Windows 32-bit). Этим обеспечивается совместимость с библиотеками третьих фирм, написанными на других языках (если они не были компилированы Topspeed компилятором). Если соглашение о передаче параметров не указано, то по умолчанию используется передача параметров в регистрах, принятая в языках семейства TopSpeed.

Независимо от того, передаются ли параметры-значения или параметры-переменные, атрибут RAW позволяет передать просто адрес памяти (*?) для STRING или GROUP в процедуру или функцию не на языке Clarion. Обычно для STRING и GROUP передаются адрес и длина строки или группы. Указание атрибута RAW исключает передачу длины. Это наиболее полезно при использовании внешних библиотечных функций, которые принимают только адрес строки.

Атрибут NAME обеспечивает процедуре внешнее, альтернативное имя. Это также делается для обеспечения совместимости с написанными на других языках библиотеками третьих фирм. Например, в некоторых компиляторах языка С, наряду с принятым в С порядком передачи параметров для функций через стек, компилятор добавляет спереди к имени функции символ подчеркивания. Указание атрибута NAME позволяет компоновщику корректно разрешить ссылку на имя функции.

Атрибут TYPE означает, что прототип не указывает на какую-либо конкретную процедуру. Вместо этого он указывает имя прототипа, использованное в другом прототипе, чтобы обозначить тип процедуры, передаваемый в другую процедуру в качестве параметра.

Атрибут DLL указывает, что данная процедура размещается в библиотеке DLL. Для 32-битовых приложений атрибут DLL обязателен, так как такие библиотеки являются настраиваемыми (перемещаемыми) в 32-битовом адресном пространстве, что требует от компилятора еще одного дополнительного разыменовывания (преобразования адреса) при обращении к процедуре.

Атрибут PRIVATE задает, что к данной процедуре могут обращаться только процедуры, расположенные в этом же самом модуле. Этот атрибут чаще всего используется в MAP-структуре модуля, хотя может использоваться и в глобальной структуре MAP.

Когда имя прототипа указывается в списке параметров другого прототипа, это означает, что прототипируемая процедура будет принимать метку процедуры, которая принимает точно такие же параметры ( и имеет точно такой же тип возвращаемого значения, если она возвращает значение). Прототип с атрибутом TYPE не может иметь атрибута NAME.

Пример:

MAP

MODULE('Test') !'test.clw' содержит эти процедуры и функции

MyProc1 PROCEDURE(LONG) ! параметр-значение типа LONG

MyProc2 PROCEDURE(<*LONG>) ! возможно отсутствие параметра

MyProc3 PROCEDURE(LONG=23) ! Если параметр опущен, то передается 23

END

MODULE('Party3.Obj') ! Библиотека третьей фирмы

Func46 PROCEDURE(*CSTRING),REAL,C,RAW ! передается только адрес строки CSTRING в функцию на C

Func47 PROCEDURE(*CSTRING),*CSTRING,C,RAW ! возвращает указатель на CSTRING

Func48 PROCEDURE(REAL),REAL,PASCAL ! соглашение о вызове как в PASCAL

Func49 PROCEDURE(SREAL),REAL,C,NAME('_func49') ! соглашение о вызове как в C и внешнее

! имя

END

MODULE('STDFuncs.DLL') ! DLL-библиотека стандартных функций

Func50 PROCEDURE(SREAL),REAL,PASCAL,DLL

END

END

Смотри также: MAP, MEMBER, MODULE, NAME, PROCEDURE, RETURN, Списки параметров в прототипах, Перегрузка процедур, CLASS

 

Списки параметров в прототипах – основной синтаксис

[CONST] тип [ метка ]

<[CONST] тип [ метка ] >

тип [ метка ] = по умолчанию

CONST Необязательный классификатор для параметра, который допустим только для параметра-переменной. Это означает, что параметр, переданный по адресу, не может быть изменен в процедуре и будет интерпретироваться как константа.

тип Тип данных параметра. Это может быть параметр-значение, параметр-переменная, неуказанный тип данных, параметр-процедура или именованные объекты GROUP, QUEUE, или CLASS.

метка Необязательная документальная метка параметра. Эта метка необязательна и помещается в прототипе только для документальных нужд.

< > Скобки-уголки указывают на то, что параметр может быть пропущен. Процедура OMITTED определяет такую установку. Все типы параметра могут быть пропущены.

= по умолчанию Значение по умолчанию показывает, что численный параметр может быть пропущен и если это так, то используется значение по умолчанию. Процедура OMITTED не определит упущения, так как присутствует значение по умолчанию. Действительно только в простых численных типах.

Список параметров представляет собой разделенный запятыми список типов данных, передаваемых в процедуру. Весь список параметров, заключенный в скобки, следует за ключевым словом PROCEDURE (или именем). За любым типом данных через пробел может следовать соответствующая синтаксису языка метка параметра (которая игнорируется компилятором и служит только для документирования параметра). Определение любого числового параметра (передаваемого “по значению”) может, кроме того, содержать присвоение числовой константы обозначению типа данных или метке параметра, если таковая имеется. Этим определяется значение по умолчанию, передаваемое в том случае, когда данный параметр опущен.

Если значение, передаваемое по умолчанию не определено, то параметр, который может опускаться при обращении к процедуре, в списке параметров в прототипе должен быть заключен в угловые скобки (<>). Определить во время выполнения программы факт опускания параметра можно с помощью функции OMITTED (за исключением тех опущенных параметров, для которых определено значение, передаваемое по умолчанию).

Пример:

MAP

MODULE('Test')

MyProc1 PROCEDURE(LONG) ! параметр - значение LONG

MyProc2 PROCEDURE(<LONG>) ! OMIT- параметр - LONG

MyProc3 PROCEDURE(LONG=23) ! передается 23 , если параметр опущен

MyProc4 PROCEDURE(LONG Count, REAL Sum) ! LONG передает Count и REAL передает Sum

MyProc5 PROCEDURE(LONG Count=1,REAL Sum=0)! Count по умолчанию - 1, Sum - 0

END

END

Параметры-значения

Параметры-значения являются “передаваемыми по значению”. В “вызываемой” процедуре используются копии переменных, передаваемые “вызывающей” процедурой в списке параметров. “Вызываемая” процедура не может изменить значение переданной ей переменной в “вызывающей” процедуре. К параметрам-значениям применяются обычные правила преобразования данных. Реально передаваемые параметры-значения преобразуются к типу данных, указанному в прототипе данной процедуры. Допустимые типы параметров-значений:

BYTE SHORT USHORT LONG ULONG SREAL REAL DATE TIME STRING

Пример:

MAP

MODULE('Test')

MyProc1 PROCEDURE(LONG) ! Параметр-значение типа LONG

MyProc2 PROCEDURE(<LONG>) ! Параметр-значение типа LONG, который может опускаться

MyProc3 PROCEDURE(LONG=23) ! Если параметр опущен, то передать 23

MyProc4 PROCEDURE(LONG Count, REAL Sum) ! Параметр типа LONG имеет имя Count, а

! параметр типа REAL имеет имя Sum

MyProc5 PROCEDURE(LONG Count=1, REAL Sum=0)!Значение по умолчанию параметра Count равно

!1, а параметра Sum равно 0

END

MODULE('Party3.Obj')

Func48 PROCEDURE(REAL),REAL,PASCAL ! передача параметров как в Паскале

Func49 PROCEDURE(SREAL),REAL,C,NAME('_func49')!передача параметров как в C и внешнее имя.

END

END

Параметры-переменные

Параметры-переменные являются “передаваемыми по адресу”. Переменные, передаваемые по адресу, имеют в памяти только одно местоположение. Изменение значения переменной в “вызываемой” процедуре изменяет его также и в “вызывающей”. Типы данных параметров-переменных приводятся в списке параметров прототипа процедуры или функции в структуре MAP со звездочкой (*) перед названием типа. Допустимые параметры-переменные:

*BYTE *SHORT *USHORT *LONG *ULONG *SREAL *REAL *BFLOAT4 *BFLOAT8

*DECIMAL *PDECIMAL *DATE *TIME *STRING *PSTRING *CSTRING *GROUP

Пример:

MAP

MODULE('Test')

MyProc2 PROCEDURE(<*LONG>) ! Параметр-переменная типа LONG

MyFunc1 PROCEDURE(*SREAL),REAL,C ! Параметр-переменная типа SREAL, возвращается REAL,

! передача параметров как в C

 

MyProc6 PROCEDURE(CONST *CSTRING Value) !Значение сохраняет постоянную величину в

!процедуре

END

MODULE('Party3.Obj')

Func4 PROCEDURE(*CSTRING),REAL,C,RAW ! В функцию на С передается только адрес строки

! типа CSTRING

Func47 PROCEDURE(*CSTRING),CSTRING,C,RAW ! возвращает указатель на CSTRING

END

END

Передача массивов в качестве параметров

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

Пример:

MAP

MainProc PROCEDURE

AddCount PROCEDURE(*LONG[,] Total,*LONG[,] Current) ! Передача двух двумерных массивов

! типа LONG

END

CODE

MainProc ! Вызов первой процедуры

MainProc PROCEDURE

TotalCount LONG,DIM(10,10)

CurrentCnt LONG,DIM(10,10)

CODE

AddCount(TotalCount,CurrentCnt) ! Обратиться к процедуре, передав массив

AddCount PROCEDURE(*LONG[,] Total,*LONG[,] Current) ! Процедура ожидает передачи двух

! массивов

CODE

LOOP I# = 1 TO MAXIMUM(Total,1) ! Цикл по первому индексу

LOOP J# = 1 TO MAXIMUM(Total,2) ! Цикл по второму индексу

Total[I#,J#] += Current[I#,J#] ! увеличить TotalCount из CurrentCnt

END

END

CLEAR(Current) ! Очистить массив CurrentCnt

 

Передача параметров с неопределенным типом данных

Используя нетипизированные параметры-значения и нетипизированные параметры-переменные, можно писать обобщенные процедуры, которые выполняют действия над переданными им параметрами в ситуации, когда точный тип параметра может изменяться от одного обращения к процедуре к другому. Это полиморфные параметры; в зависимости от типа передаваемых в процедуру данных, они могут приобретать любой другой простой тип данных.

Нетипизированные параметры-значения представляются в прототипе процедуры знаком вопроса (?). При выполнении процедуры, параметр динамически обретает тип и действует как объект данных базового типа передаваемой переменной (LONG, DECIMAL, STRING или REAL) или переменной, которой он последний раз был присвоен. Это означает, что этот “подразумеваемый” тип данных параметра можно изменить внутри процедуры, что позволяет его рассматривать как параметр любого типа данных.

Нетипизированные параметры-значения передаются в процедуру “по значению”, а его “подразумеваемый” тип данных подчиняется правилам преобразования данных, принятым в Clarion. Как нетипизированные параметры-значения могут передаваться переменные следующих типов данных:

BYTE SHORT USHORT LONG ULONG SREAL REAL BFLOAT4 BFLOAT8 DECIMAL PDECIMAL DATE TIME STRING PSTRING CSTRING GROUP (трактуемый как STRING) Нетипизированное параметр-значение (?) Нетипизированная параметр-переменная(*?)

Если нетипизированный параметр-значение передается во внешнюю библиотечную функцию, написанную не на языке Clarion, то можно использовать для него атрибут RAW. Это вызовет преобразование данных к типу LONG и затем передачу данных как параметр “void *” в С/С++ (что исключает появление предупреждения о “несовместимости типов”).

Нетипизированные параметры-переменные представляются в прототипе процедуры звездочкой и знаком вопроса (*?). Внутри процедуры параметр с типом переменной действует как объект такого же типа данных, что и переменная в вызывающей процедуре, чье значение передается данным параметром. Это означает, что во время выполнения процедуры тип данных параметра не изменяется.

Нетипизированные параметры-переменные передаются в процедуру “по адресу”. Таким образом, любые изменения, выполненные над переданным параметром, производятся непосредственно над переменной из вызывающей процедуры, использовавшейся в качестве параметра. Параметры с неопределенным типом позволяют писать полиморфные процедуры.

Внутри процедуры, которая получает параметры с нетипизированной параметром-переменной, делать какие-либо предположения о типе данных принятого параметра небезопасно. Опасность такого предположения заключается в том, что существует вероятность присвоения значения, выходящего за границы допустимого для переданного параметра диапазона. Если это происходит, то результат может существенно отличаться от ожидаемого.

Смотри также: ANY (любой простой тип данных)

В качестве нетипизированных параметров-переменных могут передаваться данные следующих типов:

BYTE SHORT USHORT LONG ULONG SREAL REAL BFLOAT4 BFLOAT8 DECIMAL

PDECIMAL DATE TIME STRING PSTRING CSTRING Нетипизированная параметр-переменная (*?)

Если нетипизированный параметр-переменная (*?) передается во внешнюю библиотечную функцию, написанную не на языке Clarion, то можно указать атрибут RAW. В таком случае это эквивалентно передаче параметра “void*” в C/C++.

Массив нельзя передавать ни в одной из форм параметров с неопределенным типом.

Пример:

PROGRAM

MAP

Proc1 PROCEDURE(?) ! Нетипизированный параметр-значение

Proc2 PROCEDURE(*?) ! Нетипизированный параметр-переменная

Proc3 PROCEDURE(*?) ! Нетипизированный параметр-переменная

!(установить для зацикливания)

Max PROCEDURE(?,?),? ! Процедура, возвращающая нетипизированную

! параметр-переменную

END

GlobalVar1 BYTE(3) ! Начальное значение = 3

GlobalVar2 DECIMAL(8,2,3)

GlobalVar3 DECIMAL(8,1,3)

MaxInteger LONG

MaxString STRING(255)

MaxFloat REAL

CODE

Proc1(GlobalVar1) ! Передать байт равный 3

Proc2(GlobalVar2) ! Передать в процедуру DECIMAL(8,2),

! значение равно 3.00 – выдаст 3.33

Proc2(GlobalVar3) ! Передать в процедуру DECIMAL(8,1),

! значение равно 3.0 - выдаст 3.3

Proc3(GlobalVar1) ! Передать в процедуру байт и наблюдать,

! как она зациклится

MaxInteger = Max(1,5) ! Процедура Max возвращает 5

MaxString = Max('Z','A') ! Процедура Max возвращает 'Z'

MaxFloat = Max(1.3,1.25) ! Процедура Max возвращает 1.3

Proc1 PROCEDURE(? ValueParm)

CODE ! ValueParm начинается с 3 и является LONG

ValueParm = ValueParm & ValueParm ! теперь содержит 33 (ValueParm - строка)

ValueParm = ValueParm / 10 ! теперь содержит 3.3 (ValueParm - REAL)

Proc2 PROCEDURE(*? VariableParm)

CODE

VariableParm = 10 / 3 ! Присвоить 3.333333... переданной переменной

Proc3 PROCEDURE(*? VariableParm)

CODE

LOOP

IF VariableParm > 250 THEN BREAK. ! Если передана переменная типа BYTE, то цикл

!бесконечный

VariableParm += 10

END

Max PROCEDURE(Val1,Val2) ! Найти большее из двух переданных значений

CODE

IF Val1 > Val2 ! Сравнить первое значение со вторым

RETURN(Val1) ! и вернуть его, если оно больше

ELSE ! иначе

RETURN(Val2) ! вернуть второе

END

Смотри также: MAP, MEMBER, MODULE, PROCEDURE, CLASS

 

Параметры-объекты

Параметры-объекты передают имя структуры данных в “вызываемую” процедуру. Передача объекта позволяет “вызываемой” процедуре использовать те команды Clarion, которые требуют указания метки структуры в качестве параметра. В прототипе процедуры в структуре MAP параметры-объекты указываются именем объекта. Параметры-объекты всегда “передаются по адресу”. Допустимые параметры-объекты:

FILE VIEW KEY INDEX QUEUE WINDOW REPORT BLOB

REPORT может быть передан как параметр прототипированной процедуре, получающей WINDOW, так как внутренне они используют одинаковую структуру.

Пример:

MAP

MODULE('Test')

MyFunc2 PROCEDURE(FILE),STRING ! Параметр-объект FILE, возвращается строка

ProcType PROCEDURE(FILE),TYPE ! Определение типа параметра-процедуры

MyFunc4 PROCEDURE(FILE),STRING,PROC ! Можно обращаться как к процедуре (не будет

! предупреждения)

MyProc6 PROCEDURE(FILE),PRIVATE ! Может вызываться другими процедурами только модуля

! TEST.CLW

END

END

Параметры-процедуры

Параметры-процедуры передают в “вызываемую” процедуру имя другой процедуры. В прототипе процедуры в структуре MAP параметры-процедуры представляются именем ранее объявленного прототипа такого же типа (который может иметь атрибут TYPE, а может и не иметь). При обращении в программе к “вызываемой” процедуре ей должно передаваться имя процедуры, которая имеет точно такой же прототип, какой имеет процедура, указанная в прототипе “вызываемой” процедуры.

За каждым параметром в списке может следовать допустимая в языке Clarion метка, которая совершенно игнорируется компилятором. Эта метка используется исключительно в целях документирования параметров, чтобы сделать прототип более удобочитаемым или чтобы продублировать определение процедуры. Каждое определение передаваемого параметра может иметь постоянное значение, соответствующее типу данных (или метке, если она есть), используемое по умолчанию, которое передается, когда параметр опущен.

Пример:

MAP

MODULE('Test')

ProcType PROCEDURE(FILE),TYPE ! Определение типа параметра-процедуры

MyFunc3 PROCEDURE(ProcType),STRING ! Процедура-параметр типа ProcType, возвращает STRING,

!должна передаваться процедура, принимающая объект FILE

!в качестве параметра

END

END

 

Передача “поименованных” структур GROUP, QUEUE и CLASS

Передача структуры GROUP как параметра-переменной или QUEUE как параметра-объекта в процедуру не позволяет в вызванной процедуре обращаться к полям - компонентам этих структур. Однако чтобы передавать адрес параметра и обеспечить доступ к полям - компонентам этих структур, можно указать в списке параметров прототипа метку структуры GROUP или QUEUE. Таким же образом можно “поименовать” класс, чтобы обеспечить принимающей процедуре возможность доступа к элементам данных и методам класса.

Для того чтобы обращаться к составляющим структуру полям поместите метку структуры GROUP, QUEUE или структуру CLASS в список прототипируемых параметров процедуры. Параметр передается “по адресу” и позволяет получающей процедуре ссылаться на поля компонентов структуры (общие методы CLASS работают таким же образом).

Структура передаваемых данных всегда должна совпадать с определением, так же как и типы данных составляющих полей. Передаваемая группа или очередь может быть “надмножеством” поименованного параметра, если только идущие впереди поля совпадают соответствующими полями поименованной структуры GROUP или QUEUE. Реально передаваемый класс также может быть производным от поименованного класса. “Экстра” поля в GROUP, QUEUE или CLASS недоступны для использования в получающей процедуре.

Для структур GROUP, QUEUE или CLASS, указанных именем в списке параметров, атрибут TYPE не нужен, и их не нужно объявлять раньше, чем структуру MAP. Однако они должны быть объявлены раньше, чем процедура будет принимать их в качестве параметров при вызове. Это единственный случай в языке Clarion, когда разрешается такая “ссылка вперед”.

Используйте синтаксис Уточнения имени переменной, чтобы ссылаться на компоненты переданной группы в получающей процедуре (LocalName.MemberName). На поля компонентов в структуре ссылаются с помощью имен, данных им в группе, названной так же, как и тип данных в прототипе, а не имена полей в фактически переданной структуре. Это позволяет получающей процедуре быть общей, вне зависимости от того, какая структура данных передается в нее на самом деле.

Пример:

PROGRAM

MAP

MyProc PROCEDURE

AddQue PROCEDURE(PassGroup PassedGroup, NameQue PassedQue)

END ! Принимает GROUP описанную так же

!как PassGroup и QUEUE

! определенную так же как NameQue

PassGroup GROUP,TYPE ! Определение типа - память не выделяется

F1 STRING(20) ! группа с 2-мя полями STRING(20)

F2 STRING(20)

END

NameGroup GROUP ! Имя группы

First STRING(20) ! первое имя

Last STRING(20) ! последнее имя

Company STRING(30) ! Это “Экстра” поле недоступно для

! получающей процедуры

END ! (процедура(AddQue) с PassGroup имеет два поля

NameQue QUEUE,TYPE ! Определение типа Name Queue –

! память не выделяется

First STRING(20)

Last STRING(20)

END

CODE

MyProc

MyProc PROCEDURE

LocalQue NameQue ! Local Name Queue объявляется как NameQue

CODE

NameGroup.First = 'Fred'

NameGroup.Last = 'Flintstone'

AddQue(NameGroup,LocalQue) ! Передача NameGroup и LocalQue процедуре AddQue

NameGroup.First = 'Barney'

NameGroup.Last = 'Rubble'

AddQue(NameGroup,LocalQue)

NameGroup.First = 'George'

NameGroup.Last = 'O''Jungle'

AddQue(NameGroup,LocalQue)

LOOP X# = 1 TO RECORDS(LocalQue) !Проверить, что есть в LocalQue сейчас

GET(LocalQue,X#)

MESSAGE(CLIP(LocalQue.First) & ' ' & LocalQue.Last)

END

AddQue PROCEDURE(PassGroup PassedGroup, NameQue PassedQue)

CODE

PassedQue.First = PassedGroup.F1 ! Актуально: LocalQue.First = NameGroup.First

PassedQue.Last = PassedGroup.F2 ! Актуально: LocalQue.Last = NameGroup.Last

ADD(PassedQue) ! Добавить элемент в очередь PassedQue (LocalQue)

ASSERT(NOT ERRORCODE())

Смотри также: MAP, MEMBER, MODULE, PROCEDURE, CLASS

 

Типы значений, возвращаемых функциями

Процедура объявленная как процедура, возвращающая значение, должна возвращать значение. Тип возвращаемого значения приводится после необязательного списка параметров, отделенный от него запятой. Допустимые типы возвращаемых значений:

BYTE SHORT USHORT LONG ULONG SREAL REAL DATE

TIME STRING нетипизированное значение - параметр (?)

Нетипизированное возвращаемое значение (?) означает, что тип данных возвращаемого процедурой значения неизвестен. Нетипизированное возвращаемое значение работает точно таким же образом, как и нетипизированный параметр-значение. Когда возвращаемое процедурой значение подпадает под стандартные правила преобразования типов, то не имеет значения, какого типа данные вернулись.

Возвращаемые типы переменных:

CSTRING *STRING *BYTE *SHORT *USHORT *LONG

*ULONG *SREAL *REAL *DATE *TIME

нетипизированная переменная - параметр(?)

Возвращаемые типы переменных даны лишь для составления внешних библиотечных функций (написанных на другом языке), которые возвращают только адрес данных - они не используются в процедурах языка Clarion.

В прототипе функций, которые возвращают указатель (адрес данных), типу возвращаемого значения (за исключением CSTRING) должна предшествовать звездочка (*). Во время выполнения программы необходимые действия с возвращенным указателем выполняются автоматически. Функции, прототипированные таким способом, действуют точно так же, как определенные в программе переменные - когда в тексте Clarion-программы используется такая функция, автоматически используются данные, адрес которых возвращен функцией. Эти данные можно присвоить другим переменным, передать в качестве параметров процедурам или получить их адрес с помощью функции ADDRESS.

Тип данных CSTRING является исключением, так как все другие типы данных имеют фиксированную длину, а CSTRING - нет. Поэтому, любую функцию на С, возвращающую указатель на CSTRING, можно прототипировать в С как “char *”, но компилятор копирует элемент данных в стек. Поэтому, точно также как в случае других значений, возвращаемых посредством указателей, при использовании функции в тексте программы на языке Clarion данные, на которые указывает возвращенный функцией указатель, используются автоматически (указатель разыменовывается).

В качестве примера предположим, что функция XYZ() возвращает *CSTRING (указатель на CSTRING), переменная CStringVar имеет тип CSTRING, а переменная LongVar имеет тип LONG. Простой оператор присваивания языка Clarion: CStringVar =XYZ() поместит данные, указанные адресом, который возвратит функция XYZ() в переменную CStringVar. Оператор LongVar = ADDRESS(XYZ()), поместит адрес данных в переменную LongVar.

Нетипизированный параметр-переменная (*?), возвращающая значение, указывает, что тип данных переменной, возвращаемый процедурой, неизвестен. Это происходит тем же образом, что и в случае нетипизированного параметра-переменной.

Ссылочные типы RETURN:

*FILE *KEY *WINDOW *VIEW

Именованный CLASS (*ClassName)

Именованный QUEUE (*QueueName)

PROCEDURE может вернуть ссылку, которая может быть либо закреплена за ссылочной переменной, либо использована в списке параметров там, где присутствие объекта ссылки будет естественным. PROCEDURE, которая возвращает *WINDOW, также может вернуть метку структуры APPLICATION либо REPORT.

Пример:

MAP

MODULE('Party3.Obj') ! Библиотека сторонней фирмы

Func46 PROCEDURE(*CSTRING),REAL,C,RAW

! В функцию на С передается только адрес данных,! возвращается Real

Func47 PROCEDURE(*CSTRING),CSTRING,C,RAW

! Возвращается указатель на CSTRING

Func48 PROCEDURE(REAL),REAL,PASCAL

! Передача параметров по типу PASCAL, возвращается Real.

Func49 PROCEDURE(SREAL),REAL,C,NAME('_func49')

! Передача параметров по типу C и внешнее имя функции, возвращается Real

END

END

Смотри также: MAP, MEMBER, MODULE, NAME, PROCEDURE, RETURN, Переменные-указатели

 

Атрибуты прототипов

C, PASCAL (соглашения о связях)

C

PASCAL

Атрибуты C и PASCAL в прототипе процедуры указывают, что параметры всегда передается через стек. В языке С параметры помещаются в стек справа налево по списку параметров, в то время как в Паскале наоборот, слева направо. Паскаль также полностью совместим с соглашениями о связях интерфейса прикладного программирования (API) Windows для 32-х разрядных приложений, эти соглашения стали соглашениями, используемыми по умолчанию операционной системой (и также запрещает “усечение” имен).

Соглашения о связях обеспечивают совместимость с библиотеками сторонних фирм, написанных на других языках (если они компилировались компиляторами TopSpeed). Если в прототипе не указать тип соглашений о связях, то по умолчанию будет использоваться внутреннее, принятое в компиляторах семейства TopSpeed соглашение, основанное на передаче параметров в регистрах.

Пример:

MAP

MODULE('Party3.Obj') ! Библиотека сторонней фирмы

Func46 PROCEDURE(*CSTRING,*REAL),REAL,C,RAW ! Передавать в функцию написанную

! на С только адрес CSTRING

Func49 PROCEDURE(*CSTRING,*REAL),REAL,PASCAL,RAW ! Передавать CSTRING, затем REAL, !только адрес

END

END

Смотри также: Прототипы процедур, Списки параметров в прототипах

 

DERIVED (предотвращает перегрузку функции)

DERIVED

Атрибут DERIVED в прототипе процедуры указывает, что процедура, для которой он установлен, является виртуальной процедурой. Он может использоваться самостоятельно или дополнительно к атрибуту VIRTUAL в прототипе.

Используйте DERIVED, чтобы принудительно вызвать ошибку компиляции, если найдено несоответствие прототипов между производным виртуальным методом и его родителем. Это предотвращает перегрузку процедуры при использовании виртуальной процедуры.

Пример:

ClassA CLASS

Method1 PROCEDURE(LONG, <LONG>)

END

ClassB CLASS(ClassA)

Method2 PROCEDURE(LONG,<LONG>),DERIVED

END

ClassC CLASS(ClassA)

Method3 PROCEDURE(LONG,<LONG>),VIRTUAL,DERIVED

END

ClassD CLASS(ClassA)

Method4 PROCEDURE(STRING),DERIVED !Вызовет ошибку компиляции

END

Смотри также: CLASS, VIRTUAL

 

DLL (процедура определена внешне, в библиотеке DLL)

DLL( флаг ] )

DLL Объявляет процедуру или функцию, определенную внешне, в библиотеке DLL.

флаг Числовая константа, метка соответствия, или определение системы поддержки проекта, которое задает, активен ли данный атрибут. Если флаг установлен в 0, то этот атрибут неактивен, как если бы его вообще не было. Если флаг имеет отличное от нуля значение, то атрибут активен. Флаг может быть неопределенной меткой, и в этом случае атрибут считается активным.

Атрибут DLL указывает, что процедура, в прототипе которой имеется этот атрибут, определена в библиотеке с динамическими связями (DLL). Для 32-битовых приложений атрибут DLL обязателен, так как такие библиотеки являются настраиваемыми (перемещаемыми) в 32-битовом адресном пространстве, которое требует от компилятора еще одного дополнительного разыменовывания (преобразования адреса) при обращении к процедуре.

Пример:

MAP

MODULE('STDFuncs.DLL') ! DLL - библиотека стандартных функций

Func50 PROCEDURE(SREAL),REAL,PASCAL,DLL(dll_mode) !

END

END

Смотри также: EXTERNAL

 

NAME (установить внешнее имя для прототипируемой процедуры)

NAME( константа )

NAME Указать компоновщику “внешнее” имя

константа Строковая константа. Регистр букв имеет значение.

Атрибут NAME задает внешнее имя, используемое компоновщиком. Этот атрибут может указываться в прототипе процедуры. Параметр константа содержит внешнее имя, используемое компоновщиком для того, чтобы подключить процедуру или функцию из внешней библиотеки или для предоставления прототипам языка Clarion внешних имен для внешних связей (обычно для устранения искажений стандартного имени компилятора), что облегчает составление экспортного листа для .DLL, используемого в других проектах языка.

Пример:

PROGRAM

MAP

MODULE('External.Obj')

AddCount PROCEDURE(LONG),LONG,C,NAME('_AddCount') ! Функция на C называющаяся ‘AddCount’

END

END

Смотри также: Прототипы процедур, Образование Имен и С++ Совместимость

 

PRIVATE (использование процедуры ограничено классом или модулем)

PRIVATE

Атрибут PRIVATE указывает, что к процедуре, в прототипе которой он помещен, можно обращаться из процедур этого же самого исходного модуля. Тем самым она скрывается от процедур других модулей.

Обычно этот атрибут указывается в прототипах методов в структурах CLASS, и поэтому к методу можно обращаться из других методов класса в данном модуле. Частные методы не наследуются классами производными от классов, содержащих прототип частного метода, хотя они могут быть виртуальными методами, если производный класс содержится в этом же модуле.

Пример:

MAP

MODULE('STDFuncs.DLL') ! Стандартные функции .DLL

Func49 PROCEDURE(SREAL),REAL,PASCAL,PROC

Proc50 PROCEDURE(SREAL),PRIVATE ! Вызов только из Func49

END

END

OneClass CLASS,MODULE('OneClass.CLW'),TYPE

BaseProc PROCEDURE(REAL Parm) ! Общий метод

Proc PROCEDURE(REAL Parm),PRIVATE ! Объявить метод частным

END

TwoClass OneClass !Пример класса OneClass

CODE

TwoClass.BaseProc(1) ! Корректный вызов BaseProc

TwoClass.Proc(2) ! Некорректный вызов Proc в OneClass.CLW:

MEMBER()

OneClass.BaseProc PROCEDURE(REAL Parm)

CODE

SELF.Proc(Parm) ! Корректный вызов Proc

OneClass.Proc PROCEDURE(REAL Parm)

CODE

RETURN(Parm)

Смотри также: CLASS

 

PROC (нет предупреждения, что функция вызывается как процедура)

PROC

Атрибут PROC может быть размещен в прототипе процедуры, которая возвращает значение. Это позволяет использовать обычный вызов процедуры, а не только в выражениях и присваиваниях в тех случаях, когда нет нужды использовать возвращаемое значение. Атрибут PROC предупреждает сообщения компилятора, которые обычно в таких случаях вы получаете.

Пример:

MAP

MODULE('STDFuncs.DLL') ! Стандартные функции .DLL

Func50 PROCEDURE(SREAL),REAL,PASCAL,PROC

END

END

Смотри также: PROCEDURE

 

PROTECTED (установить процедуру частной по отношению к CLASS

или дочернему CLASS )

PROTECTED

Атрибут PROTECTED указывает на то, что процедура, в чьем прототипе он помещен, является видимой только для тех процедур, которые объявлены в той же самой структуре CLASS (методах этого CLASS) и методах любого дочернего CLASS. Это предохраняет PROCEDURE от возможного вызова со стороны кода, внешнего по отношению к CLASS, в котором она определена, или последовательности дочерних классов.

Пример:

OneClass CLASS,MODULE('OneClass.CLW'),TYPE

BaseProc PROCEDURE(REAL Parm) ! Общий метод

Proc PROCEDURE(REAL Parm),PROTECTED !Объявление защищенного метода

END

TwoClass OneClass ! Экземпляр OneClass

ThreeClass CLASS(OneClass),MODULE('ThreeClass.CLW') ! Дочерний от OneClass

ThreeProc PROCEDURE(REAL Parm) ! Объявление общего метода

END

CODE

TwoClass.BaseProc(1) ! Корректный вызов BaseProc

TwoClass.Proc(2) ! Некорректный вызов Proc в OneClass.CLW:

MEMBER()

OneClass.BaseProc PROCEDURE(REAL Parm)

CODE

SELF.Proc(Parm) ! Корректный вызов Proc

OneClass.Proc PROCEDURE(REAL Parm)

CODE

RETURN(Parm)

!В ThreeClass.CLW:

MEMBER()

ThreeClass.NewProc PROCEDURE(REAL Parm)

CODE

SELF.Proc(Parm) ! Корректный вызов Proc

Смотри также: CLASS

 

RAW (передавать только адрес)

RAW

Атрибут RAW задает в прототипе процедуры для передаваемых в качестве параметров групп и строк передачу только их адреса памяти. Он позволяет для параметров типа *?, STRING или GROUP передавать в процедуру или функцию, написанную не на языке Clarion, только адрес памяти, независимо от того передаются ли параметры по адресу или по значению. Обычно, для параметров типа STRING или GROUP передается адрес и длина строки. Указание атрибута RAW исключает передачу длины. В случае прототипа с параметром неопределенного типа (?) параметр воспринимается как LONG, но передается как “void *”, что исключает появление предупреждений компоновщика. Этот атрибут введен для того, чтобы обеспечить совместимость с внешними библиотечными функциями, которые при вызове ожидают передачи только адреса строки.

Если функция прототипирована для возврата значения одним из следующих типов: ?, *? или *STRING, и прототип имеет атрибут RAW, то возвращаемое значение будет трактоваться как LONG.

Пример:

MAP

MODULE('Party3.Obj') ! Библиотека сторонней фирмы

Func46 PROCEDURE(*CSTRING),REAL,C,RAW ! Передавать в функцию, написанную на С только

END ! адрес CSTRING

END

Смотри также: Прототипы процедур, Списки параметров в прототипах

 

REPLACE (установить конструктор или деструктор замены)

REPLACE

Атрибут REPLACE указывает, что PROCEDURE, в чьем прототипе он помещен, полностью заменяет конструктор или деструктор родительского класса. REPLACE действителен только в PROCEDURE с меткой “Construct” или “Destruct” и объявленной в структуре CLASS, дочерней для класса, также содержащего упоминание “Construct” или “Destruct”. Если меткой PROCEDURE является “Construct”, то методом является Конструктор, автоматически вызываемый при подтверждении объекта. Объект подтверждается при вхождении в область видимости или при создании оператором NEW. Если меткой PROCEDURE является “Destruct”, то методом - Деструктор, автоматически вызываемый при уничтожении объекта. Объект уничтожается при выходе из области видимости или при уничтожении оператором DISPOSE.

Пример:

PROGRAM

SomeQueue QUEUE,TYPE

F1 STRING(10)

END

OneClass CLASS,MODULE('OneClass.CLW'),TYPE

ObjectQueue &SomeQueue ! Объявление ссылки на поименованную очередь

Construct PROCEDURE ! Объявление Конструктора

Destruct PROCEDURE ! Объявление Деструктора

END

TwoClass CLASS(OneClass),MODULE('TwoClass.CLW'),TYPE

Construct PROCEDURE,REPLACE ! Объявление замены Constructor

END

MyClass OneClass ! Экземпляр OneClass

YourClass &TwoClass ! Ссылка на TwoClass

CODE ! Появление объекта MyClass

! вызов OneClass.Construct

YourClass &= NEW(TwoClass) ! Появление объекта YourClass

! вызов TwoClass.Construct

DISPOSE(YourClass) ! Завершение объекта YourClass

! вызов OneClass.Destruct

RETURN ! Завершение объекта MyClass

! вызов OneClass.Destruct

! OneClass.CLW содержит

OneClass.Construct PROCEDURE

CODE

SELF.ObjectQueue = NEW(SomeQueue) !Создание очереди объектов

OneClass.Destruct PROCEDURE

CODE

FREE(SELF.ObjectQueue) ! очистить очередь объектов

DISPOSE(SELF.ObjectQueue) ! и удалить очередь

!TwoClass.CLW содержит:

TwoClass.Construct PROCEDURE

CODE

SELF.ObjectQueue = NEW(SomeQueue) ! Создание очереди объектов

SELF.ObjectQueue.F1 = 'First Entry'

ADD(SELF.ObjectQueue)

Смотри также: NEW, DISPOSE, CLASS

 

TYPE (задать определение типа процедуры)

TYPE

Атрибут TYPE задает прототип, который не является ссылкой на реальную процедуру. Вместо этого, он определяет имя прототипа, которое должно использоваться в других прототипах для обозначения типа процедуры, передаваемой в другую процедуру в качестве параметра.

Когда имя типизированного прототипа используется в списке параметров другого прототипа, процедура, которую этот другой прототип представляет, будет принимать в качестве параметра метку оператора PROCEDURE, которая имеет точно такой же список параметров (и такое же возвращаемое значение, если она возвращает значение), что и типизированный прототип.

Пример:

MAP

ProcType PROCEDURE(FILE),TYPE ! Определение типа процедуры-параметра

MyFunc3 PROCEDURE(ProcType),STRING ! Параметр - процедура, возвращается

!строка

!должна передаваться метка

!процедуры, которая принимает

! в качестве параметра файл

END

Смотри также: Прототипы процедур, Списки параметров в прототипах

 

VIRTUAL (установить, что метод виртуальный)

VIRTUAL

Атрибут VIRTUAL указывает, что процедура, в прототипе которой он задан, является виртуальным методом структуры CLASS, содержащий этот прототип. Этот атрибут позволяет методам родительского класса обращаться к методам дочернего класса. Атрибут VIRTUAL нужно поместить и в прототип метода родительского класса, и в прототип метода производного класса.

Пример:

OneClass CLASS ! Базовый класс

BaseProc PROCEDURE(REAL Parm) ! Не виртуальный метод

Proc PROCEDURE(REAL Parm),VIRTUAL ! Объявить виртуальный метод

END

TwoClass CLASS(OneClass) ! Производный от OneClass класс

Proc PROCEDURE(REAL Parm),VIRTUAL ! Объявить виртуальный метод

END

ClassThree OneClass ! Другой экземпляр объекта класса OneClass

ClassFour TwoClass ! Другой экземпляр объекта класса TwoClass

CODE

OneClass.BaseProc(1) ! BaseProc обращается к OneClass.Proc

TwoClass.BaseProc(2) ! BaseProc обращается к TwoClass.Proc

ClassThree.BaseProc(3) ! BaseProc обращается к OneClass.Proc

ClassFour.BaseProc(4) ! BaseProc обращается к TwoClass.Proc

OneClass.BaseProc PROCEDURE(REAL Parm)

CODE

SELF.Proc(Parm) ! Обращение к виртуальному методу, или OneClass.Proc

! или TwoClass.Proc, в зависимости от того, какой

! экземпляр объекта выполняется

Смотри также: CLASS

 

Перегрузка процедур

Перегрузка процедур означает возможность в нескольких определениях процедур использовать одно и то же имя процедуры. Это одна из форм полиморфизма. Для того чтобы сделать возможными одинаковые имена, каждая такая процедура должна получать различные параметры так, чтобы, основываясь на списке параметров, компилятор мог определить, к какой процедуре осуществляется обращение.

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

В языке Clarion также имеются полиморфные функции, для которых используются параметры “?” и “*?”, однако Перегрузка процедур расширяет этот полиморфизм, чтобы еще включать параметры-объекты и параметры “поименованные группы”.

Одним из примеров перегрузки функций может служить оператор OPEN языка Clarion, который инициализирует объект для последующего использования в программе. В зависимости от того, объект какого типа ему передан (файл, окно, структура VIEW и т.д.) он выполняет похожие, но физически различные действия.

Смотри также: Правила перегрузки процедур, Образование Имен и С++ Совместимость

 

Правила перегрузки процедур

В языке Clarion имеется встроенное преобразование типов данных, что может затруднить для компилятора реализацию перегрузки. Поэтому есть правила, обуславливающие реализацию компилятором перегрузки функций. Эти правила применяются в следующем порядке:

1. Параметры-объекты приводятся к объектам FILE, KEY, WINDOW и QUEUE. Если уже после этого можно выбрать прототип, то компилятор это и делает (под это правило попадают большинство встроенных процедур Clarion). Заметим, что KEY и VIEW неявно происходят от FILE, в то время как APPLICATION и REPORT - от WINDOW.

2. Все параметры “поименованные группы” должны соответствовать друг другу по своей структуре. Параметры-процедуры соответствуют по структуре. Классы должны соответствовать по именам, а не просто по структуре.

3. Прототипы должны соответствовать по числу и порядку следования обязательных параметров. Это третий (а не первый) фактор, по которому обычно компилятор может решить, какой прототип пользователь имел в виду или выдать наиболее осмысленное сообщение об ошибке.

4. Если соответствующий прототип не найден, то допускается соответствие производных объектов. В этот момент допускается, что KEY может соответствовать FILE, а группа, которая предполагается производной, должна соответствовать одному из базовых классов. Если одно предположение о производности объекта не срабатывает, делается следующее и так до трех раз. Теперь все QUEUE соответствуют очередям и группам и т.п. Прежде остальных типов параметров устанавливается происхождение классов.

5. Параметры-переменные (непоименованные) должны точно соответствовать типам реально передаваемых данных. *GROUP соответствует *STRING. ANY параметр-переменная соответствует *?

6. Все параметры значения считаются имеющими один и тот же тип.

Пример:

MAP

Func PROCEDURE(WINDOW) ! 1

Func PROCEDURE(FILE) ! 2

Func PROCEDURE(KEY) ! 3

Func PROCEDURE(FILE,KEY) ! 4

Func PROCEDURE(G1) ! 5

Func PROCEDURE(G0) ! 6

Func PROCEDURE(KEY,G0) ! 7

Func PROCEDURE(FILE,G1) ! 8

Func PROCEDURE(SHORT = 10) ! 9

Func PROCEDURE(LONG) ! 10

Func PROCEDURE() ! Неправильно, неотличимо от 9

Func PROCEDURE(*SHORT) ! 11

Func1 PROCEDURE(*SHORT)

Func1a PROCEDURE(*SHORT)

Func2 PROCEDURE(*LONG)

Func PROCEDURE(Func1) ! 12

Func PROCEDURE(Func1a) ! Неправильно, то же, что и 12

Func PROCEDURE(Func2) ! 13

END

G0 GROUP

END

G1 GROUP(G0)

END

CODE

Func(A:Window) ! Обращение к 1 по правилу 1

Func(A:File) ! Обращение к 2 по правилу 1

Func(A:Key) ! Обращение к 3 по правилу 1

Func(A:View) ! Обращение к 2 по правилу 4

Func(A:Key,A:Key) ! Обращение к 4 по правилу 4 (следовало бы обратиться

! к функции с параметрами key,key, если бы она была)

Func(A:G0) ! Обращение к 6 по правилу 2

Func(A:G1) ! Обращение к 5 по правилу 2

Func(A:Func2) ! Обращение к 13 по правилу 2

Func(A:Key,A:G1) ! Ошибка - неопределенность. Если использовать правило

!4, то подходят и 7 и 8

Func(A:Short) ! Ошибка - неопределенность. Обращение к 9 или 11

Func(A:Real) ! Обращение к 9 по правилу 6

Func ! Обращение к 9 по правилу 3

Смотри также: CLASS

 

Образование имен и совместимость с C++

Каждая перегружаемая функция будет иметь для компоновки имя, составленное из имени процедуры и “усеченного” списка аргументов (атрибут NAME может причинить вред усечению имени). Образование имен разработано так, чтобы обеспечить некоторую степень перекрестных обращений между C++ и Clarion. Со стороны C++ необходимо указать:

#pragma name(prefix=>” “)

и имена, состоящие из прописных букв. Со стороны Clarion нужно иметь структуру MODULE со строкой нулевой длины в качестве параметра:

MODULE(‘ ‘)

END

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

Clarion C++

BYTE unsigned char

USHORT unsigned short

SHORT short

LONG long

ULONG unsigned long

SREAL float

REAL double

*CSTRING (with RAW) char&

<*CSTRING> (with RAW) char*

<*GROUP> (with RAW) void*

Отметим, что для совместимости с С++ тип возвращаемых процедурой данных не включен в составное имя. Естественным следствием этого является то, что процедуры нельзя различить по типу возвращаемого значения.

Пример:

//прототипы в C++:

#pragma name(prefix=>"")

void HADD(short,short);

void HADD(long*,unsigned char);

void HADD(short unsigned &);

void HADD(char *,void *);

!прототипы в Clarion:

MODULE('')

hADD(short,short)

HaDD(<*long>,byte)

HAdD(*ushort)

HADd(<*CSTRING>,<*GROUP>),RAW

END

Смотри также: NAME

 

Директивы компилятора

Директивы компилятора представляют собой операторы, которые во время компиляции предписывают ему предпринять некоторые действия. В объектный код программы, который генерирует компилятор, эти операторы не включаются, не привнося, таким образом, никаких издержек в исполняемый модуль.

 

ASSERT (установить правила для отладки)

ASSERT(выражение, [сообщение] )

ASSERT Указывает правила для использования в целях отладки.

выражение Булевское выражение, которое должно всегда являться истинным (любое значение, кроме пробела или ноля).

сообщение Необязательное строковое выражение (до 64K), которое отображается в диалоговом окне.

Оператор ASSERT указывает на оценку выражения точно в той точке программы, где он помещен. Это может быть любое Булевское выражение, сформулированное таким образом, чтобы ожидаемый результат оценки всегда был истинным (любое значение, кроме пробела или ноля). Назначение ASSERT- помощь программисту при определении ошибочных присвоений.

Если включен режим отладки и значение выражения – ложь (пробел или ноль), то появится сообщение об ошибке, содержащее номер строки и модуль исходного кода в точке, где заявленное выражение приняло ложное значение. Пользователь получает предложение применить к программе GPF в той точке, которая позволяет активироваться пост-мортемным отладчикам (post-mortem debuggers).

Если режим отладки отключен, то выражение всегда оценивается, но сообщение об ошибке при определении ложного результата не появляется. Чтобы активизировать сообщение об ошибке в построенном релизе (отладка выключена), в определения проекта приложения можно добавить следующее:

asserts=>on

Пример:

MyQueue QUEUE

F1 LONG

END

CODE

LOOP X# = 1 TO 10

MyQueue.F1 = X#

ADD(MyQueue)

ASSERT(~ERRORCODE(),'ADD MyQueue Error ' & ERROR())

END

LOOP X# = 1 TO 10

GET(MyQueue, X#)

ASSERT(~ERRORCODE()) !Сообщение об ошибке появится, если произойдет ошибка

END !добавления

 

BEGIN (определить операторную структуру)

BEGIN

операторы

END

BEGIN Объявляет структуру из операторов, рассматриваемую как единый оператор.

операторы Исполняемые операторы программы.

Директива BEGIN предписывает компилятору обрабатывать группу операторов как единую структуру. Структура BEGIN должна заканчиваться точкой или оператором END.

В управляющей структуре EXECUTE директива BEGIN обычно используется для того, чтобы несколько операторов рассматривались как один.

Пример:

EXECUTE Value

Proc1 ! Выполнить, если Value=1

BEGIN ! Выполнить, если Value=2

Value += 1

Proc2

END

Proc3 ! Выполнить, если Value=3

END

Смотри также: EXECUTE

 

COMPILE (указать исходный текст для компиляции)

COMPILE(терминатор[,выражение])

COMPILE Задает порцию строк исходного текста, которые должны быть включены в процесс компиляции.

терминатор Строковая константа, которая отмечает последнюю строку исходного текста, подлежащего компиляции.

выражение Выражение, позволяющее осуществить условную компиляцию. Это одно из двух: выражение вида: МЕТКА СООТВЕТСТВИЯ = целочисленная константа или МЕТКА СООТВЕТСТВИЯ, чье значение ноль или единица.

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

Необязательный параметр выражение обеспечивает условную компиляцию. Форма выражения фиксирована: метка соответствия или условный переключатель, установленный в системе поддержки проекта, затем знак равенства (=), за которым следует целочисленная константа.

Программный текст между директивой COMPILE и терминатором компилируется, только если выражение истинно. Если выражение содержит EQUATE, который еще не определен, то ссылочное значение EQUATE принимается равным нулю.

Хотя выражение является необязательным, директива COMPILE без этого параметра не нужна, потому, что если нет явно указанных исключений, то компилируется весь исходный текст. Директивы COMPILE и OMIT противоположны по значению друг другу.

ЛАВА

Пример:

OMIT('***',_WIDTH32_) !Пропускать, если приложение 32-битное

SIGNED EQUATE(SHORT)

UNSIGNED EQUATE(USHORT)

***

COMPILE('***',_WIDTH32_) ! Компилировать если приложение 32-битное

SIGNED EQUATE(LONG)

UNSIGNED EQUATE(ULONG)

***

COMPILE('EndOfFile',OnceOnly = 0) !Компилировать только первый раз, потому что связанное

! с этим

OnceOnly EQUATE(1) соответствие OnceOnly определено после COMPILE

! поэтому второй проход в этой компиляции

! не будет перекомпилировать этот код

Demo EQUATE(1) ! Задается значение метки соответствия Demo

CODE

COMPILE('EndDemoChk',Demo = 1) ! Компилировать, если Demo включено

DO DemoCheck ! Проверить ограничения для демо-версии

! EndDemoChk ! Конец участка условной компиляции

! EndOfFile

!Следующий ниже пример, показывает, как OMIT и COMPILE могут быть вложены

COMPILE ('**32bit**',_width32_) !внешний COMPILE

COMPILE ('*debug*',_debug_)

DEBUGGER::BUTTONLIST Equate('&Continue|&Halt|&Debug')

!конец- COMPILE ('*debug*',_debug_)

OMIT ('*debug*',_debug_)

DEBUGGER::BUTTONLIST Equate('&Continue|&Halt')

!конец- OMIT ('*debug*',_debug_)

!конец- COMPILE ('**32bit**',_width32_) !конец внешнего COMPILE

OMIT ('**32bit**',_width32_)

DEBUGGER::BUTTONLIST Equate('&Continue|&Halt')

!конец- OMIT ('**32bit**',_width32_)

Смотри также: OMIT, EQUATE

 

INCLUDE (компилировать текст другого файла)

INCLUDE(файл [,секция]) [,ONCE]

INCLUDE Указывает что, следует компилировать исходный текст, который находится в отдельном файле, не являющемся member-модулем.

файл Строковая константа, которая содержит спецификацию файла исходного текста. Если расширение опущено, то подразумевается .CLW

секция Строковая константа, которая является параметром строки директивы SECTION, помечающей текст исходного кода, который должен быть включен в текст программы.

ONCE Атрибут ONCE предотвратит любые включения данных, которые могут вызвать предупреждения или ошибки компилятора из-за того, что компилируются неоднократно. Что касается использования атрибута секции, ONCE применим для использования файла целиком, без секций, таким образом, использование INCLUDE(файл, секция) будет проигнорировано.

Директива INCLUDE задает исходный текст, который должен компилироваться, и который находится в отдельном файле, который не является MEMBER-модулем. Начиная со строки, содержащей директиву INCLUDE, указанный ею файл исходного текста или секция того файла компилируется, как если бы они находились в этом месте компилируемого исходного модуля. Вложенность вставляемых файлов может равняться 3-м, то есть можно вставить оператором INCLUDE файл, в который оператором INCLUDE вставляется файл, в который оператором INCLUDE вставляется файл, но в этот последний файл уже нельзя вставить оператором INCLUDE ничего.

Для того чтобы найти файл, компилятор использует redirection-файл (CurrentReleaseName.RED), просматривая каталоги, указанные для этого типа файлов (обычно по расширению). Это снимает необходимость указывать полный путь к включаемому в компиляцию файлу. Redirection-файл рассматривается в Руководстве программиста и главе Project System в Руководстве Программиста.

Пример:

GenLedger PROCEDURE ! Объявить процедуру

INCLUDE('filedefs.clw') ! Здесь включить объявление файлов

CODE ! Начало программной секции

INCLUDE('Setups','ChkErr') ! Включить проверку ошибок из файла setups.cla

Смотри также: SECTION, ONCE

 

EQUATE (назначить соответствие)

| метка |

метка EQUATE( | [ константа ] | )

| шаблон |

| тип |

EQUATE Назначает метку другой метке или константе.

метка Метка любого оператора, предшествующего оператору EQUATE. Эта форма используется для объявления альтернативной метки оператора, которая не может быть меткой процедуры или подпрограммы.

константа Числовая или строковая константа. Эта форма используется для объявления сокращенной метки для значения константы. Это позволяет легко найти и изменить константу. Она может быть опущена только в структуре ITEMIZE. Также в качестве константы может быть использовано выражение (подобно 1+2 или BOR(1111b,0001b)).

шаблон Шаблон. Эта форма используется для того, чтобы объявить сокращенную метку для шаблона. Однако форматеры экрана и отчета в редакторе Clarion не воспринимают метку соответствия, как правильный шаблон.

тип Тип данных. Обычно этот параметр используется для того, чтобы объявить единый способ объявления переменной как переменной одного из нескольких возможных типов в зависимости от установок параметров компиляции (подобно описанию typedef в С++ для простого типа данных).

Директива EQUATE не порождает какого-нибудь выделения памяти. Она используется для того, чтобы назначить метку другой метке или константе. Метка самой директивы не может совпадать с меткой - параметром директивы.

Пример:

Init EQUATE(SetUpProg)!Установить метку алиаса

Off EQUATE(0) !Off значит 0

On EQUATE(1) !On значит 1

PI EQUATE(3.1415927) !Значение Пи

EnterMsg EQUATE('Press Ctrl-Enter to SAVE')

SocSecPic EQUATE(@P###-##-####P) !Soc-sec шаблон

Смотри также: Зарезервированные слова, ITEMIZE

 

ITEMIZE (перечень данных структуры)

[метка] ITEMIZE( [ источник ] ) [,PRE( )]

соответствия

END

метка Необязательная метка для структуры ITEMIZE.

ITEMIZE Перечень данных структуры.

источник Целочисленная константа или выражение, определяющее значение для первого оператора EQUATE в структуре.

PRE Определение метку префикса для переменной в структуре.

соответствия Последовательность объявлений EQUATE, которая определяет положительные целые значения в диапазоне от 0 до 65535.

Структура ITEMIZE определяет перечень данных. Если первое соответствие не объявлено и не определено значение источника, считать его равным единице (1). Все последующие соответствия инкрементные, с шагом 1, если их величина не специфицирована. Если величина задана для подмножества соответствий, все последующие соответствия будут инкрементными с шагом, равным единице (1).

На соответствия в структуре ITEMIZE можно ссылаться указанием, с добавлением спереди, префикса к метке соответствия (PRE атрибут--PRE:EquateLabel). Если же структура ITEMIZE имеет пустой префикс, тогда к соответствиям нужно обращаться с указанием метки ITEMIZE впереди метки соответствия (метка:EquateLabel). Если же префикса или метки нет, тогда на соответствия ссылаются указанием их собственной метки без префикса.

Пример:

ITEMIZE

False EQUATE(0) !False = 0

True EQUATE !True = 1

END

Color ITEMIZE(0),PRE !Значеение источника равно нулю

Red EQUATE !Color:Red = 0

White EQUATE !Color:White = 1

Blue EQUATE !Color:Blue = 2

Pink EQUATE(5) !Color:Pink = 5

Green EQUATE !Color:Green = 6

Last EQUATE

END

Stuff ITEMIZE(Color:Last + 1),PRE(My) !Постоянное выражение как источник

X EQUATE !My:X = Color:Last + 1

Y EQUATE !My:Y = Color:Last + 2

Z EQUATE !My:Z = Color:Last + 3

Смотри также: EQUATE, PRE

 

OMIT (указать текст, который не должен компилироваться)

OMIT(терминатор[,выражение])

OMIT Задает порцию строк исходного текста, которые во время компиляции должны пропускаться.

терминатор Строковая константа, которая отмечает последнюю строку блока исходного текста.

выражение Выражение, позволяющее осуществить условное выполнение директивы OMIT. Выражение должно быть типа МЕТКА СООТВЕТСТВИЯ = целочисленная константа или ноль / единица или EQUATE = целое.

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

Необязательный параметр выражение обеспечивает условный пропуск блока. Формат выражения фиксированный: метка соответствия или условный переключатель, установленный в системе поддержки проекта, затем знак равенства (=), за которым следует целочисленная константа.

Директива OMIT выполняется, только если выражение истинно. Таким образом, код между OMIT и терминатором компилируется только если выражение не истинно. Если выражение содержит еще не определенное EQUATE, то ссылочное значение EQUATE принимается равным нулю. COMPILE и OMIT противоположны по значению.

2 Формат исходного текста программы 77

Пример:

OMIT('**END**') ! Безусловный OMIT

! Главный цикл программы

**END**

OMIT('***',_WIDTH32_) ! OMIT если приложение 32-битное

SIGNED EQUATE(SHORT)

***

COMPILE('***',_WIDTH32_) ! COMPILE если приложение 32-битное

SIGNED EQUATE(LONG)

***

OMIT('EndOfFile',OnceOnly) ! Компилировать только первый раз, потому что связанное

! с этим

OnceOnly EQUATE(1) ! соответствие OnceOnly определено после COMPILE

! поэтому второй проход в этой компиляции

! не будет перекомпилировать этот код

Demo EQUATE(0) ! Установить значение метки Demo

CODE

OMIT('EndDemoChk',Demo = 0) ! Пропустить только если Demo выключено

DO DemoCheck ! Проверить ограничения для демо-версии

! Конец пропускаемого текста

! Конец кода

! Конец файла

! Следующий ниже пример, показывает, как OMIT и COMPILE могут быть вложены

COMPILE ('**32bit**',_width32_) !внешний COMPILE

COMPILE ('*debug*',_debug_)

DEBUGGER::BUTTONLIST Equate('&Continue|&Halt|&Debug')

!конец- COMPILE ('*debug*',_debug_)

OMIT ('*debug*',_debug_)

DEBUGGER::BUTTONLIST Equate('&Continue|&Halt')

!конец- OMIT ('*debug*',_debug_)

!конец- COMPILE ('**32bit**',_width32_) !конец внешнего COMPILE

OMIT ('**32bit**',_width32_)

DEBUGGER::BUTTONLIST Equate('&Continue|&Halt')

!конец- OMIT ('**32bit**',_width32_)

Смотри также: COMPILE, EQUATE

 

ONCE (недопущение дублирования включенных данных)

Атрибут ONCE предотвращает появление предупреждений или ошибок, выдаваемых компилятором для включенных в приложение данных, компилированных больше одного раза.

Пример:

INCLUDE('KEYCODES.CLW'),ONCE

Смотри также: INCLUDE

 

SECTION (указать секцию исходного текста)

SECTION(строка)

 

SECTION Идентифицирует начало некоторой порции исполняемых операторов.

строка Строковая константа, представляющая собой имя секции.

Директива компилятора SECTION идентифицирует начало блока исполняемых операторов или операторов объявления данных, которые могут быть включены в исходный текст в другом файле. Имя блока используется в качестве необязательного параметра в директиве INCLUDE для того, чтобы осуществить включение в компиляцию указанного блока исходного текста. Блок заканчивается следующей директивой SECTION или по концу файла исходного текста.

Пример:

SECTION('FirstSection') !Начало секции

FieldOne STRING(20)

FieldTwo LONG

SECTION('SecondSection') !Конец предыдущей секции, начало новой

IF Number <> SavNumber

DO GetNumber

END

SECTION('ThirdSection') ! Конец предыдущей секции, начало новой

CASE Action

OF 1

DO AddRec

OF 2

DO ChgRec

OF 3

DO DelRec

END !Третья секция заканчивается по концу файла

Смотри также: INCLUDE

 

SIZE (размер памяти в байтах)

| переменная |

SIZE( | константа | )

| шаблон |

SIZE Представляет общий размер памяти, использованной для хранения.

переменная Метка ранее объявленной переменной.

константа Числовая или строковая константа.

шаблон Шаблон.

Директива SIZE предписывает компилятору подставить вместо директивы число байт памяти, используемой для хранения переменной, константы или шаблона.

Пример:

SavRec STRING(1),DIM(SIZE(Cus:Record) ! Размерность массива равна длине записи

StringVar STRING(SIZE('SoftVelocity')) ! Длина строки равна длине константы

LOOP I# = 1 TO SIZE(ParseString) ! Цикл по числу байтов в строке

PicLen = SIZE(@P(###)###-####P) ! Запомнить длину шаблона

Смотри также: LEN, PROP:Size, Свойства структуры файла

к оглавлению

Знаете ли Вы, что абстракция через спецификацию - это прием программирования, позволяющий абстрагироваться от процесса вычислений описанных в теле процедуры, до уровня знания того, что данная процедура делает. Это достигается путем задания спецификации, описывающей эффект ее работы, после чего смысл обращения к данной процедуре становится ясным через анализ этой спецификации, а не самого тела процедуры. Мы пользуемся абстракцией через спецификацию всякий раз, когда связываем с процедурой некий комментарий, достаточно информативный для того, чтобы иметь возможность работать без анализа тела процедуры. Абстракция через спецификацию позволяет абстрагироваться от процесса вычислений описанных в теле процедуры, до уровня знания того, что данная процедура делает. Это достигается путем задания спецификации, описывающей эффект ее работы, после чего смысл обращения к данной процедуре становится ясным через анализ этой спецификации, а не самого тела процедуры. Мы пользуемся абстракцией через спецификацию всякий раз, когда связываем с процедурой некий комментарий, достаточно информативный для того, чтобы иметь возможность работать без анализа тела процедуры.

НОВОСТИ ФОРУМА

Форум Рыцари теории эфира


Рыцари теории эфира
 10.11.2021 - 12:37: ПЕРСОНАЛИИ - Personalias -> WHO IS WHO - КТО ЕСТЬ КТО - Карим_Хайдаров.
10.11.2021 - 12:36: СОВЕСТЬ - Conscience -> РАСЧЕЛОВЕЧИВАНИЕ ЧЕЛОВЕКА. КОМУ ЭТО НАДО? - Карим_Хайдаров.
10.11.2021 - 12:36: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ - Upbringing, Inlightening, Education -> Просвещение от д.м.н. Александра Алексеевича Редько - Карим_Хайдаров.
10.11.2021 - 12:35: ЭКОЛОГИЯ - Ecology -> Биологическая безопасность населения - Карим_Хайдаров.
10.11.2021 - 12:34: ВОЙНА, ПОЛИТИКА И НАУКА - War, Politics and Science -> Проблема государственного терроризма - Карим_Хайдаров.
10.11.2021 - 12:34: ВОЙНА, ПОЛИТИКА И НАУКА - War, Politics and Science -> ПРАВОСУДИЯ.НЕТ - Карим_Хайдаров.
10.11.2021 - 12:34: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ - Upbringing, Inlightening, Education -> Просвещение от Вадима Глогера, США - Карим_Хайдаров.
10.11.2021 - 09:18: НОВЫЕ ТЕХНОЛОГИИ - New Technologies -> Волновая генетика Петра Гаряева, 5G-контроль и управление - Карим_Хайдаров.
10.11.2021 - 09:18: ЭКОЛОГИЯ - Ecology -> ЭКОЛОГИЯ ДЛЯ ВСЕХ - Карим_Хайдаров.
10.11.2021 - 09:16: ЭКОЛОГИЯ - Ecology -> ПРОБЛЕМЫ МЕДИЦИНЫ - Карим_Хайдаров.
10.11.2021 - 09:15: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ - Upbringing, Inlightening, Education -> Просвещение от Екатерины Коваленко - Карим_Хайдаров.
10.11.2021 - 09:13: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ - Upbringing, Inlightening, Education -> Просвещение от Вильгельма Варкентина - Карим_Хайдаров.
Bourabai Research - Технологии XXI века Bourabai Research Institution