$$OUT=-

$$START!

## I. Синтаксис операторов | ## I. Syntax

### I. 1. Форматирование операторов | ### I. 1. Formatting statements

#### I. 1. a. Один оператор - одна строка | #### I. 1. a. Continue statement lines

Простые операторы не требуют завершения специальным знаком (таким, как '`;`'). Знак '`;`' используется для завершения блока. Например: `d|escriminant = B * B - 4 * A * C CASE d.Sign ? [-1]: NONE [0] : R[] << -B / 2 / A [+1]: R[] << (-B - d.Sqrt) / 2 / A R[] << (-B + d.Sqrt) / 2 / A ;` | Statements need not any finalization symbol (like '`;`'). Symbol ';' is used to finish a block of statements. E.g.: `d|escriminant = B * B - 4 * A * C CASE d.Sign ? [-1]: NONE [0] : R[] << -B / 2 / A [+1]: R[] << (-B - d.Sqrt) / 2 / A R[] << (-B + d.Sqrt) / 2 / A ;`

Строка не может быть длиннее 80 символов (не учитывая комментарии до конца строки и пробельные символы в конце строки). Символ табуляции считается за один символ. Оператор может быть записан в нескольких строках, но строка считается продолжающейся на следующую только если: строка заканчивается символами ',', '(', '['; следующая строка начинается символами: '"' (двойная кавычка - начинает строчную константу) '+' '-' (одинарный знак минус) '*' '/' '%' '|' '&' '>' '=' '#' | A line of a code should not exceed 80 characters (without ending comments and spaces and tabulations). Statement can be continued in several lines only in following cases: a line is finished with ',', '(', '['; the next line is starting with one of symbols (without quotas): '"' (double quotas - starts string constant) '+' '-' (single only, not '--') '*' '/' '%' '|' '&' '>' '=' '#'
Другой способ запомнить правило переноса: строка считается продолжающейся на следующую только если или предыдущая строка завершается символами '(', '[', ',' или следующая строка не пуста и не может начинать новый оператор, т.е.: не начинается с буквы, с символа '{' (не начинает декларацию именем типа в фигурных скобках), с символа '[' (не является условием для ветви CASE), с символа '<' (не начинает оператор вывода <<), с символов '.' или ';' (не является отдельно стоящим символом для завершения блока кода или функции) с символа '--' (не начинает блочный комментарий). | Another way to remember the rule is that a statement is continued only if: either the previous line is finished by one of symbols '(', '[', ',' or the next line is not empty and it can not a start of a new statement, that is, it is not start from: a letter, a symbol '{' (a variable declaration can start from a type name in figure brackets), a symbol '[' (not a condition for a CASE statement), a symbol '<' (an output statement can start from a symbol '<<'), symbols '.' or ';' (it is not a separate ending of a code block or a function), a symbol '--' (so it is not a block comment -------------- 'text').

#### I. 1. b. Блочные операторы | #### I. 1. b. Block statements

Блочные операторы создают вложенный уровень операторов. Блок вложенных операторов завершается символом ';'. Функции и другие блоки уровня класса завершаются символом '.' (точка). А именно: заголовок класса, список импорта, определение типа перечисления, определение блока констант. Строка не может завершаться двумя и более подряд одинаковыми символами завершения ';' или '.'. Но сочетание '; .' для завершения последней блочной конструкции в функции и самой функции допускается. Если завершения требуют более двух блоков операторов, то у символ завершения для внешнего блока будет находиться на отдельной строке. Например: | Block statements always are starting in a new line. Nesting statements block is ended with the symbol ';'. Functions and other blocks of a class level are ending with a symbol '.'. Such blocks are: a class header, an import list, enumeration declaration, constants definition block. (Though it is allowed to use ';' for an import list, too). The last line in a nested block can not be ended with two same ending symbols ';' or '.'. But it is allowed to end nesting block with its upper leveled function by two symbols '; .' at the end of the last line in the function. So, if it is required to finish two nesting blocks, then the ending symbol of the external block will be placed in a separate line of code. E.g.:

`FOR i IN [1 TO 100] : ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ CASE i % 3 == 0 ? << "Fizz" ; ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ █ CASE i % 5 == 0 ? << "Buzz" ; ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ █ CASE i % 3 != 0 && i % 5 != 0 ? << i.Str ; ▄▄▄▄ █ ; ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█`

Имеется только одно ключевое слово для условного оператора (`CASE`), одно для оператора цикла (`FOR`), один оператор сохранения и гарантированного восстановления (`PUSH`). Для отладки кода может использоваться блочный оператор `DEBUG` . Все прочие операторы являются простыми: `BREAK`, `CONTINUE`, `STOP`, `LIKE`, `REVERT`, вызовы функций, декларация и модификация переменных, ввод и вывод (>>, <<). Оператор`BREAK` может использоваться только для прекращения цикла и не используется для других целей. | There is only a single keyword for a conditional statement (`CASE`), a single keyword for a basic loop statement (`FOR`), a single save and restore statement (`PUSH`). For debugging, special blocks `DEBUG` can be used also. All other statements are simple: `BREAK`, `CONTINUE`, `STOP`, `LIKE`, `REVERT`, function calls, variable declarations and modifications, input and output (>>, <<). The `BREAK` statement can be used only to exit a `FOR` loop and not for any other purposes.
Компилятор требует помечать маркером `BAD` классы, в которых не соблюдаются правила структурирования кода: Количество вложенных уровней операторов `CASE` и `FOR` не должно превышать трёх (блоки `PUSH` / `DEBUG` не учитываются). Количество простых операторов в блоке не должно превышать семи. Количество вложенных блочных операторов в блоке так же не должно превышать семи. Специальный оператор-комментарий вида `------------------------------- '`текст комментария' может разделять группы операторов (число знаков '-' произвольно, но не менее двух), в этом случае подсчёт ведётся только внутри группы. | A compiler requires to mark with a modifier `BAD` classes in which rules of code structuring are not satisfied: Number of nested levels of block statements `CASE` and `FOR` should not exceed 3 (blocks `PUSH` / `DEBUG` are not considered). Number of simple statement in a section of a block should not exceed 7. Number of nested block statements in a section of a block also should not exceed 7. A special block comment `-------------------------------- 'text'` can separate groups of statements (number of signs '-' at least 2) treated as sections in a block.

#### I. 1. c. Комментарии | #### I. 1. c. Comments

Многострочные комментарии `*/` ... `/*` начинаются в начале строки (не считая начальных пробелов) с символов `*/ и заканчиваются строкой, завершающейся символами /*` Текстовой файл, содержащий исходный код, считается всегда начинающимся с многострочных комментариев. Признаком завершения таких комментариев является строка, завершающаяся символами `/*`. Т.е., код AL-IV всегда должен находиться между строками `/*` и `*/` (как если бы он был комментарием для C-подобного языка программирования). Комментарии до конца строки, начинающихся с двойной дроби (`//`). Не завершают текущий оператор. Комментарии, начинающиеся двумя символами --, имеют форму `-------------- 'текст'` и служат для разбиения блоков на разделы. Так же, используются в декларациях классов и в оглавлении модуля. Такой блочный комментарий может начинать переиспользуемый блок кода (операторы `LIKE`, `REVERT`). В этом случае он должен иметь модификатор REUSED (записывается через запятую после метки). Например: `---------------- 'start extracting', REUSED` | Multi-line comments `*/ ... /*`, starting brackets are always placed at the begin of a line (may be following leading spaces) from the symbol `*/ and finishing with a string started from symbols /*` A text file containing the AL-IV source code is always treating to be started from multi-line comments. A line containing at the end the symbol `/*` becomes the end of such leading comments lines. I.e. the AL-IV code should be located always between lines with symbols `/*` and `*/` (as it would be comments for some C-like programming language around). Comment to the end of line (starting from `//`). Such comments do not finish current statement. Comments starting with two minuses: `----------- 'text'` are used to separate blocks of code onto sections. These also are used in class declarations and in module headers. A block comment statement can start a reused block of code (in statements `LIKE` / `REVERT`). In such case it should have a modifier REUSED (which is written after the label comma separated). E.g.: `--------------- 'start extracting', REUSED`

#### I. 1. d. Регистрозависимость для идентификаторов | #### I. 1. d. Case sensitivity for keywords, types and other identifiers

К ЛЮЧЕВЫЕ И ЗАРЕЗЕРВИРОВАННЫЕ СЛОВА записываются только в ВЕРХНЕМ регистре.`CASE` являются ключевым словом, но `Case`, `case` - нет. | K EYWORDS can be written in the UPPER case only. `CASE` if a keyword but `case`, `cAsE` and `Case` - not.
{Имена классов} (а так же перечислений и записей) заключаются в фигурные скобки. имена простых типов данных являются зарезервированными: `BOOL`, `BYTE, INT`, `REAL`, `STR` (и других простых типов, кроме этих пяти, нет). {Имена классов} начинаются с прописных букв: `{My_class}`, {Car|_mobile}. {имена_перечислений_и_записей} начинаются со строчной буквы: `{color|s_fill}`. Имена типов образуют особое пространство имен, не пересекающееся с прочими именами (переменных, констант, функций, процедур, модулей). | {Type names} are enclosed into figure brackets. simple type names are reserved keywords: BOOL, BYTE, INT, REAL, STR (and there no simple types except these 5 listed here). {Class names} are starting from uppercase letters. {enumeration_and_record} names are starting from lowercase letters. Type names create a name space not intersecting other names at all.
Рекомендуется использовать КАПИТАЛИЗИРОВАННЫЕ имена для констант. | CONSTANT names are case sensitive. It is desired to be written CAPITALIZED.
Имена 'КОНСТАНТ', являющихся элементами перечислений и коллекций, всегда заключаются в апострофы. | Names of 'CONSTANTS' which are items of enumerations and collections are always enclosed into apostrophes.
Все имена регистро-зависимы. Например, A и a - это разные переменные (или константы). Имена Публичных полей, функций, параметров функций начинаются с Прописной буквы. Члены класса, имена которых начинаются со строчной буквы, локальны в классе (но доступны в его наследниках). Локальные переменные функций рекомендуется именовать со строчной буквы, параметры функции - с прописной. Символ подчеркивания в конце имени_ является неотъемлемой частью имени (и служит атрибутом слабой ссылки для объектов). | Variable and field names (of structures and classes) are case sensitive. So, A and a are different variables (or constants). Names of Public fields, functions, variables, types are always starting from a capital letter. All other names are local in a module. (This does not concern local variables which are always local in its functions and can be written from any case). The underscore at the end of a name_ is an integral part of the name (and used as a marker of a pointer to a structure or of a weak pointer to an object).

#### I. 1. e. Именование | #### I. 1. e. Naming
При декларации переменной, функции, типа данных сущности может быть дано два имени - краткое и полное. Сначала записывается краткое имя, затем, через символ '|' - остальная часть имени. При этом: Длина полного имени должна быть не менее 8 знаков: `S|ample_val` Только одно исключение: переменные цикла могут иметь только краткое имя: `FOR x IN M[] : ... ;` Если имя должно заканчиваться символом подчёркивания (признак слабой ссылки), то подчёркиванием должны заканчиваться обе части имени, например: `List_|of_items_[]` Для имён классов, записей и перечислений действует то же правило, и при подсчёте длины имени окружающие фигурные скобки не учитываются: `{My_class|_to_do_something}` | While declaring a variable, a function, a data type, those things can have two names - a short and a long. The first the short name is written, then, if present, a long name is following separated by the symbol '|'. So there are following rules: The whole name length should not be less then 8 characters: `S|ample_val` Only one exclusion for variable names: FOR loop variables can have only short name, even short, e.g.: `FOR x IN M[] : ... ;` If a name should be finished by an underscore character (which is a mark for a weak reference in the AL-IV), then both variants of the name should be ended with the underscore, e.g.: `List_|of_items_[]` For class names, records and enumerations the same rule is active, and figure brackets are not accounting in names lengths: `{My_class|_to_do_something}`

#### I. 1. f. Модификаторы | #### I. 1. f. Modifiers
Многие декларации языка (заголовок модуля, оператор, декларация переменной или типа данных) могут иметь модификаторы. записываются в форме `, ИМЯ` в конце оператора (или декларации), к которому относятся. Если модификаторов несколько, то они перечисляются через запятые. Например, в заголовке класса: `CLASS {My|_class}, BITWISE, RECURSIVE :` | Many language declarations (module header, statement, variable of data type declaration) can have modifiers. Modifiers are written in form `, NAME` at the end of a declaration (usually). If there are several modifiers then these are listed via ','. Modifiers are written in the upper case. E.g.: `CLASS {My|_class}, BITWISE, RECURSIVE :`
Модификаторы не воздействуют на основную семантику кода. Они лишь помогают компилятору в обеспечении большей надежности, и иногда помогают оптимизировать результирующий код. Если в готовой программе, не содержащей ошибок, убрать все модификаторы (полагая, что в языке они не требуются), это не изменит результат работы программы (но может повлиять на размер кода и скорость работы в сторону увеличения или уменьшения). | Modifiers do not affect main code semantics. These just help to compiler to provide more security and sometimes help to optimize resulting code. If to remove all modifiers in a ready program (and suppose that a language do not require it), this do not change a result of the program (but can take an effect of changing its size / working speed, either increasing or decreasing it).

### I. 2. Оператор присваивания | ### I. 2. Assignment

#### I. 2. a. Простой оператор присваивания | #### I. 2. a. Simple assignment statement

`x = y`
где `x` - переменная или поле структуры или объекта, `y` - выражение. |
`x = y`
where `x` is a variable or a field of a structure or an object and `y` is an expression.
Для сравнения на равенство двух операндов используется си-подобный оператор `==`. | To compare for equality of two operands a "C"-like operator `==` is used.

#### I. 2. b. Операторы присваивания в комбинации с арифметической, логической или поразрядной логической операцией | #### I. 2. b. Assignment in combination with arithmetic, logic or bitwise operation

Дополнительные операции `+=`, `-=`, `*=`, `/=`, `%=`, `|=`, `&=`, `^=`, `||=`, `&&=`, могут использоваться как эквивалент присваивания результата соответствующей операции `+`, `-`, `*`, ... между переменной, которой присваивается результат, и выражением справа от знака операции. | Additional operations `+=`, `-=`, `*=`, `/=`, `%=`, `|=`, `&=`, `^=`, `||=`, `&&=` can be used as an equivalent of the assignment of a result of a correspondent operation `+`, `-`, `*`, ... between the variable left to the symbol of the operation and the right-sided expression.

#### I. 2. c. Операторы отправки данных | #### I. 2. c. Data sending operations

Операция `<<` используется для добавления строки к строке, элемента к массиву и вывода текста в текущий главный поток вывода. Для строковой переменной `A` и строкового выражения `B` запись `A << B` эквивалентна оператору присваивания вида `A = A B` в случае массива `A[]` и выражения `B` запись `A[] << B` эквивалентна вызову функции `A[].Add(B)` для массива. Если левый операнд не указан, то это оператор записи строки в выходной поток (в консоль - для консольной программы). | Operation `<<` is used to append a string to a string or to append an item to an array, or to output text to a current output console. For a string variable `A` and a string expression `B`, a statement `A << B` is equal to `A = A B` In case of an array `A[]` and an expression B, statement `A[] << B` is equal to a function call `A[].Add(B)` If the left operand is not present, then such statement means writing a string to an output stream (to the console for a console application).

Аналогичная операция `>>` используется как замена вызова функции read для операнда слева (а так же для добавления нового объекта в массив объектов, см. в разделе, посвященном классам и объектам). Операторы ввода-вывода `<<` и `>>` могут комбинироваться в одном операторе в виде `<< строка [>> переменная] [>> переменная] ...` Например: ``<< 'Введите число:' >> Number`` | A similar operation `>>` is used as a replacement of a call of a function read for the left operand as a source (and also to add a newly created object to an objects array, see in a section devoted to classes and objects). Input-output operators `<<` and `>>` can be combined in a single statement in a form: `<< string [>> variable] [>>variable] ...` E.g.: `<< 'Enter number:' >> Number`

#### I. 2. d. Операторы повторного присваивания и отправки данных | #### I. 2. d. Repeating assignment and sending data operators

Если оператор начинается с символа `'..'` (без кавычек), то это ссылка на левую часть предыдущего оператора присваивания (или на зафиксированную левую часть присваивания). Соответственно, три точки подряд означают такую ссылку с последующей операцией обращения к полю или методу объекта, или обращения к функции с указанным операндом в качестве первого параметра. Для такого повторного присваивания (или отправки данных): не ведется подсчет операторов (нет ограничения на количество таких повторных присваиваний); выражение фиксируется в качестве левой части для последующих "повторных" присваиваний: если употреблено в левой части обычного оператора присваивания(a = b, a += b, a *= b, и т.п.); является левой частью обычного оператора отправки данных (a << b, a[] << b, в том числе в случае, когда оператор '<<' заменяет вызов метода Write); если в операторе в цепочке разыменования полей/методов использован псевдо-оператор '...' в позиции одинарной точки (например: `A.Field1[indexA]...Do_something(params) ...Color = RED ...Foo(params)` В приведенном примере в двух последних строчках`` символ '..' замещается компилятором выражением `A.Field1[indexA]` | If a statement is starting from a symbol `'..'` (without quotas), then this represents a reference to the left side of the previous assignment statement. So, three dots are meaning such reference with a following "dot operation" used to either name a field or a method of an object or to name a function giving the operand referred by the `'..'` symbol as the first parameter. For such repeating assignment statement (or data sending statement): statements are not counting as simple or nesting (there are no restrictions on such repeating assignments); an expression is fixed to be a destination for following repeating assignments if: it is used as the left side of a usual assignment (a = b, a += b, a *= b etc.); it is used as a destination in a usual sending data statement (a << b, a[] << b), including a case when the sending operator is replacing a method Write call; if a pseudo-operator '...' is used in place of a single "dot" operation in a chain of unnamings/indexation operations applied to an expression. E.g.: `A.Field1[indexA]...Do_something(params) ...Color = RED ...Foo(params)` In the example above, in two last lines, the symbol '..' is replaced by a compiler with an expression `A.Field1[indexA]`

#### I. 2. e. Операторы инкремента и декремента | #### I. 2. e. Increment and decrement

Операторы `++` и `--` могут использоваться для целочисленных переменных в постфиксном виде: как отдельные операторы, либо внутри индексов массивов, и в других частях выражений. Изменение значения переменной гарантируется только по окончании выполнения всего оператора. Изменение одной и той же переменной несколько раз операциями ++ / -- в одном операторе считается ошибкой. Не разрешается использовать операции ++/-- в выражении с условно вычисляемыми частями (имеющими операции && / ||). | Operators `++` and `--` can be used for integer variables in a postfix form: as separate statements or in array indexes in other parts of expression. Changing the variable value is provided only after the statement is executed. Changing the same variable more then once via ++ / -- in a single statement is not allowed. It is not allowed to use operations ++/-- in an expression containing also operations && / ||.

### I. 3. Выражения | ### I. 3. Expressions

Операция | Расшифровка | Группа
- | Взятие обратного знака | Арифметика (чисел), на выходе число
* / % | Умножение, деление, остаток от деления
+ - | Сложение, вычитание
IN !IN | Проверка на вхождение значения в диапазон или массив | Сравнение чисел, строк, классов, результат булевское (для ?? - целое)
< <= > >= == != | Сравнения
~ | Поразрядное отрицание | Поразрядные операции с целыми, результат - целое
& ^ | И, Исключающее или (xor) - поразрядные
| | ИЛИ поразрядное
! | Логическое НЕ | Логические операции (с булевскими, результат - булевское)
&& | Логическое И (&&)
|| | Логическое ИЛИ (||)
Операция конкатенации строк не имеет специального знака. Используется пробел. При наличии поразрядных логических операций в модуле в список модификаторов модуля добавляется `BITWISE`. смешение поразрядных и арифметическх операций в одном выражении недопустимо. побитовые операции сдвигов реализуются с помощью встроенных функций `ShiftL|eft`, `ShiftR|ight`, `RotateL|eft`, `RotateR|ight` - отдельные знаки бинарных операций для этого отсутствуют. |
Operator | Description | Group
- | Negation | Arithmetic operations (with numbers), result is a number
* / % | Multiplication, division, rest of division
+ - | Adding, subtracting
IN !IN | Check for presence a value in a set or array, check for an object belonging to a class | Comparing numbers, strings, classes, result is Boolean or integer (for ??)
< <= > >= == != ?? | Compares
~ | Bitwise NOT | Bitwise operations with integers, result again is integer
& ^^ | Bitwise AND, eXclusive OR (xor)
| | Bitwise OR
! | Logical NOT | Logical operations with Boolean, result also is Boolean
&& | Logical AND (&&)
|| | Logical OR (||)
~ | Internal assignment | Always in form (expression ~NName)
Concatenation operation has no special sign (use space). If any bitwise operations are used in a module, then a modifier `BITWISE` must be added for the module. Using both bitwise and arithmetic operations in the same expression is not allowed. bitwise shift and rotate operations are implemented with embedded functions`ShiftL|eft`, `ShiftR|ight`, `RotateL|eft`, `RotateR|ight`, there are no separate binary operation signs for them.

#### I. 3. a. Операторы проверки наличия | #### I. 3. a. Checking conains of an item

Операторы `IN` и `!IN` могут использоваться в выражениях: для проверки наличия скалярного значения в массиве (при этом массив может быть переменной или конструкцией вида [ значение1, значение2, ..., значение3 ]) для проверки наличия подстроки в строке. В случае конструируемого массива, список значений должен содержать только константы. В этом случае, когда тип проверяемого значения - строка, не допускается конструировать массив из единственного элемента. Либо справа должна быть строка, а не массив. Операция IN/!IN не применима к паре вещественное число - вещественный массив (так же как запрещено сравнение на равенство значений типа REAL). | Operators `IN` and `!IN` can be used in expressions: for checking if a scalar value is present in an array of values (and an array to the right can be either an array variable or a construction in form [ value1, value2, ..., valueN ]) to check is a substring is present in a string. In case of a constructed array, all its items must be constant expressions. And in case when the left value is a string, it is not allowed to construct an array from a single string value. Either a string should be to the right of IN / !IN ( the case 2). Operations IN / !IN are not applicable to REAL numbers (still it is not allowed to compare REAL values for equality/inequality).

### I. 4. Прочие простые операторы | ### I. 4. Other simple statements

Для возврата из функции до окончания ее кода используется оператор возврата `==>` . Такой оператор может записываться отдельно либо следом за другим простым оператором в той же строке, образуя простой оператор с выходом из функции. Например:``CASE R > 0 ? RESULT = R ==> ; ▄▄▄▄`` | To return from a function before its code ends, a statement `==>` used. Such statement can be written either separately or following another simple statement (in the same line of code). E.g.: `CASE R > 0 ? RESULT = R ==> ; ▄▄▄▄`
Для завершения и продолжения цикла `FOR` используются операторы `BREAK` и `CONTINUE`, для которых обязательно указывается переменная цикла, Например: `FOR x IN [1 TO 100] : ▄▄▄▄▄▄▄▄▄▄▄▄▄▄ do_something █ CASE condition ? BREAK x; ▄▄▄▄ █ ; ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█` В бесконечном цикле `FOR` (с модификатором `INFINITE`) нельзя использовать операторы `CONTINUE` и `BREAK`. Завершить такой цикл можно только выходом из функции (оператор `==>`) или в результате срабатывания исключительной ситуации. Наличие метки в операторах `BREAK` / `CONTINUE` позволяет продолжить или остановить внешний цикл из тела вложенного напрямую. | To terminate or continue a loop, keywords `BREAK` and `CONTINUE` are used, together with a loop label, e.g.: `FOR x IN [1 TO 100] : ▄▄▄▄▄▄▄▄▄▄▄▄▄▄ do_something █ CASE condition ? BREAK x; ▄▄▄▄ █ ; ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█` It is not allowed to use `BREAK` / `CONTINUE` in an infinite `FOR` loop (having the modifier `INFINITE`). It is only possible to terminate such infinite loop by the return statement (`==>`) or in result of an exception firing. Using a label in `BREAK` / `CONTINUE` statements allows to continue or terminate an outer loop from an inner loop directly.

### I. 5. Условный оператор CASE | ### I. 5. Conditional statement CASE

Выражение в операторе `CASE` должно иметь значение булевского, целочисленного, перечислимого или строкового типа. Выражения других типов (вещественных или объектных) не допускаются. Заголовок всегда завершается знаком '`?`'. В случае булевского типа условия, немедленно начинается блок кода, который выполняется при выполнении условия. И за ним может следовать блок `ELSE` (см. ниже). В остальных случаях, каждая ветвь начинается с массива иди диапазона значений в квадратных скобках `[массив значений]: код` В качестве значений должны использоваться целочисленные, строчные или перечислимые константные значения (литеральные или именованные константы), тип значений которых соответствует типу выражения в заголовке. Значение в списке значений может быть одиночным или представлять диапазон значений в виде `X TO Y`, где X и Y - константы (только для целочисленного условия). Повторение значений (и пересечение диапазонов) не допускается. В случае перечислимого типа условия, должны быть перечислены все значения соответствующего перечислимого типа, и не может использоваться ветвь `ELSE`. Общая ветвь `ELSE` выполняется (при её наличии), если ни одна из констант не совпала, и ни одна из ветвей не была выполнена. Символ ';' завершает весь оператор `CASE`. Оператор `BREAK` не используется для завершения ветви. По исполнении любой ветви всегда происходит выход из всего оператора `CASE`. | An expression in the `CASE` statement should be of Boolean, integer, enumerated or string type. Expressions of other types (e.g., `REAL`, record, objects, etc.) are not allowed. The header is always finished by the symbol '`?`'. In case of the Boolean condition, a block of code follows which is executed in case when the condition is true. And an `ELSE` block can be following (see below). In other cases each branch is starting from a constant array of constant values in square brackets: `[array of values]: code` Constants (literal or named) should be listed in the array having a type correspondent to the type of the condition in the header. The value can be a single, or it can be represented with a list of values, or by a range `X TO Y` (which is allowed in case of integer condition). All the items in all sets or arrays must be distinct. In case of enumerated condition, all the enumeration items must be listed in arrays starting branches, and in such case it is not allowed to use ELSE branch. If a common part `ELSE` is present, it is executed if the expression in the header were not matching any constant listed, and there was no a branch executed. A BREAK statement is not used to finish a branch. After any branch execution entire `CASE` statement is finished.
Классический пример - решение квадратного уравнения в области вещественных чисел: | Classic example - solving a square equation for real numbers:

`RECORD {roots_sq|uare_equation} : INT N|umber_solutions REAL X1|_solution REAL X2|_solution . FUNCTION Square_eq|uation( REAL A|_coefficient, REAL B|_coefficient, REAL c|_coefficient) ==> {roots_sq}, STATIC : -------------------------------- 'direct version' CASE A == 0 ? ==> ; ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ REAL d|escriminant = B * B - 4 * A * C CASE d.Sign ? [0]: RESULT.N = 1 ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ RESULT.X1 = -B / (2 * A) █ RESULT.X2 = RESULT.X1 █ [1]: d = d.Sqrt █ RESULT.X1 = (-B - d) / (2 * A) █ RESULT.X2 = (-B + d) / (2 * A) █ RESULT.N = 2 ; . ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█`

Особый вариант оператора `CASE ?` - без условия вообще, может использоваться для последовательного перебора вариантов, вычисляющихся последовательно, до первого выражения в квадратных скобках, получившего значение `TRUE`. После чего либо выполняется соответствующая ветвь, либо, если истинное условие не обнаружено, то срабатывает блок `ELSE` (при его наличии). Синтаксически такой вариант оператора `CASE` отличается так же тем, что после каждого выражения в квадратных скобках записывается знак '`?`' (а не двоеточие, как в случаях выше). | Especial version of the `CASE ?` statement - with a condition in the header but with sequential calculation of conditions in square brackets until either the first one is found with value `TRUE` (in such case a correspondent branch is executed only), or until the `ELSE` part (or the end of the `CASE` statement) is found. In such case symbols '`?`' are written after each expression rather then ':'.

`FUNCTION Square_eq2|uation( REAL A|_coefficient, REAL B|_coefficient, REAL c|_coefficient) ==> {roots_sq}, STATIC : ----------------------- 'sequentional version' REAL d|escriminant = B * B - 4 * A * C CASE ? ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ [A == 0] ? ==> █ [d == 0] ? RESULT.N = 1 █ RESULT.X1 = -B / (2 * A) █ RESULT.X2 = RESULT.X1 █ [d > 0] ? d = d.Sqrt █ RESULT.X1 = (-B - d) / (2 * A) █ RESULT.X2 = (-B + d) / (2 * A) █ RESULT.N = 2 ; . ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█`

### I. 6. Операторы цикла FOR | ### I. 6. FOR loop statements

Оператор цикла `FOR` с перечислением элементов массива - это единственный вариант контролируемого цикла: ``FOR переменная IN массив[] : тело ; ▄▄▄▄`` | A loop statement `FOR` enumerating array items - is a single possible controlled loop statement: ``FOR variable IN array[] : body ; ▄▄▄▄``
Переменная такого цикла всегда имеет тип, совпадающий с типом элементов перечисляемого массива. Такая переменная: Не требует декларации. Не требует длинного синонима. Не может использоваться вне цикла, кроме как в другом цикле `FOR`. Используется как метка операторов `BREAK имя` и `CONTINUE имя`. Переменная цикла `FOR` с диапазоном значений не может быть изменена в теле цикла. В цикле перечисляются все элементы с индекса 0 до индекса `*` ((индекс последнего элемента в массиве). Для изменения границ перечисления и направления перечисления следует в качестве массива использовать конструируемый с помощью диапазона массив целых в форме `[X TO Y]` или `[Y DOWNTO X]`, где X и Y - целочисленные выражения. К переменной цикла применима псевдо-функция `Index`, возвращающая целочисленный индекс элемента в массиве. Границы перечисления индексов вычисляются до начала цикла, и изменение размера динамического массива в процессе работы цикла не влияют на порядок просмотра индексов. Это может приводить к выходу индекса за границы массива, в результате чего переменная цикла будет получать значение `NONE`. | The loop variable of such loop statement is always has the same type as a enumerating array items data type. It: Does not require declaration. Does not require a long synonym. Can not be used out of the loop, except in another `FOR` loop. It is used as a label in statements `BREAK variable` and `CONTINUE variable`, related to the loop. It is possible to apply an embedded function `Index` to it (it returns an index of the variable in the enumerating array). By default, all the items are enumerated from the starting to the ending. To indexes change direction and bounds, it is necessary to use a constructed array `[X TO Y]` or `[Y DOWNTO X]`, where X and Y - are integer expressions. A variable of a `FOR` loop with a range can not be changed in a loop body (and used as a usual variable). Bounds of indices enumerating are calculated before the loop, and even if size of an array is changed during a loop, this does not affect enumerated indices. As a result, this can lead to violating array bounds, and an array variable will be set to `NONE` in such cases.

Для организации неконтролируемого бесконечного цикла используется блочный оператор `FOR, INFINITE : тело цикла ; ▄▄▄▄` Такой цикл может быть завершён только оператором выхода из функции `==>`. Операторы `BREAK` и `CONTINUE` не используются. Класс, в котором встречается бесконечный цикл, должен быть отмечен маркером `INFINITIVE`. | To create an unguided infinitive loop, a special block statement is used: `FOR, INFINITE : loop body ; ▄▄▄▄` The `FOREVER` loop can be terminated only by a return from the function statement `==>`. Statements `CONTINUE / BREAK` can not be used. A class where infinite `FOR` statements are used, must be marked with a modifier `INFINITIVE`.

### I. 7. Блок операторов PUSH | ### I. 7. PUSH statements block

Предназначен для гарантированного сохранения некоторой переменной или поля с одновременным присваиванием ему нового значения на время выполнения блока, с последующим гарантированным восстановлением значения этой переменной или поля по окончании исполнения блока. Восстанавливающие действия гарантируются в том числе: При выполнении принудительного выхода из блока из-за срабатывания операторов `BREAK`, `CONTINUE`. При выходе из функции оператором возврата `==>`. Синтаксис: `PUSH переменная = выражение : тело ; ▄▄▄▄` или `PUSH переменная : тело ; ▄▄▄▄` | A `PUSH` statement is purposed to create procedural "brackets" with saving some state before and obligatory restoring this state after the block. Restoring is always guaranteed: When the block is left by a `BREAK` / `CONTINUE` statement. When a function is left by a `==>` (return) statement. Syntax: `PUSH variable = expression : body ; ▄▄▄▄` or: `PUSH variable : body ; ▄▄▄▄`
На входе в такой блок значение переменной сохраняется (например, в локальном стеке, или в локальном динамическом массиве). После чего ей присваивается новое значение (если указано). При достижении завершающей скобки блока (любым способом, даже аварийным), восстанавливается прежнее значение переменной. В качестве переменной может быть скалярная переменная любого простого или объектного типа, или элемент массива. | On entry into the block a value of a variable is saved. E.g. in a local stack or in a local dynamic array. Then new value is assigned to it (if specified). When the finishing bracket is achieved (it is executed even in case of a failure), the value of the variable is restored. Any simple or object data type scalar variable or an array item is allowed to be used as a `PUSH` block variable.
В операторе `PUSH` может быть вызван специальный метод, имеющий модификатор `POP(метод2)`. По окончании такого блока `PUSH`, гарантированно вызывается указанный в скобках модификатора POP закрывающий метод2 (он не должен иметь параметров, и не может быть вызван другим способом). Метод с модификатором `POP` (открывающий) так же не может вызываться напрямую, кроме использования его в операторе `PUSH`. Например: | A special method with modifier `POP(method2)` can be called in the `PUSH` statement. At the end of such `PUSH` block, the method2 specified in parentheses (of the `POP` modifier of a method called in the `PUSH`), is called obligatory. Such method2 should not have parameters, and it can not be called directly (as well as opening method, having the `POP` modifier, which therefore can be called in the `PUSH` statements). E.g.:
`PUSH db.Transaction : ▄▄▄▄ // some database operations db.Commit █ ; ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█`

### I. 8. Блок операторов DEBUG | ### I. 8. DEBUG statements block

Предназначен для временной инъекции кода, который требуется только для целей отладки. Внутри этого блока не ведётся подсчёт и контроль уровней вложенности блоков. Компилятор всегда выдаёт предупреждение о наличии таких блоков с тем, чтобы программист не забыл удалить их из кода (или закомментировать) по окончании отладки. Внутри отладочных блоков могут быть декларированы локальные переменные, но использовать их можно только опять же внутри отладочных блоков (хотя и не обязательно только в том блоке, в котором они декларируются). `DEBUG : ▄▄▄▄▄▄▄ тело ; ▄▄▄█` | A DEBUG block is intended for a temporary code injection which is required for debug purposes. In such blocks, levels of nesting blocks are not controlled. A compiler is always warning about such blocks not removed from a code. Such blocks should be removed when debugging is finished. In DEBUG blocks it is possible to declare local variables as usual. But it is not allowed to use such variables out of DEBUG blocks (though it is allowed to use it in another DEBUG block in the same function). `DEBUG : ▄▄▄▄▄▄▄ body ; ▄▄▄█`
Если для правильной компиляции блоков `DEBUG` требуются дополнительные классы, отсутствующие в основном списке импорта, рекомендуется использовать специальный оператор `DEBUG IMPORT` для добавления таких классов в импорт, специально для компиляции операторов `DEBUG`. | If there required additional classes to compile `DEBUG` blocks, it is recommended to use a special directive `DEBUG IMPORT` to declare such classes rather the add them into usual `IMPORT` list.

### I. 9. Оператор LIKE | ### I. 9. LIKE statement

Предназначен для вставки ранее написанного кода без изменений в новой позиции. Вставляемый код должен быть расположен между двумя блочными комментариями (на одном уровне вложенности). Метка первого блочного комментария (в совокупности с именем функции) используется для указания того, какой именно блок кода следует повторить. Имеются правила: Используемый блок должен быть помечен модификатором `REUSED`. Если вставляется блок из другой функции, после `LIKE` записывается имя этой функции. Далее следует мульти-точие (множество точек, количество которых не ограничивается - но не менее трёх), после чего записывается метка вставляемого блока кода. Возможна вставка только кода из своего класса. Вставляемый код должен быть расположен выше по тексту. Сам вставляемый код не должен содержать операторов `LIKE`. Вставка происходит "как есть", контроль синтаксиса и семантики происходит только при компиляции оператора `LIKE`, поэтому следует не допускать дублирования деклараций, имён переменных, переменных циклов (во избежание ошибок компиляции). Количество операторов `LIKE` для одного используемого блока кода никак не ограничивается. На время вставки кода счётчик вложенности блоков сбрасывается в ноль (т.е. проблем со слишком большой вложенностью блоков `CASE`/`FOR` не будет, даже если суммарный уровень вложенности превысит допустимые три уровня). | The `LIKE` statement is intended to insert earlier written code without changes in a position of the LIKE statement. An inserted code should be placed between two block comments (on the same nesting level). A label of the first block comment (together with a function name) is used to identify the code to insert. There are rules: A reused block of code should be marked with a modifier `REUSED`. If a block is inserted from another function, the name of the function is written following the `LIKE` keyword. A multi-dot is written next (amount of dots is not restricted, at least three should present). It is not possible to insert code from another class. Inserted code should be located above the `LIKE` statement. An inserted block should not have `LIKE` statements itself (recursion or nesting are not possible like in macro). An inserted code is injected "as is", its syntax and semantics are controlled only while compiling the LIKE statement. So do not duplicate variable names, declarations etc. to avoid compiler errors. A reused block can be inserted so many times as it is needed, without restrictions. For a time while a block is inserted by the `LIKE` statement, a counter of nesting `FOR`/`CASE` levels is reset to zero, so there are no problems of total nesting level exceeding allowed amount (3 nesting levels).
Пример: | An example:
`--------------------------- 'find a dot' pos = s.Find(".") CASE pos < 0 ? pos = s.Len ; ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ------------------------------- 'end of find' ... ... LIKE ............. 'find a dot' // place in the same function or LIKE Method1 ..... 'find a dot' // place in another function`

Пожалуйста, помните: Лучше использовать `LIKE ......... '`имя', чем просто копировать код. НО Лучше выносить общий код в отдельную функцию, если это возможно (нежели использовать `LIKE`). Поэтому не злоупотребляйте использованием `LIKE` без необходимости. | Please remember: It is better to use `LIKE ..... 'name'` then just to copy/paste a code. BUT It is better to move a common code into separate functions if this is possible (then to use `LIKE`). So do not overuse the `LIKE` statement without necessity.

### I. 10. Оператор REVERT | ### I. 10. REVERT statement

Предназначен для вставки ранее написанного кода в новой позиции с переворачиванием направлений присваивания. Переворачиваемый код должен быть расположен между двумя блочными комментариями (на одном уровне вложенности). Метка первого блочного комментария (в совокупности с именем функции) используется для указания того, какой именно блок кода следует повторить. Имеются правила: Используемый блок должен быть помечен модификатором `REUSED`. Если вставляется блок из другой функции, после `REVERT` записывается имя этой функции. Далее следует мульти-точие (множество точек, количество которых не ограничивается - но не менее трёх), после чего записывается метка вставляемого блока кода. Возможна вставка только кода из своего класса. Вставляемый код должен быть расположен выше по тексту. Сам вставляемый код может содержать только операторы присваивания, причём левая и правая сторона должны допускать переворачивание (хотя бы переходом к использованию сеттеров и геттеров). Если вставляется код из другого метода, он не должен использовать обращений к локальным переменным (и параметрам). Количество операторов `REVERT` для одного используемого блока кода никак не ограничивается. | The `REVERT` statement is intended to insert earlier written sequence of assignments reverting its direction of assignment in a position of the REVERT statement. An inserted code should be placed between two block comments (on the same nesting level). A label of the first block comment (together with a function name) is used to identify the code to insert. There are rules: A reused block of code should be marked with a modifier `REUSED`. If an inverting code block is from another function, the name of the function is written following the `REVERT` keyword. A multi-dot is written next (amount of dots is not restricted, at least three should present). It is not possible to revert code from another class. Inverted code should be located above the `REVERT` statement. An inverted block should contain only assignment statements, in those destination and source parts can be reverted (at least using correspondent getters / setters). An inverted code should not use local variables (including parameters and a special variable RESULT). A reused block can be inserted so many times as it is needed, without restrictions.
Пример: | An example:

`---------------- 'save form coordinates' config.Set_i("Left", Left) config.Set_i("Top", Top) config.Set_i("Width", Width) config.Set_i("Left", Height) ------------------------------- 'end of save' ... ... REVERT ............. 'save form coordinates'`

$$STOP!!