Creation of a Perl6 executable with Rakudo (perl6 on Parrot)

Rakudo – Perl6 on Parrot

Creation of a Perl6 executable with Rakudo (perl6 on Parrot)

Well, since Parrot 1.0 was announced yesterday, it is possible that there are already people interested in trying it, but perhaps they do not know very well how to do it. I am going to describe how to create an executable from a small example made by Patrick Michaud in Rakudo. For that we are going to install both Parrot and Rakudo locally, since I still do not see the permanent installation as very ‘smooth’.

The example we are going to use is an RPN (Reverse Polish Notation) calculator made in Perl6, which comes from an implementation previously made in Perl5; you can see the article here, it is worth reading to realise how Perl6 is evolving (pmichaud was missing a metaoperator, so he does not hold back, and he just goes and implements it 🙂 )

Well, we start by downloading and compiling Rakudo/Parrot; for that we do what we are told in its git repository.

On Debian we would need the packages: git-core, perl, make, gcc and subversion.

cd /tmp
git clone git://github.com/rakudo/rakudo.git
cd rakudo
perl Configure.pl --gen-parrot &&make

Following this procedure, we will always have a Perl6 compiler with a Parrot virtual machine that is supposed to work. Also keep in mind that I have put it in the /tmp directory, so it would be lost on a reboot of the machine; if you want to have it permanently, you have to put it in any other directory.

Well, we take the example code from the website mentioned earlier and we dump it into a text file called: “calc.p6”

my %op_dispatch_table = {
        '+'    => { .push(.pop + .pop)  },
        '-'    => { .push(.pop R- .pop) },
        '*'    => { .push(.pop * .pop)  },
        '/'    => { .push(.pop R/ .pop) },
        'sqrt' => { .push(.pop.sqrt)    },
    };
sub evaluate (%odt, $expr) {
        my @stack;
        my @tokens = $expr.split(/\s+/);
        for @tokens {
                when /\d+/     { @stack.push($_); }
                when ?%odt{$_} { %odt{$_}(@stack); }
            default        { die "Unrecognized token '$_'; aborting"; }
        }
        @stack.pop;
    }

    say "Result: { evaluate(%op_dispatch_table, @*ARGS[0]) }";

Once we have our example in the file, we only have to run it and that is it, our first program in Perl6, and it is not a simple ‘hello world’.

./perl6 calc.p6 '5 6 +'

But now we want to do something more interesting: create an executable out of that Perl6 code. No problem, we have the right tools. First we are going to tell Rakudo that the code it generates should be pir, which is the assembler that the Parrot virtual machine understands, and then through Parrot we compile it to bytecode, and from there we create an executable in the following way:

./perl6 --target=pir calc.p6 > calc.pir
./parrot/parrot -o  calc.pbc calc.pir
./parrot/pbc_to_exe calc.pbc

And there we have it. This process will be automated later on, possibly a switch will be added to the Rakudo command line so that it generates the executable without us having to do all that. Well, all that is left for us is to confirm that we have an executable, and to test it.

file calc
./calc '5 6 +'

We have to bear in mind that Parrot 1.0 means the release of Parrot with a stable API for users (a user is the language developer, not the one who uses a language). Therefore there is still quite a way to go. Even so, with the previous example you can see that something like Perl6 on Parrot is functional enough to already build applications, and there are already people creating applications of a certain size. I hope you have liked it and that someone else is encouraged to try Parrot, Rakudo, or any other language; cooperating is as simple as downloading it periodically, testing it, and if you see any bug, reporting it.