Разделы сайта находятся в разработке.
Материалы могут быть неполными или содержать ошибки. Содержимое сайта будет синхронизировано с реализацией при выходе следующей версии, тогда как текущая (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 typestruct 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> \==`(…)`) не реализованы — явная ошибка.