Skip to content

Предупреждение о связанных переменных в образцах #290

@Mazdaywik

Description

@Mazdaywik

Проблема

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

В лучшем случае потеря крышки приведёт к снижению быстродействия (т.к. переменная сначала копируется, а потом сравнивается на равенство), в худшем — внесётся ошибка (т.к. значение переменной может быть иным).

Решение

Ну, очевидно нужно отлавливать такие случаи и выдавать на них предупреждение. Причём указывать можно непосредственно на переменную — переменные в дереве у Checker.ref’а имеют координаты.

Засада

Засада в том, что повторная переменная может быть намеренной частью алгоритма. Например:

DoOptTree {
0 t.OptDrive s.OptSpec s.OptAutoMarkup e.AST = 0 e.AST;
s.Cycles t.OptDrive s.OptSpec s.OptAutoMarkup e.AST
= <Log-AST ('Pass ' <Symb s.Cycles> ' (before Auto markup)') e.AST> : e.AST^
= e.AST : e.OriginAST
= <OptTree-AutoMarkup s.OptAutoMarkup e.AST> : e.AST^
= <Dec s.Cycles> : s.Cycles^
= <DriveSpecLoop s.Cycles t.OptDrive s.OptSpec e.AST> : s.Cycles^ e.AST^
= e.AST
: {
e.OriginAST = s.Cycles e.OriginAST;
e.AST^ = <DoOptTree s.Cycles t.OptDrive s.OptSpec s.OptAutoMarkup e.AST>;
}
}

DoDriveSpecLoop {
0 t.OptDrive s.OptSpec e.AST = 0 e.AST;
s.Cycles t.OptDrive s.OptSpec e.AST
= e.AST : e.OriginAST
= <DriveLoop s.Cycles t.OptDrive e.AST> : s.Cycles^ e.AST^
= <SpecPass s.Cycles s.OptSpec e.AST> : s.Cycles^ e.AST^
= e.AST
: {
e.OriginAST = s.Cycles e.OriginAST;
e.AST^ = <DoDriveSpecLoop s.Cycles t.OptDrive s.OptSpec e.AST>;
}
}

DoDriveLoop {
0 t.OptDrive e.AST = 0 e.AST;
s.Cycles t.OptDrive e.AST
= <Log-AST ('Pass ' <Symb s.Cycles> ' (before Drive)') e.AST> : e.AST^
= e.AST : e.OriginAST
= <ExpandClosures e.AST> : e.AST^
= <OptTree-Drive t.OptDrive e.AST> : e.AST^
= <Dec s.Cycles> : s.Cycles^
= e.AST
: {
e.OriginAST = s.Cycles e.OriginAST;
e.AST^ = <DoDriveLoop s.Cycles t.OptDrive e.AST>;
};
}

Все три примера проверяют, что дерево осталось неизменным с предыдущей итерации. Поэтому просто выдавать предупреждения на повторные переменные в образцах блоков и вложенных функций нельзя — будет много ложноположительных срабатываний.

Повторная переменная может быть ключом при ассоциативном поиске (по открытой переменной), а значит, тоже является частью алгоритма.

Наиболее консервативной (но и наиболее слабой) эвристикой можно рассматривать повторные переменные в присваиваниях с жёсткими образцами. Но этого мало. Нужны более тонкие эвристики для блоков и вложенных функций.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions