| Синтаксис.
/*
CLASS
{имена}
, модификаторы
:
IMPORT: {Class1} ... ;
BASE CLASS {базовый_класс}
поле1
поле2
...
метод1
метод2
...
--------------- 'метка
секции1'
...
--------------- 'метка секции2'
...
END
*/ |
В одном файле располагается декларация одного класса.
Все прочие декларации (перечислимые типы, функции, константы, поля)
существуют только в пределах классах.
Глобальных (статических) полей классов не бывает, все поля являются
членами каких-либо экземпляров классов.
|
Syntax.
/*
CLASS
{names},
modifiers :
IMPORT: {Class1} ... ;
BASE CLASS {Base_class}
field1
field2
...
method1
method2
...
--------------- 'section
label1'
...
--------------- 'section label2'
...
END
*/ |
One file contains exactly one class definition. All other
declarations (enumerations, functions, constants, fields) are located
only in classes and belong them. The are no global (static)
class fields, all the fields are members of certain objects. |
- Код AL-IV всегда располагается
между строками с символами конца и начала
многострочного комментария /* и
*/.
- Имена классов заключаются в
фигурные скобки.
- Имя класса начинается с прописной буквы.
- Имя класса может разделяться на две части символом
'|'. До этого символа находится краткое
имя класса, после - длинное имя класса.
Например: {My|_class} определяет два имени
- краткое {My} и длинное
{My_class} для одного класса.
- Длинное имя должно быть не менее 8 символов (не считая фигурные
скобки).
- Имя файла класса (без расширения
класса) должно совпадать с длинным именем класса (без фигурных
скобок). Но нарушение этого правила не
вызывает ошибку, только предупреждение.
Основная часть декларации класса - это определения полей и
функций.
- Поля декларируются в форме
{тип}
имена = значение,
модификатор
- Тип - это один из системных простых типов
BOOL, BYTE, INT, REAL,
STR, либо имя класса в фигурных скобках
(начинается с прописной буквы), либо
имя перечисления или записи в фигурных скобках (начинается со строчной буквы).
- Если имена поля или метода начинаются
с прописной буквы, то имя - публичное.
- Со строчной буквы начинается имя скрытого поля или метода. Они
доступны в самом классе, и в наследниках
класса.
- Декларации в классе могут разбиваться на секции с помощью
оператора-разделителя:
----------- 'метка
разделителя'
- Внутри одной секции не должно быть более 7 полей.
- Декларация функции так же завершает текущую группу.
- Если правило "не более 7 полей в группе" не выполняется, модуль должен иметь модификатор
BAD.
|
- The AL-IV code is always located between lines containing
symbols of the end and the start of multi-line comments: /* and */.
- Class names are enclosed into
figure brackets.
- Class names always start from an uppercase letter.
- Class name can be separated onto two parts by the symbol '|'.
Before the symbol a short name of the class is defined, after the
'|' symbol - the rest of a long name of the class.
E.g.: {My|_class} defines short name {My} and full name {My_class}
for the same class.
- A long name must not be shorter then 8 characters.
- Class file name (w/o extension) should much the long class name
(w/o figure brackets). But violating this rule leads only to a
warning, not to an error.
The main part of a class declaration consists of declarations
of fields and methods.
- Fields of a class are declared in form
{type} names = value,
modifier
- Type - is one of system simple types
BOOL,
BYTE, INT, REAL, STR or a
class name in figure brackets (its name is starting from an uppercase
letter) or a enumeration or a record name in figure brackets (name is
starting from a lowercase letter).
- If field and method names are starting from an uppercase letter,
then the name is Public.
- If the first letter of a name is in lowercase then the name is
hidden. Such methods and fields are accessible only in the module
where the class is declared, and in inherited classes.
- Groups of declarations in a class can be separated onto sections
with a separator in form:
----------- 'separator label'
(at least two '-' signs)
- Each section should not contain more then 7 fields.
- Function declaration also ends a group of declarations.
- If the rule "maximum 7 fields in a section" is not satisfied,
then such class must be marked with a
modifier
BAD.
|
Для указания предка класса,
первым в классе после оператора
IMPORT записывается:
- Если конструкция
BASE CLASS ...
отсутствует, то класс не имеет предков, кроме общего для всех
классов предка - безымянного класса {}.
- Если в классе переопределяются методы предка, то все такие
переопределения начинаются словом
OVERRIDE:
OVERRIDE some_name(paramer) ==> result_type:
...
. |
- Для выполнения действий при создании каждого экземпляра класса,
после присваивания значений полей,
используется процедура
CONSTRUCT|ION
- Для выполнения действий при уничтожении объекта, используется
специальная процедура
- Если классы использует деструктор, то он
обязан иметь модификатор
DESTRUCTORS
в заголовке.
|
To
specify an ancestor for a class its declaration is written in a form
(immediately after IMPORT):
BASE CLASS <Base class name 1> |
- If a construction
BASE CLASS ... is absent, then
the class has no other ancestors except the common for all classes
unnamed class {}.
- If the are methods in a class which are overriding correspondent
methods of a base class then all those methods are declared starting
from a keyword
OVERRIDE:
OVERRIDE some_name(paramer) ==> result_type:
...
. |
- To assign other initial values to fields of a base class and to
do something else on a create time of an instance of a class, a
procedure is used
- To do something special when an object is destroyed, a procedure
is used
- If a destruction procedure is used in a class it is necessary
to add a modifier
DESTRUCTORS to the header of the
class.
|
| При переопределении метода в классе:
- Используется префикс
OVERRIDE
вместо METHOD.
- Указывается только одно имя метода.
- Перечисляются (в скобках, через запятую) все определения
параметров переопределяемой функции (должны совпадать первые буквы имен
соответствующих параметров). Типы
должны быть совместимы, размерности для
массивов - совпадать.
- Для методов, возвращающих значение:
- указывается тип
возвращаемого результата.
- Пример:
OVERRIDE FUN
enabled
==> BOOL :
RESULT = o.Edit1.Text != ""
.
Переопределённый метод может вызывать базовый метод (одноимённый
метод родительского класса).
- Для явного вызова базового метода в теле переопределённого
метода используется запись
BASE.
- При этом все параметры передаются обычным способом, в том числе
явно передаётся сам объект как неявный параметр:
BASE(параметры).
- Метод, не возвращающий значение, либо должен хотя бы раз вызвать
базовый метод (обычно, вначале), либо ему следует добавить
модификатор
REPLACE.
|
When a method is
redefined in a class:
- A prefix
OVERRIDE is used instead of the METHOD.
- Only one name of the method is specified.
- All the parameters of a base method are listed (in parenthesis, comma
separated). First letters of correspondent parameter names must
much. Types must be compatible by types and by dimensions (for
arrays).
- For methods returning a value:
- data type of a returning value is specified.
- An example:
OVERRIDE FUN
enabled ==> BOOL
: RESULT = o.Edit1.Text != ""
.
A redefined method can call a base method (the same named method of
the base class).
- To call explicitly a base method in a body of a redefined method
a syntax is used:
BASE.
- All the parameters are passing by a usual way, and the object
itself is passed implicitly as usual :
Base(parameters).
- A method not returning a value, should at least once call a base
method (usually, at the start), else it is necessary to add a
modifier
REPLACE to the overriding method.
|
Модификаторы для класса
записываются после имен класса ,
через запятые.
Имеются модификаторы:
ABSTRACT - класс
предназначен только для наследования новых классов на его основе,
создавать объекты этого класса нельзя.
BAD - класс не
выдерживает требований по оформлению кода (не более 3 параметров, не
более 3 уровней вложенности блочных операторов, не более 7 полей в
секции класса, не более 7 простых + 7 блочных операторов в секции
кода).
BITWISE - в классе
используется поразрядная логика.
BYTES - в классе
используются байты.
DESTRUCTORS - имеется
деструктор.
NATIVE - имеются "нативные"
функции.
RECURSIVE - имеются
рекурсивные фукции.
SHORT_STRINGS -
используются короткие строки.
STOPPING - используется
оператор STOP.
UNTESTED - есть не
оттестированный код.
SAFE - всё хорошо, класс
оттестирован, не содержит никаких замечаний по безопасности или
оформлению.
DEPRECATED('text') -
класс поддерживается, но его использование осуждается. В скобках и
апострофах указано, что использовать в качестве альтернативы.
Желательно как можно быстрее отказаться от использования этого
класса, т.к. в скором времени он может более не поддерживаться.
ABANDONED('text') -
использование этой версии класса запрещено. В скобках и кавычках
указано, что использовать в качестве альтернативы (не обязательно
это класс, возможно, технический приём, или поле другого класса).
Попытка объявить переменную с таким классом или функцию,
возвращающую объект такого класса (и любая другая ссылка на класс)
вызывает ошибку компиляции.
|
A modifier for a class is written following the class names. Such as:
ABSTRACT - the
class is intended only for deriving new classes on base of this
class, it is not allowed to create objects of the class itself.
BAD - the class is not satisfying requirements on
code style (not more then 3 parameters for a function, not more then
3 nesting levels of block statements, not more then 7 fields in a
section of a class, not more then 7 simple statement + 7 block
statements in a section of a block in a function code).
BITWISE - bitwise logical operations between
integer values are used.
BYTES - bytes are used in the class.
DESTRUCTORS - the class has a destructor.
NATIVE - there are native functions in the class.
RECURSIVE - there are recursive functions in the
class.
SHORT_STRINGS - strings with a modifier MAXLEN[n]
are used in the class.
STOPPING - a STOP operation is used in the class.
UNTESTED - there is an untested code in the class.
SAFE - all is OK, class is tested fully and there
are no warnings on a safety or style.
DEPRECATED('text') - the class is still supported
but its using is deprecated. The text in apostrophes contains
information about an alternative which should be used as soon as
possible still in future the class can become not supported.
ABANDONED('text') - the class is abandoned. Any
reference to it leads to a compilation error. The text contains
information about an alternative.
|
Переменная класса (экземпляр
класса) является объектом класса.
- Объекты класса декларируются
как переменные с именем класса в качестве типа данных.
Например:
{My_class} M|y_object = {My_class}
- Поле или переменная,
не имеющая в именах завершающего символа подчеркивания,
является удерживающей ссылкой объекта.
- Переменные_ с завершающим подчеркиванием в имени являются
слабыми ссылками и лишь ссылаются на существующие объекты.
- Слабая ссылка действительна лишь до тех пор, пока они
объект существует (на него ссылаются
переменные-сильные указатели, или жив владелец объекта).
- Все локальные переменные функций являются сильными ссылками.
Слабыми ссылками могут быть только поля класса.
- При обнулении счетчика использования сильными ссылками объект уничтожается. Все использующие переменные немедленно начинают ссылаться на
NONE.
- Если в момент создания объекта для него явно указан владелец (
OWNED
BY), то наличие сильных ссылок на него уже никак не
влияет на время жизни объекта: он будет уничтожен вместе со своим
владельцем, при этом все ссылки на него, сильные или слабые,
перенаправляются на NONE-объект.
NONE - объект - это
специальный объект класса, имеющий все поля равными
NONE (и 0 - для чисел, пустым
строкам - для строк, и т.д.). Запись в поля этого псевдо-объекта
игнорируется, чтение из его полей возвращает
NONE-значения, вызов методов не выполняет
никаких действий.
- Все объектные переменные (как сильные, так и слабые ссылки) изначально имеют значение
NONE, чтение за пределами
массива объектов так же возвращает NONE.
|
A variable of a class type (a class instance) is an object of the class.
- Objects are declared by specifying a correspondent class
name in figure brackets as a type name of the variable.
E.g.:
{My Class} M|y_object = {My_class}
- A field or a variable not having trailing underscore characters
in its names, is a keeping reference to an object.
- If an object_
name has a trailing underscore character, it is defined not to own an
object but to be just a weak reference to to another object.
- Such weak object reference variable links to it
just while it exist and there are object variables referencing such object
strongly (or an owner of the object still exists).
- All the local variables in a function are strong references
always.
- When a count of strongly referencing variables becomes zero, the
object is destroyed and all the weak pointers start pointing
to
NONE
value immediately.
- If at create time for an object an owner was specified
explicitly (
OWNED BY), then presence of strong references to it has
no effect: it will be destroyed together with its owner, and at that
moment all the references to it, either strong or weak will be
redirected to the NONE object.
NONE - is a special object of a class, having all the object
fields equal to NONE (and 0 for numbers, "" - for strings, etc.).
Writing to fields of such pseudo-object is always ignored, reading
is always returning NONE and 0 values, calling its methods does not
lead no any valuable operations.
- All the object variables initially are set to
NONE, and if an
object is read out of bounds of an array, also NONE is
returned.
|
ПРАВИЛО
- Поле FA класса
A, являющееся удерживающей ссылкой на объект, не может
иметь тип класса B,
являющегося предком по отношению к классу A.
- Если класс А имеет удерживающее поле класса
B, то класс B не может иметь
удерживающих полей
класса А
или классов, родственных
A по прямой линии (как предков, так и потомков).
- Если класс А1 содержит удерживающее поле класса А2,
класс А2
содержит удерживающее поле класса А3, и т.д.,
и класс А(n-1)
содержит удерживающее поле класса А(n), то класс А(n)
не может содержать удерживающих полей классов А1, А2, ..., А(n-1).
- В частности, объект не может ссылаться на объекты своего класса.
- В результате, невозможно создание цепочек взаимного владения.
- Одноранговые сети, графы, и т.п. организуются с помощью
слабых_
ссылок.
|
THE
RULE
- A
field FA of a class A which is a strong reference to an object can not
belong to a class B
which is a direct ancestor of
the class A.
-
If a class A has an object field of class B which is a
strong reference,
then the class B can not have object fields which are strong
references to class
A
or other
classes which are direct ancestors or inheritances of A.
- When a class A1 references strongly an object of a class
A2,
and the class A2 references strongly an object
of a class A3 and so on,
and a class A(n-1) references strongly an object of a class A(n),
then the class A(n) can not contain object fields which
are strong references to any of previous classes
A1, A2, ..., A(n-1).
- It is not possible to refer with a strong reference
to an object of the same class, in part.
- As a result, it is not possible to create circled chains of strong references
of objects to each others.
- Different kinds of peer
networks of objects, graphs, lists etc. can be easy formed using weak_
only pointers.
|
Вновь созданные объект должен быть
либо
присвоен внешней (по отношению к
функции)
объектной переменной без подчёркивания на конце имени (сильной ссылке),
либо добавлен во внешний массив сильных ссылок (операция
, >> массив[]),
либо через запятую должен быть указан объект-владелец вновь
созданного объекта, например, OWNED BY var_ref,
либо присвоен переменной, в имени которой присутствует строка
temp (в любом регистре, например,
Example|_TempVar).
- Переменная является внешней по отношению к функции, если она:
- либо является полем самого класса,
- либо является полем внешней переменной,
- либо является псевдо-переменной
RESULT,
- либо является полем переменной
RESULT,
- либо является полем объектного параметра.
- Если вновь созданный объект хотя бы раз в теле функции
присваивается переменной
RESULT, то
функция должны быть помечена маркером NEW.
- Функция с маркером
NEW может
вызываться только в отдельном операторе присваивания, как и для
оператора создания нового объекта. При этом вновь созданный такой
функцией объект так же должен быть присвоен внешней сильной ссылке
или temp-переменной.
- Для результата NEW-функции
не может быть применена конструкция
OWNED BY,
в отличие от прямого создания объекта.
|
Just created object should be either
assigned to an external (for a function) object variable
without an underscore at the end of its name (i.e. a strong reference to
it should be created),
or it should be added to an external array of strong
references (an operation , >> array[]),
or an owner object should be specified (an operation
, OWNED BY var_ref),
or it should be assigned to a (local) variable which has
substring 'temp' in its name (in any case, e.g.,
Example|_TempVar).
- A variable is an external to a function if it is:
- either is a field of the class itself,
- or it is a field of an external variable,
- or it is a pseudo-variable
RESULT,
- or it is a field of the
RESULT,
- or it is a field of an object parameter.
- If a newly created object at least once in a function body is
assigned to the
RESULT variable, then the function
should be marked as NEW.
- Function marked as
NEW can be called only in a
standalone statement like a statement where a new object is created
directly. And the new object created with a function marked as
NEW, also must be
assigned to an external variable, added to an external array or
assigned to a temporary variable.
- For a
NEW function result it is not allowed to use
OWNED BY
instruction.
|
|
Конструкция объекта: variable = {Class_name}(
Field1
= expression, Field2[] << expression, ...)
- Если значение присваивается переменной в операторе декларации
этой переменной (который начинается с указания типа переменной в
угловых скобках), и оператором создаётся объект именно этого типа,
то в декларации может быть опущено имя типа декларируемой
переменной:
stream|_read_temp = {File_stream}(
Path = source_path, Mode = 'READ')
- Если при создании объекта не требуется инициализировать поля, то
круглые скобки опускаются.
- Если за именем типа и списком инициализации следует через запятую запись
OWNED BY выражение, то тем
самым созданному объекту назначается исключительный владелец.
- Для такого объекта, счётчики использования строгими
указателями не влияют на время жизни объекта: он существует,
пока жив его владелец.
- Если на момент создания объекта
значение выражения в части
OWNED BY равно
NONE, то владелец не
назначается, и при отсутствии других строгих ссылок на него,
проживёт не долее, чем выполняется функция, в которой он создан.
- Либо далее может располагаться операция добавления созданного объекта
в один или несколько массивов объектов:
>>
переменная[].
- Создаваемый объект должен быть присвоен либо внешнему для функции объекту
(параметру или его полю, полю класса или его полю), или
добавлен во внешний по отношению к функции массив строгих ссылок на
объекты, либо ему должен быть назначен исключительный владелец (
,
OWNED BY). В противном случае, переменная, которой
присваивается созданный объект, должен иметь в своём имени подстроку
'temp'.
|
Object construction:
variable = {Class_name}(
Field1
= expression, Field2[] << expression, ...)
|
| Первым в классе
после заголовка должен быть указан оператор
IMPORT,
если он требуется. В операторе импорта перечисляются используемые
классы (в том числе родительский класс, если класс образован не от
базового класса {Object}).
IMPORT : {Класс1}, {Класс2},
... ; (В качестве
завершения блока IMPORT может быть точка или
точка с запятой). |
The first in a class
(following the class header) should be specified a statement
IMPORT if it is required. In an import statement classes are
listed which are used (including an ancestor class if the class is not
descending from the common class {Object}).
IMPORT : {Class1}, {Class2}, ... ;
(the semicolon or the dot can be used to end the IMPORT statement). |
| Если класс имеет
предка в иерархии, он должен быть указан оператором
BASE CLASS {Имя},
но после оператора импорта, в котором указывается класс предка.
Допускается форма с инициализацией полей:
BASE CLASS {Имя}(Поле1
= Значение1,
...
)
Для завершения оператора BASE CLASS
не используется специальный символ. |
If the class has an
ancestor in its hierarchy, this should be specified with the statement
BASE CLASS {Name}, but after the IMPORT statement where the
ancestor class is listed.
The BASE CLASS ... statement is not ended with a dot or
semicolon. |
| Завершается класс
оператором END в отдельной
строке. |
A class is always ended
with a standalone statement END located in a separate line. |
| До оператора
END могут встречаться:
- операторы определения перечислений
ENUM {имя|уточнение}
:
'НАИМЕН|ОВАНИЕ1'
'НАИМЕН|ОВАНИЕ2'
... .
- операторы описания структур (записей)
RECORD {имя|уточнение}
:
поле1
поле2
... .
- операторы описания таблиц
TABLE Имя|уточнение
: {запись}
NAME "имя"
COUNTER(список)
NOTNULL(список)
NAMES(поле = "имя",
...) .
- декларации полей
ТИП Имя|уточнение
[размер] = инициализация, модификатор
- деклараци
я конструктора
CONSTRUCT :
ТЕЛО .
- декларация
деструктора
DESTRUCT :
ТЕЛО .
- декларации статических функций
FUNCTION Имя|уточнение(параметры)
==> ТИП_РЕЗУЛЬТАТА,
модификатор1, модификатор2,
... :
ТЕЛО .
- декларации
методов
METHOD Имя|уточнение(параметры)
==> ТИП_РЕЗУЛЬТАТА,
модификатор1, модификатор2,
... :
ТЕЛО .
- декларации переопределённых функций
OVERRIDE Имя(параметры)
==> ТИП, модификатор1, ...
:
ТЕЛО . - функции тестирования
TEST Имя|уточнение(параметры)
==> ТИП_РЕЗУЛЬТАТА :
ТЕЛО .- блочные комментарии
--------------------------- 'текст'
- директивы NATIVE
NATIVE: "код
специфичный для
платформы" .
- операторы TODO
TODO: "строка" .
|
Before the END
statement following statements/blocks can be found:
- enumeration declarations
ENUM {name|detailed} :
'NAME|DETAILED1'
'NAME|DETAILED2'
... .
- structure definitions
RECORD {name|detailed} :
Field1
Field2
... .
- table definitions
TABLE Name|detailed : {запись}
NAME "name"
COUNTER(list)
NOTNULL(list)
NAMES(field = "name", ...) .
- field declarations
TYPE Name|detailed [size] = initialization, modifier
- constructor declaration
CONSTRUCT:
BODY .
- destructor declaration
DESTRUCT:
BODY .
- static functions declarations
FUNCTION Name|detailed(parameters) ==> RESULT_TYPE, modifier1,
modifier2, ... :
BODY .
- methods declarations
METHOD Name|detailed(parameters) ==> RESULT_TYPE, modifier1,
modifier2, ... :
BODY .
- overridden methods
OVERRIDE Name(parameters) ==> TYPE, modifier1,
... :
BODY .
- test functions
TEST Name|detailed (parameters) ==> TYPE :
BODY .
- block comments
--------------------------------- 'text'
- native code directives
NATIVE: "code specific for a platform" .
- to-do statements
TODO "text" .
|