Разделы сайта находятся в разработке.

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

Классы

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

Статус: реализованы базовые :Struct (строго POD) и :Class (наследование), генерируемые в C++ struct; полноценное ООП (виртуальные методы/override, конструкторы/деструкторы, статические члены) в текущей версии не реализовано. Из «объектно-ориентированных» типов также реализованы перечисления :Enum, варианты :Variant и кортежи :Tuple (см. Словари и наборы), а также предварительное объявление нативных C++-классов (String ::= %std::string { ... }; — см. Нативные типы) и пользовательские шаблон-классы (<T> :Box ::= :Class{...} — см. Обобщённое программирование). Актуальные границы реализации — в Статусе реализации.

Объявление :Struct/:Class — через ::= с телом, члены которого задаются оператором := (Name ::= :Base{ ... };):

Point ::= :Struct{ x:Int32 := _; y:Int32 := _; };      # строго POD; поля БЕЗ значения (`:= _`)
Animal ::= :Class{ name:Int32 := 0; speak():Int32 := { ... }; };  # Class: default допустим
Dog ::= :Animal{ age:Int32 := _; };                    # наследование (Class)
Iface ::= :Class ...;                                  # предварительное объявление (форма без тела)

Оба типа генерируются как C++ struct (все члены публичные); :Struct дополнительно получает static_assert на POD (std::is_trivial_v && std::is_standard_layout_v). Поля/методы с ведущим _ (защищённые) и __ (приватные) поддерживаются на уровне соглашения об именовании — влияют только на автодополнение, в C++ генерируются без изменения доступа. Голое имя члена (obj.field, obj.method()) транслируется в прямое обращение к члену struct.

Правила значений и объявлений:

  • member := ... — прототип метода (объявление без тела) внутри определения класса. Класс с телом (даже если все методы — прототипы) является полным определением (struct c_Name { ... };) — в C++ прототипы существуют только внутри определения, а не в forward-объявлении.
  • member := _ — отсутствие значения (поле без значения по умолчанию).
  • field:Type := <value> — поле со значением по умолчанию.
  • :Name ::= :Base ...; (форма без тела) — предварительное объявление → C++ incomplete type struct c_Name;. Имя типа при этом уже зарегистрировано и видно, поэтому позднее то же имя можно доопределить (:Name ::= :Base { ... };); повторное определение — ошибка. В C++ forward-объявление не содержит членов (ни полей, ни методов); тип неполный.
  • Self-ссылки разрешены: имя record-типа видно внутри его собственного тела (аналог C++ injected-class-name), поэтому :Node ::= :Class{ next : @[reftype("shared")@] Node := _; } корректно. Ссылки (shared/weak/unique-указатель) на неполный тип допустимы; value-поле самого себя — ошибка бесконечного размера (см. ниже).
  • field := ... недопустимо: в C++ член-данное нельзя предобъявить (оно существует только в определении).

Рекурсивные/циклические ссылки в полях запрещены статически (анализатор RefCycleHook), чтобы не допускать утечек и невыразимых типов: -Wrecursive-shared — цикл с shared-ребром (утечка refcount; разрывается weak-обратной ссылкой), -Wrecursive-unique — взаимное unique-владение двух типов, -Wrecursive-value — рекурсия по значению (value/default unique = inline, бесконечный размер). Все — default error, переключаются -Wrecursive-*=ignore|warning|error. Самоссылка unique-указателем — легальный owned-список и не диагностируется.

Для :Struct (строго POD) значение по умолчанию поля запрещено анализатором (NSDMI нарушает тривиальность): поле объявляется как field:Type := _;. Для :Class значение поля не проверяется — допустимы и := <value> (эмитится как C++ default member initializer), и := _ (без инициализатора).

Виртуальные методы (@[virtual]) и переопределение (@[override]) в текущей версии не реализованы — их использование приводит к явной ошибке компиляции (а не к молчаливому игнорированию).

Перегрузка операторов

Оператор объявляется именем-символом в обратных кавычках (лексема REFLECTION): в теле класса — как метод, на верхнем уровне модуля — как свободная функция. Тело и сигнатура — как у обычного метода.

Point ::= :Class{
    x: Int32 := _;
    `==`(o: Point): Bool := { ... };      # member → C++ operator==
    `()`(i: Int32): Int32 := { ... };     # operator()  (только member)
    `[]`(i: Int32): Int32 := { ... };     # operator[]  (только member)
};

`!=`(a: Point, b: Point): Bool := { ... };   # свободный оператор (все операнды — параметры)

Символ транслируется в C++ operator<sym> (`==` → operator==, `()` → operator()); выражения a == b / a != b для пользовательских типов разрешаются C++-перегрузкой, поэтому оператором можно пользоваться в обычных выражениях.

Использование в TrustLang-коде: a == b (сравнения), a(5) (вызов значения — оператор ()), a[i] (индексация — оператор []). Каждая форма транслируется в соответствующую C++-операцию (a(5) → a(5), a[i] → (a)[i]) и разрешается C++-перегрузкой.

Реализованы: сравнения == != < > <= >= (как member, так и свободные) и вызов/индекс () / [] (только member — требование C++; [] принимает ровно один параметр). Арность проверяется (сравнение — один параметр у member и два у свободного), повторный символ в типе запрещён.

Использование проверяется на этапе анализа: сравнение/вызов/индексация требуют объявленного оператора у типа (иначе — ошибка компиляции, а не ошибка C++), арность вызова проверяется по объявлению; конфликт «member + свободная функция» одного символа диагностируется как неоднозначность. Операторы поддерживают контракты (trust_pre/trust_post, как функции и методы). Шаблонные операторы (<T> \==`(…)`) не реализованы — явная ошибка.