Пишу игрушечный компилятор на scala. Сам целевой язык выглядит как scala, но представляет собой открытое поле для экспериментов.
После нескольких больших рефакторингов я не могу найти хороший способ смоделировать мое абстрактное синтаксическое дерево. Я хотел бы использовать средства сопоставления с образцом scala, проблема в том, что дерево несет движущуюся информацию (, такую как типы, символы )в процессе компиляции.
Я вижу пару решений, ни одно из которых мне не нравится:
классы case с изменяемыми полями (Я полагаю, что это делает компилятор scala):проблема в том, что эти поля отсутствуют на каждом этапе компиляции и, следовательно, должны быть обнулены (или опционированы ), и становится очень тяжело отлаживать/писать код. Более того, если, например, я нахожу узел с нулевым типом после фазы ввода, мне очень трудно найти причину ошибки.
огромная иерархия классов трейтов/кейсов :что-то вроде Node, NodeWithSymbol, NodeWithType,... Кажется, писать и работать с этим сложно
что-то полностью ручной работы с экстракторами
Я также не уверен, что это хорошая практика - использовать полностью неизменяемый AST,особенно в scala, где нет неявного совместного использования (, потому что компилятор не знает о неизменяемости ), и постоянное копирование дерева может повредить производительности.
Можете ли вы придумать элегантный шаблон для моделирования моего дерева с использованием мощной системы типов scala?