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

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