Выражения

В данном разделе описывается язык выражений, представляющих конкретные действия или рассуждения, выполняемые над моделью предметной области. Данные выражения чаще всего используются в составе узлов деревьев решений, но могут использоваться и отдельно.
Данный раздел соответствует пакету its.model.expressions в коде.

Общие принципы

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

Каждый вид выражений в коде представлен отдельным классом-наследником от класса Operator, и может иметь дочерние выражения (операнды), представленные списком Operator.children.
Выражения также имеют возвращаемый тип, представленный функцией Operator.resolvedType(DomainModel) (в общем случае тип выражения может зависеть от определений в модели предметной области).

Синтаксис

Ниже в данном разделе будут приведены все поддерживаемые виды выражений, и для каждого из них будет приведена их текстовая форма записи.
Данная текстовая форма считается частью LOQI-синтаксиса, хотя и не используется в обычных .loqi файлах (поскольку LOQI описывает в первую очередь модель предметной области, где выражений нет). Эта запись выражений ("LOQI-выражения") имеет некоторые общие синтаксические конструкции с обычной LOQI-записью модели, в связи с чем вынесена в ту же грамматику LoqiGrammar.g4

Построение выражений в коде

Таблица приоритетов выражений

Приоритеты в таблице расположены от наибольшего к наименьшему

Приоритет Операторы Ассоциативность
0 Литералы-константы
Ссылочные литералы
-
1 obj.property
obj->relationship
obj.class()
Левая
2 subj=>relationship(obj, ... ).param
subj=>relationship(obj, ... )
Левая
3 not Левая
4 < > <= >=
expr.compare(expr)
is
Левая
5 == != Левая
6 expr as class Левая
7 expr and expr Левая
8 expr or expr Левая
9 subj+=>relationship(obj, ...) Левая
10 expr ? expr : expr Правая
11 var = obj
obj.property = value
Правая
12 if(expr) expr else expr Правая
Приоритет не имеет
значения ввиду
скобок в синтаксисе
( expr )
find ...
findExtreme ...
forAll ...
forAny ...
{ expr; ... }
-

Далее будут подробно рассмотрены отдельные виды выражений.


Литералы-константы

Литералы-константы представляют некоторую константу, записываемую в выражении.
В коде все они являются наследниками ValueLiteral и имеют следующее содержание:

  • ValueLiteral.value - конкретное значение константы, представленное литералом. Имеет тип, соответствующий литералу.
  • ValueLiteral.type - тип данных значения данного литерала.

Данные литералы полностью соответствуют значениям, описанным в разделе о LOQI.
В коде они представлены:

  • Строковые константы (Строковый литерал) - StringLiteral
  • Целые числа (Целочисленный литерал) - IntegerLiteral
  • Дробные числа (Вещественный литерал) - DoubleLiteral
  • Булевы значения (Булев литерал) - BooleanLiteral
  • Значения перечисления (Перечислимый литерал) - EnumLiteral

Ссылочные литералы

Под ссылочными литерами подразумевается получение некоторой сущности по ссылающемуся на него имени.
В коде все они являются наследниками ReferenceLiteral и имеют следующее содержание:

  • ReferenceLiteral.name - имя, по которому происходит ссылка.
Important

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

Переменная дерева решений

Синтаксис:

<имя переменной>

Примеры: X, Y, MyVar
(по конвенции стараемся использовать PascalCase - т.е. запись с большой буквы - для переменных дерева решений, для того чтобы было легче отличать от контекстных переменных)

Смысл: Получить (вернуть) объект, записанный в переменную дерева решений.
Возвращаемый тип: объект (ObjectType) соответствующего переменной класса (ObjectType.className)
В коде: DecisionTreeVarLiteral

Валидация:

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

Контекстная переменная

Синтаксис:

$<имя переменной>

Примеры: x1, y1, someVar
(по конвенции стараемся использовать camelCase - т.е. запись с маленькой буквы - для контекстных переменных, для того чтобы было легче отличать от переменных дерева решений)

Смысл: Получить объект, записанный в контекстную переменную.
Контекстные переменные отличаются от переменных дерева решений тем, что контекстные переменные вводятся внутри выражений и используются только внутри вводящих их выражений, а переменные дерева решений вводятся в узлах дерева решений и могут использоваться в различных выражениях.
Возвращаемый тип: объект (ObjectType) соответствующего переменной класса (ObjectType.className)
В коде: VariableLiteral

Валидация:

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

Ссылка на класс

Синтаксис:

class:<имя класса>

Примеры: class:MyClass

Смысл: Получить класс, объявленный в модели, по его имени
Возвращаемый тип: класс (ClassType), наследующийся от соответствующего класса (ClassType.className)
В коде: ClassLiteral

Валидация:

  • В модели предметной области должен существовать класс с соответствующим именем.

Ссылка на объект (по имени)

Синтаксис:

obj:<имя объекта>

Примеры: obj:someObj

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

Валидация:

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

Операции получения данных из модели

Проверка класса объекта

Синтаксис:

<выражение-объект> is <выражение-класс>

Примеры: X is class:Operator

Смысл: проверить, является ли объект экземпляром переданного класса. Данное выражение учитывает наследование (т.е. объект может быть не прямым наследником класса).
Возвращаемый тип: булев (BooleanType) - true если является экземпляром, false иначе.
В коде: CheckClass

Валидация:

  • Выражение-объект должно возвращать объект (ObjectType)
  • Выражение-класс должно возвращать класс (ClassType)
  • Типы объекта и класса должны соответствовать - класс объекта должен быть супертипом для проверяемого класса.
    • Потому что нет смысла проверять объект на принадлежность классу, которому он никогда не может принадлежать.

Получение класса объекта

Синтаксис:

<выражение-объект> .class()

Примеры: X is class:Operator

Смысл: получить прямой класс объекта.
Возвращаемый тип: класс (ClassType), наследующийся от класса выражения-объекта
В коде: getClass

Валидация:

  • Выражение-объект должно возвращать объект (ObjectType)

Получение значения свойства

Синтаксис:
В базовой форме выражение выглядит так:

<выражение-объект> .<имя свойства>

Примеры: X.myProperty, obj:systemObj.description

У выражения также есть параметризованная форма, для получения свойства по параметрам:

<выражение-объект> .<имя свойства> <значения параметров>

Здесь и далее в этом разделе структура <значения параметров> определена как:

< <имя параметра 1> = <выражение-параметр 1>, ... >
ИЛИ
< <выражение-параметр 1>, <выражение-параметр 2>, ... >

(В записи выше треугольные скобки < > в начале и конце строки должны интерпретироваться буквально.)
Примеры записи значений параметров: <myIntParam=2, myBoolParam=true>, <2, true>
Примеры записи параметризованной формы выражения получения свойства: X.myPropertyForEnum<MyEnum:FIRST>, Y.priority<placement = Placement:Left, inParenthesis = true>.

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

Валидация:

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

Проверка наличия связи по отношению между объектами

Синтаксис:

<выражение-субъект> =><имя отношения>[<значения параметров>](<выражение-объект 1>, ...)

(структура <значения параметров> подробно описана выше)
Примеры: X=>someRel(Y), X=>isBetween(Y1, Y2), X=>isOperandOf<Placement:Left>(Y)

Смысл: Проверить, существует ли между объектами связь по заданному отношению. Если выражение параметризовано, то проверить, существует ли между объектами связь по заданному отношению, которая также содержит заданные значения параметров.
Возвращаемый тип: булев (BooleanType) - true если связь существует, false если нет.
В коде: CheckRelationship

Валидация:

  • Выражение-субъект и выражения-объекты должны быть объектами (ObjectType)
  • Для заданных классов субъекта и объектов должно существовать заданное отношение
    • В данном выражении поддерживается проекция, но для этого должно существовать единственное отношение, в которое будет спроецировано указанное.
  • Количество заданных выражений-объектов должно быть равно объявленному для данного отношения количеству объектов
  • Состав (имя и тип) параметров, переданных в выражении, должен соответствовать параметрам, объявленным для данного отношения (но можно передать неполный набор параметров).

Получить значение параметра связи между объектами

Синтаксис:

<выражение-субъект> =><имя отношения>[<значения параметров>](<выражение-объект 1>, ...).<имя получаемого параметра>

(структура <значения параметров> подробно описана выше)
Примеры: X=>someRel(Y).myParam, X=>isBetween(Y1, Y2).isAbove, X=>isOperandOf<Placement:Left>(Y).priority

Смысл: найти между объектами связь по отношению, аналогично проверке наличия связи. Если таких связей нет, или их несколько, то будет выброшена ошибка выполнения. Иначе, если такая связь единственная, то получить у нее значение некоторого параметра по его имени.
Примечания:

  • Данное выражение не поддерживает проекцию, в отличие от проверки наличия связи
  • Для зависимых отношений значения параметров определяются как описано в соответствующем разделе.
    Возвращаемый тип: в соответствии с типом получаемого параметра.
    В коде: GetRelationshipParamValue

Валидация:

Поиск объекта по условию

Синтаксис:

find <имя типа> <имя переменной поиска> { <выражение-условие поиска> }

Примеры: find Operator x { $x =>isLeftOf(Y) }

Important

Поиск объектов, удовлетворяющих выражению-условию
В этом и других типах выражений используется общий механизм поиска объектов по условию.
Условием обычно считается выражение, возвращающее булево значение, и имеющее внутри себя контекстные переменные. Объект считается удовлетворяющим этому условию как переменная <var>, если существующая внутри данного выражения контекстная переменная <var> объявлена с типом, соответствующим типу данного объекта, и если при задании переменной <var> равной этому объекту, выражение-условие возвращает true.
Например, условием может выступать выражение $person.age >= 18, где переменная $person объявлена с типом Person, и тогда объект obj alice : Person будет считаться удовлетворяющим данному условию как переменная $person, если его свойство .age больше или равно 18.

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

Валидация:

  • Объявленный для переменной тип должен существовать в модели
  • Объявляемое имя переменной не должно перекрывать уже существующие в данном контексте переменные.
  • Выражение-условие поиска должно возвращать булево значение (BooleanType).
    • Внутри выражения-поиска существует контекстная переменная поиска, объявленная данным оператором.

Поиск объекта по условию экстремума

Синтаксис:

findExtreme <имя экстремальной переменной> [ <выражение-условие экстремума> ]
among <имя типа переменной> <имя общей переменной> { <выражение-условие поиска> }

Примеры: findExtreme x1 [ $x1 =>isLeftOf($xToken) ] among token xToken { $xToken =>belongsTo(X) }

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

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

findExtreme extremeVar [ <extremeConditionExpr($extremeVar, $var)> ]
among type var { <conditionExpr($var)> }

эквивалентно выражению

find type extremeVar {
	<conditionExpr($extremeVar)> 
	and forAll type var [<conditionExpr($var)> and $var != $extremeVar ] {
		<extremeConditionExpr($extremeVar, $var)> 
	} 
}

(См. поиск объекта по условию и квантор общности для лучшего понимания выражения выше)

Возвращаемый тип: объект (ObjectType) соответствующего объявленной переменной типа.
В коде: GetExtreme

Валидация:

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

Получение объекта по связи по отношению

Синтаксис:

<выражение-субъект> -><имя отношения>[<значения параметров>]

(структура <значения параметров> подробно описана выше)
Примеры: X->someRel, X->isOperandOf<Placement:Left>

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

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

someObj->someRelationship<...>

эквивалентно выражению

find type anotherObj {
	someObj->someRelationship<...>($anotherObj)
}

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

Возвращаемый тип: объект (ObjectType) типа, соответствующего типу объекта связи.
В коде: GetByRelationship

Валидация:

  • Выражение-субъект и выражения-объекты должны быть объектами (ObjectType)
  • Для заданных классов субъекта и объектов должно существовать заданное отношение
  • Состав (имя и тип) параметров, переданных в выражении, должен соответствовать параметрам, объявленным для данного отношения (но можно передать неполный набор параметров).

Логические операторы

Логическое И

Синтаксис:

<выражение 1> and <выражение 2>

Примеры: $a == $b and $a != $c

Смысл: найти логическое И от двух выражений. Второе (правое) выражение не выполняется, если первое (левое) вернуло false
Возвращаемый тип: булево значение (BooleanType)
В коде: LogicalAnd

Валидация:

  • Оба выражения-операнда должны возвращать булево значение (BooleanType)

Логическое ИЛИ

Синтаксис:

<выражение 1> or <выражение 2>

Примеры: $a == $b or $a != $c

Смысл: найти логическое ИЛИ от двух выражений. Второе (правое) выражение не выполняется, если первое (левое) вернуло true
Возвращаемый тип: булево значение (BooleanType)
В коде: LogicalOr

Валидация:

  • Оба выражения-операнда должны возвращать булево значение (BooleanType)

Логическое НЕ

Синтаксис:

not <выражение>

Примеры: not ($a is class:MyClass)

Смысл: вычислить логическое отрицание выражения операнда.
Возвращаемый тип: булево значение (BooleanType)
В коде: LogicalNot

Валидация:

  • Выражение-операнд должно возвращать булево значение (BooleanType)

Сравнение двух значений

Синтаксис:

<выражение 1> == <выражение 2>
<выражение 1> != <выражение 2>
<выражение 1> > <выражение 2>
<выражение 1> >= <выражение 2>
<выражение 1> < <выражение 2>
<выражение 1> <= <выражение 2>

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

Валидация:

  • Возвращаемые типы выражений-операндов должны быть одинаковы, или приводимы друг к другу (численные типы в данном случае считаются приводимыми друг к другу)
  • Сравнения на больше/меньше применимы только к численным типам

Трехзначное сравнение двух значений

Синтаксис:

<выражение 1> .compare( <выражение 2> )

Смысл: сравнить величину значения двух выражений. Возвращает один из трех вариантов - больше/меньше/равно (относительно первого выражения, т.е. "больше" значит что первое больше второго и т.д.)
Возвращаемый тип: значение встроенного перечисления Comparison (EnumType)
В коде: Compare

Валидация:

  • Возвращаемые типы выражений-операндов должны быть численными

Кванторы

Квантор общности ("Для всех")

Синтаксис:

forAll <имя типа> <имя переменной квантора> [
	<выражение-условие выбора>
] {
	<выражение-тело квантора>
}

Также допускается более короткая запись

forAll <имя типа> <имя переменной квантора> {
	<выражение-тело квантора>
}

когда <выражение-условие выбора> равно true (т.е. выбрать все объекты подходящего типа).
Примеры:

forAll Operand xOp [
	$xOp=>isOperandOf(X)
] {
	$xOp.state == State:unevaluated
}

forAll Operand op {
	$op.state = State:evaluated
}

Смысл: найти все объекты, удовлетворяющие условию выбора как переменная квантора. Далее в зависимости от типа выражения-тела квантора:

  • Если выражение-тело возвращает булево значение, то вернуть true, если все найденные выше объекты удовлетворяют выражению-телу в качестве условия, как переменная квантора, иначе вернуть false - Проверяющий режим квантора.
    • Обратите внимание, что проверяющий режим предполагает, что повторное или многократное выполнение тела квантора не приведет к изменениям результата выполнения или состояния модели. В связи с этим выполнение может прерваться сразу, если для одного из объектов тело квантора вернуло false. Во избежание нежелательных последствий, в данном режиме не стоит менять состояние модели.
  • Иначе (если выражение-тело имеет другой тип), то выполнить выражение-тело для всех найденных объектов (подставляя объекты в качестве переменной квантора), и ничего не вернуть - Управляющий режим квантора (или режим цикла).

Возвращаемый тип: булево значение (BooleanType) в проверяющем режиме, или ничего (NoneType) в управляющем режиме
В коде: ForAllQuantifier

Валидация:

  • Выражение-условие выбора должно возвращать булево значение (BooleanType).
    • Внутри выражения-условия выбора и выражения-тела квантора существует контекстная переменная квантора, объявленная данным оператором.

Квантор существования ("Для любого")

Синтаксис:

forAny <имя типа> <имя переменной квантора> [
	<выражение-условие выбора>
] {
	<выражение-тело квантора>
}

Также допускается более короткая запись

forAny <имя типа> <имя переменной квантора> {
	<выражение-тело квантора>
}

когда <выражение-условие выбора> равно true (т.е. выбрать все объекты подходящего типа).
Примеры:

forAny Operand xOp [
	$xOp=>isOperandOf(X)
] {
	$xOp.state == State:unevaluated
}

forAny Operand op {
	$op.state = State:evaluated
}

Смысл: найти все объекты, удовлетворяющие условию выбора как переменная квантора. Далее в зависимости от типа выражения-тела квантора:

  • Если выражение-тело возвращает булево значение, то вернуть true, если любой из найденных выше объектов удовлетворяет выражению-телу как переменная квантора, иначе вернуть false - Проверяющий режим квантора.
    • Обратите внимание, что проверяющий режим предполагает, что повторное или многократное выполнение тела квантора не приведет к изменениям результата выполнения или состояния модели. В связи с этим выполнение может прерваться сразу, если для одного из объектов тело квантора вернуло true. Во избежание нежелательных последствий, в данном режиме не стоит менять состояние модели.
  • Иначе (если выражение-тело имеет другой тип), то выполнить выражение-тело для одного любого из найденных объектов (подставляя его в качестве переменной квантора), и ничего не вернуть - Управляющий режим квантора (или режим действия).
    • Механизм выбора одного из объектов не определен данной спецификацией. Ожидается, что данный механизм будет использоваться в ситуациях, когда заранее известно, что подходящий объект один.

Возвращаемый тип: булево значение (BooleanType) в проверяющем режиме, или ничего (NoneType) в управляющем режиме
В коде: ExistenceQuantifier

Валидация:

  • Выражение-условие выбора должно возвращать булево значение (BooleanType).
    • Внутри выражения-условия выбора и выражения-тела квантора существует контекстная переменная квантора, объявленная данным оператором.

Модификация модели предметной области

Присвоение переменной дерева решений

Синтаксис:

<имя переменной> = <выражение-значение>

Примеры: X = Y->hasOperand

Смысл: (пере)присвоить переменной дерева решений новое значение (объект).
Возвращаемый тип: отсутствует (NoneType)
В коде: AssignDecisionTreeVar

Валидация:

  • Переменная, обозначенная данным именем, должна существовать в контексте валидации выражения (т.е. должна быть объявлена где-то в дереве решений, чтобы она могла быть использована в выражении)
  • Выражение-значение должно возвращать объект (ObjectType), чей класс (ObjectType.className) совместим с объявленным для переменной типом.

Присвоение значения свойству

Синтаксис:

<выражение-объект> .<имя свойства>[<значения параметров>] = <выражение-значение>

(структура <значения параметров> подробно описана выше)
Примеры: X.state = State:unevaluated

Смысл: (пере)присвоить свойству объекта новое значение.
Возвращаемый тип: отсутствует (NoneType)
В коде: AssignProperty

Валидация:

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

Добавление связи по отношению между объектами

Синтаксис:

<выражение-субъект> +=><имя отношения>[<значения параметров>](<выражение-объект 1>, ...)

(структура <значения параметров> подробно описана выше)
Примеры: X+=>isOperandOf<Placement:Left>(Y)

Смысл: добавить между указанными объектами связь по отношению.
Возвращаемый тип: отсутствует (NoneType)
В коде: AddRelationshipLink

Валидация:

  • Выражение-субъект и выражения-объекты должны быть объектами (ObjectType)
  • Для заданных классов субъекта и объектов должно существовать заданное отношение, и оно не может быть зависимым.
  • Количество заданных выражений-объектов должно быть равно объявленному для данного отношения количеству объектов
  • Состав (имя и тип) параметров, переданных в выражении, должен соответствовать параметрам, объявленным для данного отношения.
  • Если для данного отношения объявлены параметры, то при добавлении связи необходимо передать все объявленные параметры (нельзя заполнить параметры частично).

Управление потоком выполнения выражений

Скобки

Синтаксис:

( <выражение> )

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

Приведение к типу (Cast)

Синтаксис:

<выражение-объект> as <выражение-класс>

Примеры: X as class:Operator

Смысл: расценивать результат выражения-объекта как объект заданного класса в данном контексте. Если при выполнении окажется, что данный объект не является экземпляром данного класса, то будет выброшена ошибка выполнения.
Возвращаемый тип: объект (ObjectType) заданного класса.
В коде: Cast

Валидация:

  • Выражение-объект должно возвращать объект (ObjectType)
  • Выражение-класс должно возвращать класс (ClassType)
  • Типы объекта и класса должны соответствовать - класс объекта должен быть супертипом для проверяемого класса.
    • Потому что нет смысла пытаться привести объект к классу, которому он никогда не может принадлежать.

Условный оператор

Синтаксис:
Тернарная форма:

<выражение-условие> ? <выражение-then> : <выражение-else> 

Примеры: X is Operator ? 1 : 2

Условная форма:

if(<выражение-условие>) <выражение-then> [else <выражение-else> ]

Примеры: if(X is Operator) 1 else 2, if(X is Operator) X.state = State:unevaluated

Смысл: в зависимости от наличия выражения-else:

  • Если выражение-else есть - Полное условие:
    • Если выражение-условие выполняется, то выполнить выражение-then и вернуть его результат. Иначе выполнить выражение-else и вернуть его результат
  • Если выражение-else отсутствует - Неполное условие:
    • Если выражение-условие выполняется, то выполнить выражение-then. Ничего не возвращать.

Возвращаемый тип: ближайший супертип типов -then и -else выражений при полном условии, и ничего (NoneType) при неполном условии.
В коде: IfThen

Валидация:

  • Выражение-условие должно возвращать булево значение (BooleanType)
  • При полном условии типы -then и -else выражений должны быть приводимы к общему типу (иметь общий супертип).

Блок выражений

Синтаксис:

{ <выражение 1> ; <выражение 2> ; ... [;] }

Смысл: последовательно выполнить вложенные выражения. Вернуть результат последнего выполненного выражения
Возвращаемый тип: аналогично типу последнего выражения.
В коде: Block

Валидация: отсутствует