ThinkGeek - Cool Stuff for Geeks and Technophiles

Tuesday, July 1, 2008

grokking pir

If you're writing a compiler for the Parrot Virtual Machine, you'll need to understand Parrot Intermediate Representation (PIR). I've been slogging through the PIR documentation, and am slowly beginning to understand how it works.

PIR is not Parrot's bytecode, and it's not Parrot's assembly language. Those are PBC and PASM, respectively. PIR resembles PASM, but has some additional syntactic sugar that makes a lot of things easier. With PASM, for example, you have to assign variables to registers manually. PIR has "temporary registers" that let you assign a register type and let Parrot take it from there.

The following examples are all taken from somewhere within the Parrot documentation (although I can't locate the first one at the moment).



.sub _ :main
$P0 = new .Random
$N0 = $P0
print $N0
print "\n"
$N0 = $P0
print $N0
print "\n"
.end



This short code snippit generates random numbers. (Well, not true random numbers; I get the same two values every time I run it.) Notice the $P0 and $N0: These represent a PMC register and a numeric (floating point) register, respectively. Rather than assigning these directly to registers P0 and N0, we can use register aliases. This will be very helpful in larger programs where it might otherwise be difficult to keep track of what's available.

Here's another snippet:



.sub double
.param int arg
arg *= 2
.return(arg)
.end

.sub main :main
.local int result
result = double(42)
print result
print " was returned\n"
.end



Note the :main directive in .sub main. It is the :main directive, not the name of the sub, that tells Parrot where to start. If :main does not appear, by default the first sub will be the entry point.

Note, too, the .local int result directive in main. This is not a local variable; Parrot will assign an integer register for the result. The .param directive in the subroutine tells Parrot to expect a parameter of type int.

One more example for now:


.sub almost
.local num almost_pi
almost_pi = 22/7
print almost_pi
print "\n"
.end



I've modified this from the Parrot documentation code. almost_pi is assigned to a num (float) register; and given a value of 22/7. Although 22 and 7 are both integers, the result is a float because of the register type. If almost_pi had been an int register, the resulting value would have been 3.

Knowing PIR is essential to designing a compiler for Parrot, because all the other languages targeting Parrot are compiled to PIR. The source code for all PBC is PIR, or to put it another way, from Parrot's perspective, there is only one source language. This means that any language targeting Parrot could theoretically have access to any code written in any other language targeting Parrot, as long as they compile to compatible PIR.

More information:

Labels: ,

0 Comments:

Post a Comment

Links to this post:

Create a Link

<< Home