Skip to content
← Back

src/ir/values/null_coalesce.ghul

1
namespace IR.Values is
2
use Semantic.Types.Type;
3
4
// The result of `a ?? b` for a reference-typed `a: T?`. `T?` is a
5
// reference that may be null at IL, so a single dup-and-branch is
6
// enough — `b` is evaluated only when `a` is null.
7
//
8
// <left IL> // [..., a]
9
// dup // [..., a, a]
10
// brtrue.s <end> // pops the top a; non-null leaves the
11
// // other a on the stack at end
12
// pop // [...]
13
// <right IL> // [..., b]
14
// <end>:
15
//
16
// Built by COMPILE_OPERATORS.visit_binary when the operator is `??`.
17
// The two operands are evaluated by their own Values; this Value
18
// composes the surrounding short-circuit shell.
19
class NULL_COALESCE: Value is
20
left: Value;
21
right: Value;
22
_result_type: Type;
23
24
type: Type => _result_type;
25
is_lightweight_pure: bool => false;
26
27
init(left: Value, right: Value, result_type: Type) is
28
super.init();
29
30
self.left = left;
31
self.right = right;
32
self._result_type = result_type;
33
si
34
35
gen(context: IR.CONTEXT) is
36
let end_label = IR.LABEL();
37
38
gen(left, context);
39
context.write_line("dup");
40
context.write_line("brtrue.s {end_label}");
41
context.write_line("pop");
42
gen(right, context);
43
context.write_line("{end_label}:");
44
si
45
46
to_string() -> string =>
47
"null-coalesce:[{type}]({left},{right})";
48
si
49
si