Разделы сайта находятся в разработке.
Материалы могут быть неполными или содержать ошибки. Содержимое сайта будет синхронизировано с реализацией при выходе следующей версии, тогда как текущая (0.6.0) предназначена для прототипирования синтаксиса и создания песочницы.
Именование объектов
В качестве имен объектов и названий типов данных можно использовать буквы, цифры и знаки подчеркивания в любых комбинациях, при условии, что первый символ имени не является цифрой.
Имя не может состоять из единственного знака подчеркивания, так как это специальный термин, который используется в служебных целях.
Для избежания коллизий имен можно использовать пространство имен и модульную структуру кода, которые TrustLang поддерживает одновременно. Допускается переопределение и перегрузка функций.
При создании объектов имя идентификатора может содержать один или несколько специальных символов — квалификаторов (или сигилов), за которыми закреплено определённое значение.
Квалификаторы имён
- ‘@’ — префикс собачка используется для указания имени макроса, который обрабатывается препроцессором до начала синтаксического анализа исходного текста программы.
- ‘$’ — знак доллара в начале имени объекта обозначает временное имя, время жизни которого ограничено семантикой языка.
- ‘::’ — двойное двоеточие разделяет пространства имён и является признаком постоянного объекта, значение которого сохраняется после выхода из текущей области видимости. Если имя начинается с ‘::’, то область его видимости будет глобальной и он будет доступен из других модулей программы.
- ‘.’ — префикс точка используется при обращении к полю модуля или класса (ограничивает область видимости только текущим объектом). Префикс точка также может быть использован при определении или вызове функции для указания имени аргумента, который нельзя перекрыть макросом препроцессора.
- ‘\’ — обратный слеш в начале имени обозначает имя программного модуля, а также разделяет имена каталогов в иерархии размещения программных модулей в файловой системе.
- ‘:’ — двоеточие в начале термина обозначает имя типа данных или конструктор класса, который всегда является постоянным
- ‘%’ — префикс знак процента указывается для нативных имён переменных и функций
Разрешение имен (name lookup)
Если имя объекта не содержит квалификатора, оно является простым.
Когда TrustLang встречает простое имя объекта без квалификатора, в дело вступает алгоритм разрешения имён (name lookup), который связывает простое имя, встретившееся в исходном тексте программы, с его декларацией или созданным объектом.
Разрешение простых имен без квалификатора (name lookup, или поиск имени функции/переменной) происходит всегда в строго определённом порядке:
- в первую очередь происходит поиск имени среди макросов
- в случае вызова функции выполняется статическое разрешение имен при перегрузке функций
- далее выполняется поиск имени среди локальных объектов до объектов текущего модуля
- в последнюю очередь выполняется поиск среди статических объектов с постепенным расширением пространства имен области поиска от текущей до глобальной
Такая последовательность разрешения имён всегда предоставляет возможность переопределить глобальные/локальные объекты или имена аргументов у функций для уже существующего кода без его серьёзных изменений.
Например, для имени name в области имён ns поиск происходит в следующей последовательности:
@name → %name → $name → ns::name → ::ns::name → ::name,
а для имени аргумента arg проверяется только @arg:
ns:: {
name(arg='value');
};
И в то же время всегда остаётся возможность указать конкретный объект независимо от работы алгоритма разрешения простых имён. Достаточно указать квалификатор в имени объекта в явном виде.
Например, обратиться к глобальному объекту name из пространства имён ns из примера выше нужно по полному имени объекта ::ns::name,
а именованный аргумент ’. arg’ не будет заменён макросом @arg, если такой будет определён:
::ns::name(.arg='value');
Расширение поиска пространства имён
Для указания нескольких областей имен для расширенного поиска при разрешении простых имён без квалификатора,
используется синтаксическая конструкция ... = ns::name, ns::name2; или @using(ns::name, ns::name2); при использовании DSL.
Поиск в перечисленных областях имён производится в порядке их указания до конца текущего блока кода,
до следующего оператора расширенного поиска или до оператора ... = _;,
который отменяет расширенный поиск в пространствах имен до конца текущего блока кода (до конца модуля).
Предварительное объявление
В тексте программы можно ссылаться только на реально существующие (созданные) объекты. Но для тех случаев, когда требуется сослаться на объект, который создан в другом модуле или будет создан позже, можно сделать предварительное объявление, при котором компилятор регистрирует имя и тип объекта без его реального создания.
За счет предварительного объявления можно ссылаться только на статические объекты (типы данных), или локальные поля класса, о которых компилятор ещё не знает, но которые будут определены в процессе компиляции позже.
Для предварительного объявления используется полное квалифицированное имя, которое должно в точности совпадать с именем объекта при его последующем создании.
Для предварительного объявления используется такой же синтаксис, как и при реальном создании объекта, только справа от оператора создания должно быть указано многоточие.
Область видимости предварительного объявления соответствует области видимости его размещения, а не реальной области видимости объекта, который будет впоследствии создан.
# Предварительное определение переменной модуля
# Действует для всего модуля
var_module:Int32 := ...;
func() := {
@return func2(var_module);
};
func2(arg:Int32):Int32 := {
@return $arg*$arg;
}
var_module:Int32 := 1;
Имена аргументов, специальные и системные имена
Обозначение имен аргументов у функций очень похоже на обращение к аргументам в bash-скриптах, где “$1” или “$name” — порядковый номер или имя соответствующего аргумента.
Зарезервированное имя “$0” обозначает текущий объект, а именем “$$” обозначается родительский объект.
Все аргументы функции собраны в одном словаре со специальным именем $*
Неизменяемая виртуальная переменная компилятора “$^” содержит результат выполнения последнего оператора или блока кода.
Неизменяемые объекты
TrustLang реализует динамическую иммутабельность. Это свойство лексического объекта, а не свойство типа данных и означает, что объект может стать неизменяемым не только в момент создания, но и в будущем при одной из операций присвоения/изменения значения.
Для придания объекту свойства иммутабельности (невозможности изменять свое значение далее по тексту программы), используются символ ‘^’ карет (крышечка/домик) после имени объекта.
val := 0; # Create mutable variable
val = 1; # Set new value
val^ = 2; # Set unchangeable value
val = 3; # Error !!!
Свойство иммутабельности у аргументов функций зависит от типа функции. У чистых функций аргументы, передаваемые по ссылке (владеющие переменные), всегда иммутабельные. Свойство мутабельности у остальных аргументов указывается при определении функции на общих основаниях:
func( arg1^:Int32, arg2:Int32) := {
arg1 = 1; # Error (arg1 - immutable)
arg2 = 1; # OK
arg2^ = 2; # OK - set immutable value
arg2 = 3; # Already error
}
Иммутабельность вызовов и атрибуты
Признак неизменяемости может относиться и к вызовам функций. Чистые функции и принудительное вычисление на этапе компиляции (::-, cube^(...)) в текущей версии не реализованы — см. Функции и Статус. Атрибуты объектов (в т.ч. реальная форма @[имя(...)] перед объявлением) описаны в разделе Макросы и Взаимодействие с C/C++.