-
Notifications
You must be signed in to change notification settings - Fork 15
/
test2.pl
58 lines (51 loc) · 1.91 KB
/
test2.pl
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
57
58
# vim: ft=perl6
use Test;
my class Hash {
method new() { Q:CgOp { (box Hash (rawnew Dictionary<string,Variable>)) } }
method !extend is rawcall {
Q:CgOp {
(letn d [unbox Dictionary<string,Variable> (@ (pos 0))]
k [unbox String (@ (methodcall (pos 1) Str))]
[ternary (rawcall (l d) ContainsKey (l k))
(die "Autovivification collision")
(prog)]
[setindex (l k) (l d) (pos 2)]
[null Variable])
};
}
# TODO: We need something like pir:: notation for this to not suck
method at-key($key) {
Q:CgOp {
(box Bool (rawcall [unbox Dictionary<string,Variable> (@ (l self))]
ContainsKey [unbox String (@ (methodcall (l $key) Str))]))
}
?? Q:CgOp {
(getindex [unbox String (@ (methodcall (l $key) Str))]
[unbox Dictionary<string,Variable> (@ (l self))])
} !! Any!butWHENCE({ self!extend($key, Q:CgOp { (pos 0) }) });
}
}
sub postcircumfix:<{ }> is rawcall {
my $key ::= Q:CgOp { (pos 1) };
(Q:CgOp { (pos 0) }).defined
?? (Q:CgOp { (pos 0) }).at-key($key)
!! Any!butWHENCE(sub () is rawcall {
my $ar := Q:CgOp { (getindex (int 0) (getfield pos
(getfield outer (callframe)))) };
$ar.defined && die("Autovivification collision");
$ar = Hash.new;
$ar!extend($key, Q:CgOp { (pos 0) });
});
}
my $foo;
ok !($foo{'x'}.defined), "fetch from hash, no value";
ok !($foo.defined), "no autoviv for rvalue";
$foo{'x'} = 'foo';
is $foo{'x'}, 'foo', "values are retained";
ok !($foo{'y'}.defined), "no cross-slot leakage";
ok $foo ~~ Hash, "foo isa hash now";
$foo{'z'}{'a'} = 'pie';
is $foo{'z'}{'a'}, 'pie', "can autoviv deeply";
$foo{'y'}[2] = 'zed';
is $foo{'y'}[2], 'zed', "can mix array and hash viv";
done-testing;