use v6;
sub find_first(@list, Matcher $matcher --> Int)
{
@fl = @list.grep($matcher);
if @fl.elems >= 0
{
for @list.kv -> $i, $v
{
return $i if $v eqv @fl[0];
}
}
return Int;
}
class Symbol
{
our @!strlist;
has Int $!index
submethod BUILD(Str $data)
{
Int $ix = find_first(@!strlist, { $_.k eq $data });
if $ix.defined
{
@!strlist[ix].v++;
$!index = $ix;
}
else
{
$!index = @!strlist.elems;
@!strlist.push($data => 1);
}
}
multi method new(Str $data)
{
return self.bless(*, :$data);
}
submethod DESTROY()
{
@!strlist[$!index].v--;
if @!strlist[$!index].v == 0
{
@!strlist.splice($!index, 1);
}
}
multi method Str() is export
{
@!strlist[$!index].k;
}
}
multi sub infix:<cmp>(Symbol $x, Symbol $y) is deep
{
return $x.Str cmp $y.Str;
}
multi sub infix:<cmp>(Symbol $x, $y) is deep
{
return $x.Str cmp ~$y;
}
multi sub infix:<cmp>($y, Symbol $x) is deep
{
return ~$x. cmp $y.Str;
}
my $a = Symbol.new('lol');
my $b = Symbol.new('wut');
"$a {$a.WHERE}".say
"$b {$b.WHERE}".say;
"----------------".say;
my $x = Symbol.new('lol');
my $y = Symbol.new('wut');
"$x {$x.WHERE}".say
"$y {$y.WHERE}".say;
dXNlIHY2OwoKc3ViIGZpbmRfZmlyc3QoQGxpc3QsIE1hdGNoZXIgJG1hdGNoZXIgLS0+IEludCkKewogICAgQGZsID0gQGxpc3QuZ3JlcCgkbWF0Y2hlcik7CiAgICBpZiBAZmwuZWxlbXMgPj0gMAogICAgewogICAgICAgIGZvciBAbGlzdC5rdiAtPiAkaSwgJHYKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiAkaSBpZiAkdiBlcXYgQGZsWzBdOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiBJbnQ7Cn0KCmNsYXNzIFN5bWJvbAp7CiAgICBvdXIgQCFzdHJsaXN0OwogICAgaGFzIEludCAkIWluZGV4CiAgICAKICAgIHN1Ym1ldGhvZCBCVUlMRChTdHIgJGRhdGEpCiAgICB7CiAgICAgICAgSW50ICRpeCA9IGZpbmRfZmlyc3QoQCFzdHJsaXN0LCB7ICRfLmsgZXEgJGRhdGEgfSk7CiAgICAgICAgaWYgJGl4LmRlZmluZWQKICAgICAgICB7CiAgICAgICAgICAgIEAhc3RybGlzdFtpeF0udisrOwogICAgICAgICAgICAkIWluZGV4ID0gJGl4OwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICAkIWluZGV4ID0gQCFzdHJsaXN0LmVsZW1zOwogICAgICAgICAgICBAIXN0cmxpc3QucHVzaCgkZGF0YSA9PiAxKTsKICAgICAgICB9CiAgICB9CiAgICAKICAgIG11bHRpIG1ldGhvZCBuZXcoU3RyICRkYXRhKQogICAgewogICAgICAgIHJldHVybiBzZWxmLmJsZXNzKCosIDokZGF0YSk7CiAgICB9CgogICAgc3VibWV0aG9kIERFU1RST1koKQogICAgewogICAgICAgIEAhc3RybGlzdFskIWluZGV4XS52LS07CiAgICAgICAgaWYgQCFzdHJsaXN0WyQhaW5kZXhdLnYgPT0gMAogICAgICAgIHsKICAgICAgICAgICAgQCFzdHJsaXN0LnNwbGljZSgkIWluZGV4LCAxKTsKICAgICAgICB9CiAgICB9CgogICAgbXVsdGkgbWV0aG9kIFN0cigpIGlzIGV4cG9ydAogICAgewogICAgICAgIEAhc3RybGlzdFskIWluZGV4XS5rOwogICAgfQp9CgptdWx0aSBzdWIgaW5maXg6PGNtcD4oU3ltYm9sICR4LCBTeW1ib2wgJHkpIGlzIGRlZXAKewogICAgcmV0dXJuICR4LlN0ciBjbXAgJHkuU3RyOwp9CgptdWx0aSBzdWIgaW5maXg6PGNtcD4oU3ltYm9sICR4LCAkeSkgaXMgZGVlcAp7CiAgICByZXR1cm4gJHguU3RyIGNtcCB+JHk7Cn0KCm11bHRpIHN1YiBpbmZpeDo8Y21wPigkeSwgU3ltYm9sICR4KSBpcyBkZWVwCnsKICAgIHJldHVybiB+JHguIGNtcCAkeS5TdHI7Cn0KCm15ICRhID0gU3ltYm9sLm5ldygnbG9sJyk7Cm15ICRiID0gU3ltYm9sLm5ldygnd3V0Jyk7CiIkYSB7JGEuV0hFUkV9Ii5zYXkKIiRiIHskYi5XSEVSRX0iLnNheTsKIi0tLS0tLS0tLS0tLS0tLS0iLnNheTsKbXkgJHggPSBTeW1ib2wubmV3KCdsb2wnKTsKbXkgJHkgPSBTeW1ib2wubmV3KCd3dXQnKTsKIiR4IHskeC5XSEVSRX0iLnNheQoiJHkgeyR5LldIRVJFfSIuc2F5Ow==