Реализация областей видимости

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

Каждый объект имеет владельца.

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

Класс Term используется парсером и с его помощью реализуется анализ AST. Класс Obj является универсальным объектом для хранения любых типов данных. Класс Variable (std::variant) - главная структура для хранения объектов во время выполнения с учетом типизации. Переменные по значению хранятся непосредственно в Variable, а ссылочные и защищеные переменных данные хранятся в std::shared_ptr, который сам находится в Variable.

Структура VariablePair содержит связку TermPtr и Variable, т.е. данные с привязкой к AST. Класс LatterType (последнее вычисленное значение) - хранит VariablePair или VariablePair * в зависимости от последнего вычисленого результата. Ссылка на VariablePair * возвращается если последний результат был реальной переменной, тогда как значение VariablePair возвращается, если последний результат никуда не сохранялся.

Module –> std::map<std::string, VariablePair> (статические переменные модуля) Runtime –> GlobalObjects –> std::map<std::string, VariablePair> (глобальные и встроенные объекты) Context –> std::vector –> VariableScope –> std::map<std::string, VariablePair> (временные и thread_local переменные)

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

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

Объекты модуля:

Определение объекта Аналог определения на C++ (или модификатор) Общее объявление (видимость из других пакетов) Доступ по полному имени (из дргуих модулей) Доступ из других потоков Можно взять ссылку
::obj_glob ObjPtr obj_glob да да да да
@::obj_static ObjPtr obj_static нет да да да
obj_package ObjPtr obj_package нет да да да
$obj_local thread_local ObjPtr obj_local нет нет нет да

Объекты модуля:

|
Явное ограничение области видимости (применяется к любому типу объекта) ||||| |int_pub:Int32 | int int_pub | - | - | - | - | |_int_prot:Int32 | int _int_prot | нет | нет | - | - | |__int_priv:Int32 | static int __int_priv | нет | нет | нет | - |

Объекты класса:

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

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

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

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

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

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

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