Репозитарий
Размышления
Здесь будем писать наше видиние репозитария, требования, необходимая функциональность и т.д. Когда дойдет дело до его реализации будем иметь хотябы список требований, поэтом прошу не ленится и активно постить свое мнение/видение всего этого.
Для начала, раз уж у нас компилятор базируется на асис (вернее большая часть фронтенда работает именно в терминах асиса) думаю логичным сделать хранение в репозитарии информации о compilation_unit (возможно Element, тут уж поправьте) как о основной действующей единице в асисе.
Юнит_Репозитария
Назначение - хранение информации о compilation_unit, его связях и т.д.
Свойства
- ссылка на исходник_репозитария (см. исходник_репозитария)
- тело (или спецификация) - указатель на тело/спецификацию
- контрольная сумма (данного юнита)
- время последней компиляции
- затраченое на компиляцию время
- родитель - указатель на родителя
- дети - список указателей на детей (древовидная структура)
- опционально для тела - список указателей на подмодули (древовидная структура)
- завищу - список указателей на юниты от которых завишу семантически (древовидная структура)
- зависят - список модулей которые зависят от меня семантически (древовидная структура)
- тела которые от меня зависят - список тел которые зависят от меня семантически (древовидная структура)
- паргмы примененные к юниту (A_Pure_Pragma, A_Preelaborate_Pragma, An_Elaborate_Body_Pragma)
Описание:
- Asis.Compilation_Units.Relations
- Надо быстро переключатся с тела на спецификацию и наоборот, т.е. эта связь должна быть "зафиксирована" неким образом, возможно даже необходимо модифицировать реализацию самих element/compilation_unit
- Для каждого compilation_unit хранить взаимосвязи 2 видов, предок-наследник и семантически_зависит/сематически зависим, причем связь должна біть двухсторонней, т.е. если 1 модуль зависит от 2 то у 2 надо ставить обратную зависимоть (т.е. от 2 модуля зависит 1), єто позволит "ходить" по дереву зависимости вверх/вниз. Тут необходимо оговорить трабл на который я сам наскочил, родительские зависимости немогут быть циклическими - это понятно, а вот с сематическими зависимостями не совсем так, для спецификаций надо контролировать циклическую зависимость, для тел нет, поскольку от самого тела никто не зависит. Видимо имеет смысл организовывать 3 списка зависимости 1 - родитель/предок, 2 - семантичяеская зависимость спецификаций, 3 - семантическая зависимость тел. По поводу 3 списка можно посмотреть в Asis.Compilation_Units.Relations.Utils Tree_Node:Body_Dependences там находятся пакеты от которых зависит тело, к сожалению обратной связи пакета от которого зависит тело с этим самым телом нет, этого и не требовалось, но впринципе это может понадобится, для быстрого определения инконсистент пакетов. Кроме самой связи в этом списке надо хранить контрольную_сумму того юнита от которого зависим при которой компилировался данный юнит. Таким образом мы сможем отловить необходимость перекомпиляции, пробегаем по списку от кого зависим и сравнимаем суммы. Нужно ли в подобных списках содержать весь набор юнитов или содержать только юниты "первой руки" вопрос. Думаю для работы достаточно содержать только непосредственных поставщиков/потребителей, остальных можно выявить рекурсией пройдясь по наследникам допустим первых и т.д. Но для быстрой работы некоторых алгоритмов возможно понадобится полный список. Тут нужно думать.
- Для Asis.Compilation_Units.Times необходимо в свойствах юнита хранить время последней компиляции, контрольную сумму исходника, время затраченое на компиляцию данного юнита.
Исходник_Репозитария
Назначение - хранение информации о исходном файле целиком, юнитах в него входящих и т.д.
Свойства
- контрольная сумма (файла целиком)
- юниты - список указателей на юнитов_репозитария, которые содержатся в данном файле
- паргмы применимые к файлу целиком
- ключи компиляции
Описание: Для избежания дублирования именно этих прагм необходимо, видимо, создать надструктуру описывающаю весь исходный файл целоком. Это, во первых позволит избежать дублирования общих прагм, ключей компиляции и всего остального, что применяется к исходному файлу целиком, во вторых позволит быстро открывать контекст, так как мало знать что исходник не менялся, надо по нему еще и построить compilation_unit, для того чтоб небыло необходимости снова парсить и разбирать исходник, подобный "обект" необходим.
ну и пока все ;)
Коментарий by max 28.02.2008
Я тут думал над опцией --with_needed_units, заставляющей ASIS читать все модули необходимые для построение программы. С одной стороны эта опция нужна для полноценной работы Asis.Compilation_Units.Relations, с другой стороны это повлечет полный разбор всех текстов программы и построение синтаксического дерева, всех зависимостей и прочей кухни для работы на уровне Asis.Element. Это может требовать больших ресурсов для больших программ и посути бесполезно.
ASIS предлагает как бы двухслойный API для использования.
- На уровне Asis.Compilation_Unit, для работы с модулями и их зависимостями и свойствами. На этом уровне работает, например, binder.
- На уровне Asis.Element, для работы с отдельными синтаксическими элементами. На этом уровне работают большенство программ на ASIS.
Обычно программа работает или на одном уровне или на другом. Биндер не лазит во внутринности модулей, "остальные программы" не интересуются отношениями между модулями.
Наша модель "все в памяти" нормально (в плане производительности) реализует API уровня Asis.Element. И, повидимому, не подходит сильно подходит для API уровня Asis.Compilation_Unit. Для этого уровня и нужен репозиторий. Чтобы раз обработав модуль и сохранив его данные в репозитории, в последствии нам больше не нужно было делать полный разбор его исходного текста.
Т.е. все функции Asis.Compilation_Units и Asis.Compilation_Units.* должны работать "из репозитория". А разбор текстов (или чтение прекомпилированного вида модуля) должен выполняться только при запросе пользователя Asis.Elements.Unit_Declaration или Context_Clause_Elements.
Реализовано
- Словарик для идентификаторов/названий/ключевых фраз Словарик. Позволяет оперировать не строковыми литералами а соответствующими "Идентификаторами"