Переезд на паттерн "Посетитель"
Текущая реализация абстрактного синтаксического дерева требует перехода к указанному паттерну.
| File | Coverage | Branches | Missing | |
|---|---|---|---|---|
| All files | 42% |
37% |
:white_check_mark: | |
| HydraScript.Lib.BackEnd.AddressedInstructions | 90% |
85% |
:white_check_mark: | 23 82 |
| HydraScript.Lib.BackEnd.Instructions.WithJump.Goto | 81% |
100% |
:white_check_mark: | 9 14-15 |
| HydraScript.Lib.BackEnd.Instructions.WithAssignment.Simple | 32% |
16% |
:white_check_mark: | 32-48 58-66 77-84 86-90 |
| HydraScript.Lib.BackEnd.Instructions.WithAssignment.ComplexData.Write.DotAssignment | 68% |
50% |
:white_check_mark: | 22 |
| HydraScript.Lib.BackEnd.Instructions.WithAssignment.ComplexData.Write.IndexAssignment | 93% |
100% |
:white_check_mark: | 22 |
| HydraScript.Lib.BackEnd.Instructions.WithAssignment.ComplexData.Read.DotRead | 0% |
100% |
:x: | 11-28 |
| HydraScript.Lib.BackEnd.Instructions.WithAssignment.ComplexData.Read.IndexRead | 0% |
100% |
:x: | 11-26 |
| HydraScript.Lib.BackEnd.Addresses.HashAddress | 70% |
50% |
:white_check_mark: | 17 |
| HydraScript.Lib.BackEnd.Addresses.Label | 69% |
50% |
:white_check_mark: | 17 |
Minimum allowed coverage is 20%
Generated by :monkey: cobertura-action against 8154d4d153f877a8bb7d99377da572f400d193d9
В процессе рефакторинга стало ясно, что нужна новая система хранения инструкций, поскольку не ясно, как при их создании задавать им адрес
При этом механизм адресации должен быть независимым. То есть само хранилище инструкций назначает адреса, а не поставщик вроде AST
В процессе перехода было принято решение упростить кодогенерацию.
Из недостатков - увеличение объёма IR.
Пример: x = (1 + 3) + 5

t1 = 1
t2 = 3
t3 = t1 + t2
t4 = 5
t5 = t4 + t3
x = t5
https://web.eecs.umich.edu/~weimerw/2016-ldi/ca2.html
Сейчас 80% кодогенерации переведено на visitor'ы. Оставшиеся 20 затрагивают работу с некорректно составленной грамматикой, поэтому сейчас ветка отпочкуется на её исправление.
Текущая реализация системы семантического анализа выглядит крайне запутанной. Она пытается за один проход по AST сделать всё и сразу, причём часть ответственности за заполнение таблиц символов лежит на парсере.
Как минимум, требуется разделить семантический анализ на объявление и инициализацию.
https://courses.cs.washington.edu/courses/cse401/07au/CSE401-07sem.pdf
По итогу реализации семантического анализа, такой фрагмент кода:
let x = f();
function f(){
console.log(x);
return 5;
}
Должен выдавать ошибку: Cannot access 'x' before initialization
В процессе перехода было принято решение упростить кодогенерацию.
Из недостатков - увеличение объёма IR.
Пример:
x = (1 + 3) + 5![]()
t1 = 1 t2 = 3 t3 = t1 + t2 t4 = 5 t5 = t4 + t3 x = t5
Здесь всё же получилось обойти проблему, инструкции генерируются в небольшом объёме
По итогу реализации семантического анализа, такой фрагмент кода:
let x = f(); function f(){ console.log(x); return 5; }Должен выдавать ошибку:
Cannot access 'x' before initialization
Сохранять вместе с символом его состояние на момент прохода по дереву: объявлен/инициализирован
По итогу реализации семантического анализа, такой фрагмент кода:
let x = f(); function f(){ console.log(x); return 5; }Должен выдавать ошибку:
Cannot access 'x' before initialization
оказалось, что в TypeScript это ошибка рантайма
В классе FunctionSymbol поле Body, хранящее ссылку на объявление функции (узел FunctionDeclaration), должно быть удалено
inline типы после двоеточия надо запретить:
let x: {y: number} = {
y: 1
}
let f: () => null = () => null
код выше уродливая бессмыслица
inline типы после двоеточия надо запретить:
let x: {y: number} = { y: 1 } let f: () => null = () => nullкод выше уродливая бессмыслица
Оказалось, что запрета можно избежать
Реализация методов хромает. Нужно рассмотреть другой подход, какие-то мысли можно подчерпнуть из
https://groups.seas.harvard.edu/courses/cs153/2018fa/lectures/Lec11-Objects.pdf
https://citeseerx.ist.psu.edu/document?repid=rep1&type=pdf&doi=160489e8b12cd9a44cbff0cd85fb6aa05437d1ac