Skip to content
← Back

src/syntax/trees/statements/list.ghul

1
namespace Syntax.Trees.Statements is
2
3
use Source
4
5
use Logging
6
7
class LIST: Trees.Statements.Statement, Collections.Iterable[Statement] is
8
_statements: Collections.List[Statement]
9
statements: Collections.Iterable[Statement] => _statements
10
11
// False when the final statement of this list reached the list's
12
// terminator without the `;` that would have ended it - the shape
13
// that makes a function-body tail an implicit return value. Set by
14
// the statement-list parser; every other path leaves it true.
15
last_was_terminated: bool public
16
17
// Stamped by compile-expressions on a function body list whose
18
// final statement is an implicit tail return: the walk judges the
19
// tail against the declared return type (including the async
20
// TASK[T] wrap) while scope and flow state are live.
21
function_tail: bool public => list_state.function_tail, = value is list_state.function_tail = value si
22
23
list_state: Syntax.Process.LIST_STATE field
24
25
is_tuple_literal: bool =>
26
let l = last in
27
28
if l? then
29
l.is_tuple_literal
30
else
31
false
32
fi
33
34
// Disposal bookkeeping recorded by compile-expressions, read by
35
// IL generation; contents owned by that pass.
36
dispose_state: Syntax.Process.LIST_DISPOSAL_STATE field
37
38
variables_to_dispose: Collections.List[Semantic.Symbols.Variable] => dispose_state.variables_to_dispose!
39
40
want_dispose: bool => dispose_state.want_dispose
41
provides_value: bool => true
42
43
init(location: LOCATION, statements: Collections.List[Statement]) is
44
super.init(location)
45
46
_statements = statements
47
last_was_terminated = true
48
si
49
50
iterator: Collections.Iterator[Statement] => _statements.iterator
51
52
is_empty: bool => _statements.count == 0
53
54
last: Statement? =>
55
if _statements.count == 0 then
56
null
57
else
58
_statements[_statements.count - 1]
59
fi
60
61
set_expected_type(expected_type: Semantic.Types.Type?, error_message: string?) =>
62
let l = last in
63
64
if l? then
65
l.set_expected_type(expected_type, error_message)
66
fi
67
68
clear_expected_type() =>
69
let l = last in
70
71
if l? then
72
l.clear_expected_type()
73
fi
74
75
add_variable_to_dispose(v: Semantic.Symbols.Variable) is
76
dispose_state.add(v)
77
si
78
79
clear() is
80
super.clear()
81
dispose_state.clear()
82
list_state.clear()
83
si
84
85
clear_outputs() is
86
super.clear_outputs()
87
dispose_state.clear()
88
si
89
90
// In-place replacement of the underlying statements.
91
replace_all(new_statements: Collections.Iterable[Statement]) is
92
_statements = Collections.LIST[Statement](new_statements)
93
si
94
95
add(statement: Statement) is
96
let grown = Collections.LIST[Statement]()
97
for s in _statements do
98
grown.add(s)
99
od
100
grown.add(statement)
101
102
_statements = grown
103
si
104
105
accept(visitor: Visitor) is
106
visitor.visit(self)
107
si
108
109
walk(visitor: Visitor) is
110
if !visitor.pre(self) then
111
for s in statements do
112
visitor.enter_node(s)
113
try
114
s.walk(visitor)
115
finally
116
visitor.leave_node(s)
117
yrt
118
od
119
fi
120
121
accept(visitor)
122
si
123
si
124
si