Расширяем функциональность! В прошлом чекпоинте мы создали инфраструктуру проекта, теперь необходимо соединить блоки, чтобы построить дерево scope-ов!
Необходимо создать Visitor, который строит следующие сущности:
Дерево, хранящее scope-ы всех переменных:
- в вершине дерева находится scope
- необходимо по имени переменной быстро находить ссылку на объект, к которому обращаемся (см. алгоритм с построением дерева scope-ов через stack)
Для чего мы строим это дерево? Оно поможет нам обработать следующие вещи:
- по токену понимать, какого он будет типа
- по токену понимать, вызывать ее надо или использовать как тип переменной класса
- если токен - переменная, то какой сдвиг у нее от начала стека
- если токен - это конструктор класса, то сколько памяти надо выделять
- если токен - массив, то сколько памяти под нее надо выделять при создании new
При этом листами в дереве scope-ов должны ссылаться на построенную таблицу символов (где хранятся сигнатуры методов и классов), где:
- для методов фиксируется имена принимаемых аргументов, а также имя этого метода
- для классов фиксируется его имя, список методов и его полей (напоминаем - все методы публичные, все поля - приватные)
- (задание со звездочкой) - подумайте, как можно было бы обработать конструктор класса
Важные случаи, которые необходимо при этом обработать:
- Необходимо обработать shadowing-переменных (одна переменная закрывает другую)
- Переменная дважды объявляется в одном scope
- Переменная используется, хотя она не объявлена