Управление памятью для типов на сложных языках

У меня возникла небольшая проблема для написания управления памятью в отношении внутреннего представления типов в компиляторе для статически типизированных сложных языков. Рассмотрим простой фрагмент кода на С++, который легко демонстрирует тип, который ссылается на себя.

class X {
    void f(const X&) {}
};

Типы могут иметь почти бесконечно сложные отношения друг с другом. Итак, как процесс компилятора, как вы убедитесь, что они правильно собраны?

До сих пор я решил, что сборка мусора может быть правильным способом, и я не буду слишком доволен, потому что хочу написать компилятор на С++, или, альтернативно, просто оставить их и никогда не собирать их для жизни фазы компиляции, для которой они необходимы (который имеет очень фиксированный срок службы), а затем собирать их все потом. Проблема в том, что если у вас было много сложных типов, вы могли бы потерять много памяти.

Ответ 1

Управление памятью легко, просто используйте дескриптор типа table-name- > для каждого области объявления. Типы уникально идентифицируются по имени, независимо от того, насколько сложна вложенность. Даже рекурсивный тип по-прежнему остается только одним типом. Поскольку tp1 говорит правильно, вы обычно выполняете несколько проходов, чтобы заполнить все пробелы. Например, вы можете проверить, что имя типа известно в первом проходе, а затем вычислить все ссылки, а затем вы вычислите тип.

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

Ответ 2

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

  • Определения функций зависят от определений типов и деклараций функций.
  • Определения типов зависят от объявлений функций и типов (и определения содержащихся типов)
  • Объявления функций зависят от деклараций типов

В вашем примере график зависимостей f_def -> X_def -> f_decl -> X_decl.

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