One of the interesting things about Rakudo is that you can embed Parrot assembly code (PIR to be exact) into Perl 6 code. With this you can optimize critical parts of the code and you can expose additional Parrot features to Perl 6. Let’s start with a hello-world example:
Q:PIR {
say "Hello world"
};
Though it is not obvious right now, the stuff inside the Q:PIR { ... }; is parrot code.
Parameters
Of course, embedded Parrot code would be pretty useless if you couldn’t send parameters in and get results out. Here is a simple Parrot routine that takes two parameters, adds then and returns the result:
sub ($a,$a) = (3,4);
sub $result = Q:PIR {
# Input.
$P0 = find_lex '$a'
$P1 = find_lex '$b'
# Compute the sum.
$I0 = $P0
$I1 = $P1
$I2 = $I0 + $I1
# Return it.
%r = box $I2
};
say $result;
Yes, that’s quite verbose. PIR is not much higher level than an assembly language. The $P0, $P1, … are Parrot registers. The $P* registers hold Parrot objects, and the $I* registers hold integers. A more interesting example would be a factorial function:
sub factorial(Int $n where {$n >= 0}) {
return 1 if $n == 0;
return Q:PIR {
# Define variables.
.local int ans, n
# Input.
$P0 = find_lex '$n'
n = $P0
# Compute the answer.
ans = 1
LOOP:
ans *= n
n -= 1
if n > 1 goto LOOP
# Return it.
%r = box ans
};
}
say "5! = " ~ factorial(5);
Exposing Parrot libraries to Perl
A specially neat feature of embedded Parrot is that you can expose Parrot libraries to Perl. For example, Parrot comes with support for the MD5 digest function, which itself comes from the OpenSSL library:
sub md5(Str $text) {
my $binary = Q:PIR {
.local string text
.local pmc digest
# Input.
$P0 = find_lex '$text'
text = $P0
# Load digest library.
$P1 = loadlib 'digest_group'
digest = new 'MD5'
# Calculate the digest.
digest.'Init'()
digest.'Update'(text)
$S0 = digest.'Final'()
%r = box $S0
};
# Convert to hex.
return join '', map {sprintf '%02x', (ord $^a)}, $binary.comb;
}
say md5("The quick brown fox jumps over the lazy dog");
The resulting library is of course much simpler and runs much faster than anything we could code in pure Perl. And this will run wherever Rakudo is available, without the need for a separate compilation step.



