Именование объектов

Правила именования переменных, функций и типов данных

В качестве имен объектов и типов данных можно использовать буквы, цифры и знаки подчеркивания в любых комбинациях, при условии, что первый символ имени не является цифрой.

Все идентификаторы должны быть уникальны, а для избежания коллизий можно использовать пространство имен и модульную структуру кода, которые NewLang поддерживает одновременно.

Перегрузка функций по типам аргументов NewLang отсуствует, поэтому несколько функций с однинаковым именем но разными аругментами определить нельзя, но можно переопределить функцию, в том числе и расширив типы принимаемых аргументов или увеличив их количество.

Идентификатор объекта может содержать один или несколько специальных символов - квалификаторов (или сигилов), за которыми закрепелено определенное значение. Идентификатор объекта который не содержит квалификатора, называется простым:

Квалификаторы имен:

  • @’ — префикс собачка используется для указания имени макроса, который обрабатыватся препроцессором до начала синтаксического анализа исходного текста программы.
  • $’ — знак доллара в начале имени объекта обозначает автоматичекое имя временной переменной, область памяти для которой выделяется динамически во время выполнения приложения, а время жизни ограничено семантикой яызка
  • ::’ — двойное двоеточие является разделителем пространства имен, и является признаком статического объекта, область памяти для которого выделяется во время компиляции приложения или модуля. Если имя начинается на ‘::’, то область видимости объекта будет глобальной и он будет доступен в рамках всего приложения. В противном случае, видимость объекта будет ограничена только текущим программным модулем.
  • .’ — префикс точка используется при обращении к полю модуля или класса (ограничивает область видимости текущим объектом). Префикс точка может использоваться при определении (вызове) функции для явной идентификации именованного аргумента, чтобы его нельзя было перекрыть макросом препроцессора.
  • \’ — обратный слеш в начале термина обозначает имя программного модуля, а так же разделяет имена каталогов в иерархии размещения программных модулей.
  • :’ — двоеточие в начале термина обозначает имя типа данных или конструктор класса
  • %’ — префикс знак процента указывается для импортируемых символов (нативных переменных и функций)
  • ^’ — символ карет (крышечка/домик) после имени используется для придания объекту иммутабельности (константности, не изменяемости).

Разрешение имен (name lookup)

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

В других случаях, когда NewLang встречает простое имя объекта без квалификатора (сигила), то в дело вструпает специальный алгоритм, который связывает простое имя, встретившееся в исходном тексте программы, с его декларацией или конкретным объектом по его внутреннему имени.

Разрешение простых имен без квалификатора (name lookup, или поиск имени функции/переменной) происходит всегда в строго определенном порядке:

  • в первую очередь происходит поиск имени среди макросов
  • далее выполняется поиск имени среди локальных объектов до объектов текущего модуля
  • в последнюю очередь выполняется поиск среди глобальных объетов с постепенным расширением пространства имен области поиска от текущей до глобальной

Такая последовательность разрешение имен всегда предоставляет возможность переопределить глобальные/локальные объекты или имена аргументов у функций для уже существующего кода без его серъезных изменений.

Например, для имени name в области имен ns поиск происходит в следующей последовательности: @name -> $name -> ns::name -> ::ns::name -> ::name, а для имени arg проверяется только @arg:

    ns:: {
        name(arg="value");
    };

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

Например, обратиться к глобальному объекту name из пространства имен ns из примера выше, нужно по полному имени объекта ::ns::name, а именованнй аргумент . arg’ не будет заменен макросом @arg, если такой будет определен:

    ::ns::name(.arg="value");

Предварительное объявление

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

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

Для предварительного объявления можно использовать только полное квалифцированное имя, которое должно будет в точности совпадать с именем обекта при его последующем создании.

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

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


    # Предварительное определение переменной модуля
    # Действует для всего модуля
    var_module:Int32 := ...;

    func() ::= {

        # Предварительное объявление с помощью DSL
        # (действует только внутри тела функции)
        @declare( func2(arg:Int32):Int32 );

        var_module = func2(var_module);
        @return var_module;
    };


    func2(arg:Int32):Int32 ::= {
        @return $arg*$arg;
    }

    var_module:Int32 := 1;

Имена аргументов, специальные, системные имена

Обозначение имен аргументов у функций очень похоже на обращение к аргументы в bash скриптах, где “$1” или “$name” — порядковый номер или имя соответствующего аргумента.

Зарезервированное имя “$0” обозначает текущий объект, а именем “$$” обозначается родительский объект.

Все аргументы функции собранны в одном словаре со специальным имеенм $*

Неизменяемая переменная “$^” содержит результат выполнения последнего оператора или блока кода.

Полное имя текущего модуля содержится в переменной @\\, а текущая область имен в переменной @::, т.е.:

# Имя файла filename.src в каталоге dir

ns:: { # Использовать пространство имен ns
    name:: {
        # Команда препроцессора "@#" - преобразовать в символьную строку
        ns_str :=  @#  @::; # Строка с областью имен "::ns::name::"
        mod_str :=  @#  @\\; # Строка с именем модуля "\\dir\filename"
    };
};

Области видимости

Символ подчерка, а так же подчерк в начале имени или двойные подчерки в начале и в конце имени имеют специальное значение.

Один подчерк соответствует защищенной, а два подчерка - приватной области видимости объекта в модуле или классе, что соответствует принятым соглашениям в языке Python.

Но так же, как и в языке Python, области видимости больше соответствуют “джентльменской” договоренности и при явном указании имени, доступ к защищенным объектам можно получить, просто указав полное имя объекта.

В дополнении к этому, существуют еще системные поля и объекты, которые начинаются и заканчиваются на два подчерка.

  • $’ — знак доллара в начале имени обозначает системное (локальное) имя временной переменной, область памяти для которой выделяется во время выполнения, а время жизни ограничено семантикой яызка
  • ::’ — двойное двоеточие являются разделителем при указании пространства имен. Явное указание пространства имен является признаком статического объекта, область памяти для которого выделяется во время компиляции приложения или модуля.