Skip to content
← Back

src/syntax/process/loop_assignment_collector.ghul

1
namespace Syntax.Process is
2
// Collects the names of variables written within a walked
3
// subtree — by assignment (`=`, including destructuring) or by
4
// being passed `ref`. Used to compute the loop kill-set: a
5
// narrow on a variable the loop body writes cannot be assumed
6
// across the back-edge and is dropped; a narrow on a variable
7
// the body never writes survives the loop.
8
//
9
// A `Visitor` whose default per-node visits are no-ops, so only
10
// ASSIGNMENT and REFERENCE need overriding; default `pre`
11
// returns false, so the framework descends through everything.
12
class LOOP_ASSIGNMENT_COLLECTOR: Visitor is
13
names: Collections.SET[string] public;
14
15
init() is
16
super.init();
17
names = Collections.SET[string]();
18
si
19
20
visit(assignment: Trees.Statements.ASSIGNMENT) is
21
let targets = Collections.LIST[Trees.Expressions.Expression]();
22
assignment.left.get_names_into(targets);
23
24
for target in targets do
25
_collect(target);
26
od
27
si
28
29
visit(reference: Trees.Expressions.REFERENCE) is
30
// `x ref` — a `ref` argument may be written by the callee.
31
_collect(reference.left);
32
si
33
34
_collect(expr: Trees.Expressions.Expression) is
35
if !isa Trees.Expressions.IDENTIFIER(expr) then
36
return;
37
fi
38
39
let identifier = expr;
40
41
names.add(identifier.identifier.name);
42
si
43
si
44
si