Архитектура
На память
clang-17 не поддерживает:
Feature | Proposal | Available |
---|---|---|
Coroutines | P0912R5 | Partial Fully supported on all targets except Windows, which still has some stability and ABI issues. |
Extended floating-point types and standard names | P1467R9 | No |
Concepts | P0848R3 | Clang 16 (Partial) |
Modules | No |
Начиная с C++ should adopt the same characters for C++26.
- Add @, $, and ` to the basic character set P2558R2 Yes
Система классов реализации
RunTime - единственный класс для приложения (процесса) - интерфейс для взаимодействия с операционной системой
- Загружат и выгружает модули и является их владельцем (shared_ptr)
- Хранит сслыки на глобальные объекты (WeakPtr) и непосредственно глобальные объекты (встроенные типы и функции). Ключем явялется строка с внутренним именем объекта
- Хранит список глобальных объектов (типы данных и прототипы функций, которые создаются на этапе компиляции). Используется парсером и компилятором для разбора исходного текста и создания исполняемого файла.
Module - класс для модуля
- Хранение объектов модуля (shared_ptr) и добавляет weak_ptr в глобальный список объектов в RunTime
Context - класс для хранения временных данных при выполнении программы
- Один класс создается сразу при создании RunTime
- В дальнейшем создается по одному объекту для каждого нового потока (:Thread)
- Хранение списка объектов (weak_ptr
) - Хранение локальных объектов (ObjPtr), которые создаются на этапе выполнения
Исходный текст -> Парсинг -> AST (TermPtr) -+-> Компиляция в модуль (LLVM) -> Выполнение модуля | +-> Интерпретация (Выполнение AST)
Obj - Универсальный класс для хранения данных любого типа. VarData - класс для реалиазации переменных с возможностью хранения нативных типов в чистом виде без использования класса Obj (для увеличения производительсости)
Реализация загрузки модулей и пакетов
Загрузка модулей происодит следующим образом. Когда во время парсинга исходного текста встречается команда загруки модуля, создается отдельный экземпляр парсера, которому на вход подается исходный текст загружаемого модуля.
Загружаемый модуль парсится как обучный файл (включая обработку вложенных модулей), после чего парсер завершает работу. В результате получается отдельное AST загружаемого модуля и общая база макросов. После этого в AST модуля раскрываются области имен, производится проверка имен объетов и создание единой базы глобальных объектов.
После проверки отдельного AST модуля, обработка текущего файла моедт быть прожолжена. После завершения обарботки файла раскрываются области имен, производится проверка имен объетов и создание единой базы глобальных объектов как и в случае с обработко отдельного AST модуля.
При такой схеме работы, компиляция отдельных AST у каждого модуля может производиться параллельно с остальными моделями, а создание общего исоплняемого файла после компиляции всех используемых модулей.
Загрузка пакета обработывается точто таким же образом, как и загрузка моделя.
Шаги сборки компилятора
- Сборка
nlc
- Генерация с помощью
nlc --no-runtime --no-dsl -emit-cpp
модуля dsl - Сборка модуля dsl
- Генерация с помощью
nlc --no-runtime -emit-cpp
пакета runtime - Сборка пакета runtime
В результате имеем готовый nlc с модулями runtime.nlm и dsl.nlm, а заодно и проверяем:
- генерацию С++ кода без макросов
- сборку модуля
- загрузку модуля
- генерацию С++ кода с макросами
- сборку пакета
- загрузку пакета
Выполнение тестов с модулями runtime.nlm и dsl.nlm
Опции компилятора
- -no-dsl - не использовать автоматически загружаемый модуль dsl
- -no-runtime - не использовать автоматически загружаемый модуль runtime
- -emit-cpp - генерировать выходной *.cpp файл
Эта инициализация позаимствована из C. Инициализируемые члены могут быть опущены и не только в конце, для них гарантируется инициализация по умолчанию. В отличие от C, порядок членов изменять нельзя, он должен быть таким же, как и при объявлении.