Skip to content
← Back

src/ir/values/all_of.ghul

1
namespace IR.Values is
2
use System.Reflection.Metadata.ILOpCode
3
4
use Semantic.Types.Type
5
6
use Ghul.Pipes
7
8
// Every one of a list of boolean values, short-circuited: the
9
// first that answers false is the answer, and the rest are never
10
// evaluated.
11
//
12
// A synthesized `=~` is a guard followed by one comparison per
13
// member followed by whatever the base contributes, and each of
14
// those is built as a value of its own. This is the conjunction
15
// around them, so that nothing has to build a tree of `/\`
16
// expressions to say `and` in.
17
//
18
// <first>
19
// brfalse <false>
20
// <second>
21
// brfalse <false>
22
// ...
23
// ldc.i4.1
24
// br <end>
25
// <false>:
26
// ldc.i4.0
27
// <end>:
28
class ALL_OF: Value is
29
operands: Collections.LIST[Value]
30
_result_type: Type
31
32
type: Type => _result_type
33
is_lightweight_pure: bool => false
34
35
init(operands: Collections.LIST[Value], result_type: Type) is
36
super.init()
37
38
self.operands = operands
39
self._result_type = result_type
40
si
41
42
gen(context: IR.CONTEXT) is
43
let body = context.current_srm_body_emitter!
44
45
// Nothing to be false: an empty conjunction is true, which
46
// is what a type with no members to compare answers once
47
// its guard has passed.
48
if operands.count == 0 then
49
body.ldc_i4(1)
50
51
return
52
fi
53
54
let false_label = IR.LABEL()
55
let end_label = IR.LABEL()
56
57
for operand in operands do
58
gen(operand, context)
59
body.branch(ILOpCode.BRFALSE, false_label)
60
od
61
62
body.ldc_i4(1)
63
body.branch(ILOpCode.BR, end_label)
64
65
body.mark_label(false_label)
66
body.ldc_i4(0)
67
68
body.mark_label(end_label)
69
si
70
71
to_string() -> string =>
72
"all-of:[{type}]({operands |> map(o => "{o}") |> join(",")})"
73
si
74
si