Skip to content
← Back

src/syntax/process/variable_left_state.ghul

1
namespace Syntax.Process is
2
use Collections;
3
4
use LOCATION = Source.LOCATION;
5
use Type = Semantic.Types.Type;
6
use Value = IR.Values.Value;
7
use VariableLeft = Trees.Variables.VariableLeft;
8
9
// Compile-expressions output for one variable binding target (a
10
// VariableLeft node). Owned by the compile-expressions pass and read
11
// by IL generation; kept here, keyed by node, rather than in fields
12
// on the node itself (see NodeStateStore).
13
class VARIABLE_LEFT_STATE is
14
// code to store into the bound variable, from the initializer
15
value: Value? public;
16
explicit_type: Type? public;
17
// the compiled initializer, if any
18
right_value: Value? public;
19
right_location: LOCATION? public;
20
variable_location: LOCATION? public;
21
22
init() is
23
si
24
si
25
26
// Entries are keyed by (file name, node id), not node object
27
// identity — see Node.node_id. Ids are never reused, so an entry
28
// orphaned by tree replacement can go stale but can never be
29
// served for a different node.
30
class VARIABLE_LEFT_STATE_STORE: NodeStateStore is
31
_state_by_file: MutableMap[string, MutableMap[int, VARIABLE_LEFT_STATE]];
32
33
name: string => "variable-left";
34
35
entry_count: int => _count_entries();
36
37
init(registry: STATE_STORE_REGISTRY) is
38
_state_by_file = MAP[string, MutableMap[int, VARIABLE_LEFT_STATE]]();
39
40
registry.register(self);
41
si
42
43
// The state recorded for `left`, or null when none has been.
44
get(left: VariableLeft) -> VARIABLE_LEFT_STATE? is
45
let by_node: MutableMap[int, VARIABLE_LEFT_STATE] mut;
46
47
if !_state_by_file.try_get_value(left.location.file_name, by_node ref) then
48
return null;
49
fi
50
51
let result: VARIABLE_LEFT_STATE mut;
52
53
if by_node.try_get_value(left.node_id, result ref) then
54
return result;
55
fi
56
57
return null;
58
si
59
60
get_or_add(left: VariableLeft) -> VARIABLE_LEFT_STATE is
61
let file_name = left.location.file_name;
62
63
let by_node: MutableMap[int, VARIABLE_LEFT_STATE] mut;
64
65
if !_state_by_file.try_get_value(file_name, by_node ref) then
66
by_node = MAP[int, VARIABLE_LEFT_STATE]();
67
_state_by_file[file_name] = by_node;
68
fi
69
70
let result: VARIABLE_LEFT_STATE mut;
71
72
if !by_node.try_get_value(left.node_id, result ref) then
73
result = VARIABLE_LEFT_STATE();
74
by_node[left.node_id] = result;
75
fi
76
77
return result;
78
si
79
80
remove(left: VariableLeft) is
81
let by_node: MutableMap[int, VARIABLE_LEFT_STATE] mut;
82
83
if _state_by_file.try_get_value(left.location.file_name, by_node ref) then
84
by_node.remove(left.node_id);
85
fi
86
si
87
88
drop_file(file_name: string) is
89
_state_by_file.remove(file_name);
90
si
91
92
clear_all() is
93
_state_by_file = MAP[string, MutableMap[int, VARIABLE_LEFT_STATE]]();
94
si
95
96
_count_entries() -> int is
97
let result mut = 0;
98
99
for by_node in _state_by_file.values do
100
result = result + by_node.count;
101
od
102
103
return result;
104
si
105
si
106
si