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`. Two consumers, each dropping a narrow on
5
// a variable the walked subtree writes: the loop kill-set, where
6
// a narrow cannot be assumed across the back-edge, and the entry
7
// to a finally body, where a narrow proven before the try
8
// survives what the try did not write.
9
//
10
// A `Visitor` whose default per-node visits are no-ops, so only
11
// ASSIGNMENT and REFERENCE need overriding; default `pre`
12
// returns false, so the framework descends through everything.
13
class LOOP_ASSIGNMENT_COLLECTOR: Visitor is
14
names: Collections.SET[string] public
15
16
init() is
17
super.init()
18
names = Collections.SET[string]()
19
si
20
21
visit(assignment: Trees.Statements.ASSIGNMENT) is
22
let targets = Collections.LIST[Trees.Expressions.Expression]()
23
assignment.left.get_names_into(targets)
24
25
for target in targets do
26
_collect(target)
27
od
28
si
29
30
visit(reference: Trees.Expressions.REFERENCE) is
31
// `x ref` — a `ref` argument may be written by the callee.
32
_collect(reference.left)
33
si
34
35
_collect(expr: Trees.Expressions.Expression) is
36
if !isa Trees.Expressions.IDENTIFIER(expr) then
37
return
38
fi
39
40
let identifier = expr
41
42
names.add(identifier.identifier.name)
43
si
44
si
45
si