/
Case.pm6
56 lines (49 loc) · 1.32 KB
/
Case.pm6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
use Red::AST;
use Red::AST::Infixes;
use Red::AST::Value;
unit role Red::AST::Optimizer::Case;
my subset AstFalse of Red::AST::Value where { .value === False };
my subset AstTrue of Red::AST::Value where { .value === True };
multi method optimize(
Red::AST:U :$case,
Red::AST :%when! where {
.elems == 1 && .values.head.?type ~~ Positional
},
Red::AST :$else
) {
%when.values.head.get-value<>
}
multi method optimize(
Red::AST :$case,
Red::AST :%when! where {
.first: { .key ~~ AstTrue }
},
Red::AST :$else
) {
%when.first({ .key ~~ AstTrue }).value.self
}
multi method optimize(
Red::AST:U :$case,
Red::AST :%when! where {
.elems == 1 and not .keys.head.defined
},
Red::AST :$else
) {
%when.values.head
}
multi method optimize(
Red::AST:U :$case,
Red::AST :%when! where {
.elems == 2
&& Red::AST::AND.new(|.keys) ~~ AstTrue
},
Red::AST:U :$else
) {
my $to-remove = %when.keys.first(Red::AST::So) // %when.keys.head;
self.bless: :else(%when{$to-remove}:delete), :%when
}
multi method optimize(:$case, :%when, :$else) {
my Red::AST %filteredWhen{Red::AST} = %when.grep: { .key !~~ AstFalse };
die "No conditions passed to CASE/WHEN" unless %filteredWhen;
self.bless: :$case, :when(%filteredWhen), :$else
}