update: see Inline::Parrot for the most current code.

I couldn't find an implementation of Inline::Parrot, so I thought maybe I could try to write one.

This is a slow-but-it-works version of the module that can execute Parrot Intermediate Representation (pir) code using pure Perl.

I tested this in MS Windows, with Activestate Perl 5.8.0, and a pre-built Parrot obtained from http://www.jwcs.net/developers/perl/pow/. I installed Inline using ppm.

It can execute this sample code:

use Inline Parrot; print "Start Perl\n"; _hello( 'int count' => 5, name => 'test' ); print "End Perl\n"; __END__ __Parrot__ .sub _hello .param int count .param string name print "Hello world\n" print count print " " print name print "\n" ret .end

Output:

Start Perl
Hello world
5 test
End Perl

I've got some ideas on how to improve this, but I'd like to have some feedback, before I go too far.

There are still a lot of limitations, but most are fixable:
- the Perl parameter 'int count' should be written just 'count', but I'm not parsing the ".param" line yet.
- only 1 subroutine can be defined. This is also a simple parsing problem.
- it doesn't retrieve return values back to Perl.
- it doesn't allow positional parameters to be specified.
- there are no options for specifying the calling mode for pir.
- it doesn't pass data structures back and forth.
- you can't pass a data structure by reference - this is not likely to be fixable, because the perl and the parrot processes don't share memory.
- the current code uses temporary files for interprocess communication; it doesn't reuse the compiled code between calls; it has problems if two or more processes use the same source code. These problems are all fixable by using proper IPC with Open3 or sockets.

package Inline::Parrot; $VERSION = '0.01'; require Inline; @ISA = qw(Inline); use strict; use Carp; use File::Spec; sub register { return { language => 'Parrot', aliases => ['parrot', 'pasm', 'pir'], type => 'interpreted', suffix => 'pir', }; } sub usage_config { my $key = shift; "'$key' is not a valid config option for Inline::Parrot\n"; } sub usage_config_bar { "Invalid value for Inline::Parrot config option BAR"; } sub validate { my $o = shift; $o->{ILSM}{PATTERN} ||= 'parrot-'; $o->{ILSM}{BAR} ||= 0; while (@_) { my ($key, $value) = splice @_, 0, 2; if ($key eq 'PATTERN') { $o->{ILSM}{PATTERN} = $value; next; } if ($key eq 'BAR') { croak usage_config_bar unless $value =~ /^[01]$/; $o->{ILSM}{BAR} = $value; next; } croak usage_config($key); } } sub build { my $o = shift; my $code = $o->{API}{code}; my $pattern = $o->{ILSM}{PATTERN}; $code =~ s/$pattern//g; $code =~ s/bar-//g if $o->{ILSM}{BAR}; my ( $sub_name ) = $code =~ m/\.sub\s+(\w+)/s; my $path = File::Spec->catdir($o->{API}{install_lib},'auto',$o->{A +PI}{modpname}); my $obj = $o->{API}{location}; $o->mkpath($path) unless -d $path; open PARROT_OBJ, "> $obj" or croak "Can't open $obj for output\n$!"; print PARROT_OBJ $code; close \*PARROT_OBJ; } sub load { my $o = shift; my $obj = $o->{API}{location}; open PARROT_OBJ, "< $obj" or croak "Can't open $obj for output\n$!"; my $code = join '', <PARROT_OBJ>; close \*PARROT_OBJ; #warn "Load $code\n"; #warn "Package $o->{API}{pkg}\n"; my ( $sub_name ) = $code =~ m/\.sub\s+(\w+)/s; #warn "Sub $sub_name\n"; my $obj_normalized = $obj; $obj_normalized =~ tr/\\/\//; # Windows OS my $cmd = " package $o->{API}{pkg} ; \n" . " sub $sub_name { \n" . ' my @param_keys; my $skip; for ( @_ ) { push @param_keys, $_ if $skip = ! $skip; } my %param = @_; my $local_params; for ( @param_keys ) { my $name = $_; $name = "string " . $name unless $name =~ /\s/; $local_params .= " .local $name\n"; } my $value_params; for ( @param_keys ) { my $name = ( split ( /\s+/, $_ ) )[-1]; $value_params .= " $name = \"$param{$_}\"\n"; } my $arg_params; for ( reverse @param_keys ) { my $name = ( split ( /\s+/, $_ ) )[-1]; $arg_params .= " .arg $name \n"; } my $cmd = \' .pragma fastcall ' . $code . ' .sub _start_' . $sub_name . ' @MAIN # print "starting parrot\\n" \' . $local_params . \' \' . $value_params . \' \' . $arg_params . \' call ' . $sub_name . ' # print "ending parrot\\n" end .end \' ; ' . <<EOT; open PARROT_OBJ, ">", "$obj_normalized.pir" or die "Can't open $obj_normalized.pir for output\\n$!"; print PARROT_OBJ \$cmd; close \*PARROT_OBJ; open( PARROT_RUN, "|-", "parrot $obj_normalized.pir" ) or die "Can't open $obj_normalized.pir for output\\n$! +"; close( PARROT_RUN ); } EOT #warn "Cmd $cmd [end Cmd]\n"; #warn "Eval\n" . $cmd . "\n"; eval $cmd; croak "Unable to load Parrot module $obj:\n$@" if $@; } sub info { my $o = shift; } 1; __END__

In reply to Inline::Parrot by fglock

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.