On Wednesday 16 August 2006 08:57, jerry gay wrote: > i'll happily test, but i can't apply it, as it seems not to be in the > format my patch util expects. did you use C<diff -u>? i don't see the > familiar "Index: <filename>" headers.
It's a standard svk diff. That's really weird. Is this any better? -- c
--- MANIFEST (revision 20216) +++ MANIFEST (local) @@ -201,6 +201,7 @@ config/gen/makefiles/dynpmc.in [] config/gen/makefiles/dynpmc_pl.in [] config/gen/makefiles/editor.in [] +config/gen/makefiles/ext.in [] config/gen/makefiles/languages.in [] config/gen/makefiles/parrot.pc.in [] config/gen/makefiles/past.in [] @@ -637,6 +638,15 @@ examples/tge/branch/lib/Branch.pir [main]doc examples/tge/branch/lib/Leaf.pir [main]doc examples/tge/branch/transform.pir [main]doc +ext/Parrot-Embed/t/embed.t [devel] +ext/Parrot-Embed/t/greet.pir [devel] +ext/Parrot-Embed/lib/Parrot/Embed.xs [devel] +ext/Parrot-Embed/lib/Parrot/Embed.pm [devel] +ext/Parrot-Embed/Changes [devel] +ext/Parrot-Embed/MANIFEST [devel] +ext/Parrot-Embed/typemap [devel] +ext/Parrot-Embed/Build.PL [devel] +ext/Parrot-Embed/README [devel] include/parrot/builtin.h [main]include include/parrot/caches.h [main]include include/parrot/cclass.h [main]include --- config/gen/makefiles/root.in (revision 20216) +++ config/gen/makefiles/root.in (local) @@ -186,6 +186,7 @@ compilers/tge/Makefile \ compilers/bcg/Makefile \ editor/Makefile \ + ext/Makefile \ languages/Makefile \ languages/amber/Makefile \ languages/APL/Makefile \ --- config/gen/makefiles/ext.in (revision 20216) +++ config/gen/makefiles/ext.in (local) @@ -0,0 +1,64 @@ +# $Id: /parrotcode/offline/config/gen/makefiles/languages.in 19764 2006-08-03T18:17:04.907999Z chromatic $ + +# setup of commands [EMAIL PROTECTED]@ +PERL = @perl@ +MAKE = @make_c@ +RM_F = @rm_f@ + +# add new languages here +# remove obsolete languages here +EXT = \ + Parrot-Embed + +# the default target +all: $(EXT) + +# hard-code these for now +test: Parrot-Embed + - cd Parrot-Embed && $(PERL) Build test + +clean: Parrot-Embed + - cd Parrot-Embed && $(PERL) Build clean + +# This is a listing of all targets, that are meant to be called by users +help: + @echo "" + @echo "Following targets are available for the user:" + @echo "" + @echo " all: Make a lot of language implementations." + @echo " This is the default." + @echo " test: Unified test suite for a lot of languages." + @echo "" + @echo " clean: Clean up a lot of languages." + @echo "" + @echo " help: Print this help message." + @echo "" + @echo " smoke: Run the test suite and send smoke.html to " + @echo " http://smoke.parrotcode.org/" + @echo "" + @echo " smoke-clean: clean up smoke.html" + @echo "" + @echo "" + @echo "Following languages are available:" + @echo " $(LANGUAGES)" + @echo "A particular language <lang> can be built, tested and cleand up" + @echo " make <lang>" + @echo " make <lang>.test" + @echo " make <lang>.clean" + @echo "For the status of individual languages see LANGUAGES.STATUS.pod" + @echo "" + +clean: \ + Parrot-Embed.clean + +# +# Extension specific targets +# + +# The *.dummy targets are a replacement for the target .PHONY in 'GNU make' + +Parrot-Embed : Parrot-Embed.dummy + +Parrot-Embed.dummy: + - cd ext/Parrot-Embed && $(PERL) Build.PL && $(PERL) Build --- config/gen/makefiles.pm (revision 20216) +++ config/gen/makefiles.pm (local) @@ -117,6 +117,11 @@ replace_slashes => 1 ); genfile( + 'config/gen/makefiles/ext.in' => 'ext/Makefile', + commentType => '#', + replace_slashes => 1 + ); + genfile( 'config/gen/makefiles/parrot.pc.in' => 'parrot.pc' ); --- ext/Parrot-Embed/Build.PL (revision 20216) +++ ext/Parrot-Embed/Build.PL (local) @@ -0,0 +1,41 @@ +use strict; +use warnings; + +use Module::Build; +use ExtUtils::PkgConfig; + +my %pkg_info = ExtUtils::PkgConfig->find( 'parrot' ); + +my $class = Module::Build->subclass( + code => <<'END_HERE', + use Cwd; + + sub ACTION_build + { + my $self = shift; + my $old_dir = cwd(); + chdir 't'; + + system(qw( parrot -o greet.pbc greet.pir ) ) == 0 + or die "Cannot compile PBC for test: $?"; + + chdir $old_dir; + $self->SUPER::ACTION_build( @_ ); + } +END_HERE +); + +my $builder = $class->new( + module_name => 'Parrot::Embed', + license => 'perl', + dist_author => 'chromatic <[EMAIL PROTECTED]>', + dist_version_from => 'lib/Parrot/Embed.pm', + build_requires => { + 'Test::More' => 0, + }, + add_to_cleanup => [ 'Parrot-Embed-*' ], + extra_compiler_flags => $pkg_info{cflags}, + extra_linker_flags => $pkg_info{libs}, +); + +$builder->create_build_script(); --- ext/Parrot-Embed/Changes (revision 20216) +++ ext/Parrot-Embed/Changes (local) @@ -0,0 +1,5 @@ +Revision history for Parrot-Embed + +0.01 Date/time + First version, released on an unsuspecting world. + --- ext/Parrot-Embed/MANIFEST (revision 20216) +++ ext/Parrot-Embed/MANIFEST (local) @@ -0,0 +1,10 @@ +Build.PL +Changes +MANIFEST +META.yml # Will be created by "make dist" +README +lib/Parrot/Embed.pm +lib/Parrot/Embed.xs +t/embed.t +t/greet.pir +typemap --- ext/Parrot-Embed/README (revision 20216) +++ ext/Parrot-Embed/README (local) @@ -0,0 +1,22 @@ +Parrot::Embed +------------- + +This is the first version of an embedding interface to use Parrot from Perl 5. + +Be afraid. + +INSTALLATION + +To install this module, run the following commands: + + perl Build.PL + perl ./Build + perl ./Build test + perl ./Build install + +COPYRIGHT AND LICENCE + +Copyright (C) 2006 The Perl Foundation/chromatic + +This program is free software; you can redistribute it and/or modify it +under the same terms as Parrot itself. --- ext/Parrot-Embed/lib/Parrot/Embed.pm (revision 20216) +++ ext/Parrot-Embed/lib/Parrot/Embed.pm (local) @@ -0,0 +1,44 @@ +package Parrot::Embed; + +use strict; +use warnings; + +our $VERSION = '0.01'; + +use base 'DynaLoader'; + +Parrot::Embed->bootstrap( $VERSION ); + +1; + +__END__ + +=head1 NAME + +Parrot::Embed - use Parrot from Perl 5 + +=head1 VERSION + +Version 0.01 + +=head1 SYNOPSIS + +This module embeds libparrot in Perl 5 programs. You can load Parrot bytecode, +compile your own code, and call Parrot subroutines and send and receive values +to them. + +=head1 AUTHOR + +chromatic, C<< <chromatic at wgz.org> >> + +=head1 BUGS + +Please report any bugs or feature requests to the Parrot Porters mailing list. +Someday there may be a CPAN version of this code. Who knows? + +=head1 COPYRIGHT & LICENSE + +Copyright (c) 2006 The Perl Foundation / chromatic, all rights reserved. + +This program is free software; you can redistribute it and/or modify it +under the same terms as Parrot itself. --- ext/Parrot-Embed/lib/Parrot/Embed.xs (revision 20216) +++ ext/Parrot-Embed/lib/Parrot/Embed.xs (local) @@ -0,0 +1,133 @@ +#define PERL_NO_GET_CONTEXT +#include "EXTERN.h" +#include "perl.h" +#include "XSUB.h" +#include "parrot/parrot.h" +#include "parrot/embed.h" +#include "parrot/extend.h" + +MODULE = Parrot::Embed PACKAGE = Parrot::Embed + +Parrot_Interp +create_interpreter( ... ) +INIT: + Parrot_Interp parent; + Parrot_Interp interp; + Parrot_PackFile pf; +CODE: + if (items == 0) + { + parent = 0; + } + else if ( items == 1 ) + { + parent = INT2PTR( Parrot_Interp, SvIV( ST(0) ) ); + } + else + { + Perl_croak( aTHX_ + "Usage: Parrot::Embed::create_interpreter( [ parent ] )" ); + } + interp = Parrot_new( parent ); + pf = PackFile_new( interp, 0 ); + Parrot_loadbc( interp, pf ); + RETVAL = interp; +OUTPUT: + RETVAL + +Parrot_STRING +create_string( interp, string ) + Parrot_Interp interp + SV * string +INIT: + int length; +CODE: + length = SvLEN( string ); + RETVAL = const_string( interp, SvPVX( string ) ); +OUTPUT: + RETVAL + +Parrot_PackFile +read_bytecode( interp, filename ) + Parrot_Interp interp + char * filename +CODE: + RETVAL = Parrot_readbc( interp, filename ); +OUTPUT: + RETVAL + +void +load_bytecode( interp, packfile ) + Parrot_Interp interp + Parrot_PackFile packfile +CODE: + Parrot_loadbc( interp, packfile ); + +Parrot_PMC +find_global( interp, ... ) + Parrot_Interp interp +INIT: + SV * namespace; + Parrot_STRING p_namespace; + Parrot_STRING p_global; +CODE: + if ( items < 2 || items > 3 ) + { + Perl_croak( aTHX_ + "Usage: Parrot::Embed::find_global( interp, name, [ namespace ] )"); + } + + p_global = const_string( interp, SvPVX( ST(1) ) ); + + if ( items == 3 ) + namespace = ST(2); + else + namespace = &PL_sv_undef; + + if (namespace != &PL_sv_undef ) + { + p_namespace = const_string( interp, SvPVX( namespace ) ); + RETVAL = Parrot_find_global_s( interp, p_namespace, p_global ); + } + else + { + RETVAL = Parrot_find_global_cur( interp, p_global ); + } +OUTPUT: + RETVAL + +Parrot_PMC +call_sub( interp, sub, signature, argument ) + Parrot_Interp interp + Parrot_PMC sub + const char * signature + const char * argument +INIT: + Parrot_STRING arg_string; +CODE: + arg_string = const_string( interp, argument ); + RETVAL = Parrot_call_sub( interp, sub, signature, arg_string ); +OUTPUT: + RETVAL + +char * +get_string_from_pmc( interp, pmc ) + Parrot_Interp interp + Parrot_PMC pmc +CODE: + RETVAL = Parrot_PMC_get_cstring( interp, pmc ); +OUTPUT: + RETVAL + +Parrot_PMC +compile_string( interp, code ) + Parrot_Interp interp + char * code +INIT: + STRING *code_type; + STRING *error; +CODE: + code_type = const_string( interp, "PIR" ); + RETVAL = Parrot_compile_string( interp, code_type, code, &error ); +OUTPUT: + RETVAL --- ext/Parrot-Embed/t/embed.t (revision 20216) +++ ext/Parrot-Embed/t/embed.t (local) @@ -0,0 +1,105 @@ +#!perl + +use strict; +use warnings; + +use Test::More tests => 27; +use File::Spec; + +my $hello_pbc = File::Spec->catfile( 't', 'greet.pbc' ); + +my $module = 'Parrot::Embed'; +use_ok( $module ) or exit; + +diag( "Testing Parrot::Embed $Parrot::Embed::VERSION, Perl $], $^X" ); + +can_ok( $module, 'create_interpreter' ); +my $interp = Parrot::Embed::create_interpreter( 0 ); +ok( $interp, 'create_interpreter() should return a valid interpreter' ); + +my $i2 = Parrot::Embed::create_interpreter( $interp ); +isnt( $interp, $i2, '... but not always the same one' ); + +eval { Parrot::Embed::create_interpreter( 0, 1, 2 ) }; +like( $@, qr/Usage: .+create_interpreter/, + '... and should croak when given invalid arguments' ); + +can_ok( $module, 'read_bytecode' ); +my $bc = Parrot::Embed::read_bytecode( $interp, $hello_pbc ); +ok( $bc, 'read_bytecode() should work on valid file' ); + +TODO: +{ + local $TODO = 'Cannot catch Parrot exceptions yet'; + + # XXX - can you not see that I am serious? + close STDERR; + + eval { Parrot::Embed::read_bytecode( $interp, $0 ) }; + like( $@, qr/Can't unpack packfile/, '... but not on non-PBC file' ); + + eval { Parrot::Embed::read_bytecode( $interp, 'not_a_file' ) }; + like( $@, qr/Can't unpack packfile/, '... or a non-existent file' ); +} + +can_ok( $module, 'load_bytecode' ); +eval { Parrot::Embed::load_bytecode( $interp, $bc ) }; +is( $@, '', 'load_bytecode() should work on read bytecode' ); + +TODO: +{ + local $TODO = 'Cannot catch Parrot exceptions yet'; + + eval { Parrot::Embed::load_bytecode( $interp, undef ) }; + like( $@, qr/Invalid packfile/, '... but not on non-packfile' ); + +} + +can_ok( $module, 'find_global' ); +my $global_greet = Parrot::Embed::find_global( $interp, 'greet' ); +ok( $global_greet, + 'find_global() should return non-namespaced global, if found' ); + +ok( ! Parrot::Embed::find_global( $interp, 'goat' ), + '... or nothing, if there is no non-namespaced global of that name' ); + +my $else_greet = Parrot::Embed::find_global( $interp, 'greet', 'Elsewhere' ); +ok( $else_greet, '... or a namespaced global, if it exists in the namespace' ); +isnt( $global_greet, $else_greet, '... and definitely the namespaced version' ); + +ok( ! Parrot::Embed::find_global( $interp, 'goat', 'Elsewhere' ), + '... but again, not if there is no global of that name there' ); + +can_ok( $module, 'call_sub' ); +my $pmc = Parrot::Embed::call_sub( $interp, $global_greet, 'PS', 'Bob' ); +ok( $pmc, 'call_sub() should return a PMC, given that signature' ); + +can_ok( $module, 'get_string_from_pmc' ); +is( Parrot::Embed::get_string_from_pmc( $interp, $pmc ), 'Hello, Bob!', + '... containing a string returned as a PMC' ); + +$pmc = Parrot::Embed::call_sub( $interp, $else_greet, 'P', '' ); +is( Parrot::Embed::get_string_from_pmc( $interp, $pmc ), 'Hiya!', + '... calling the passed-in subroutine' ); + +can_ok( $module, 'compile_string' ); +my $eval = Parrot::Embed::compile_string( $interp, <<END_PIR ); +.sub foo + .param pmc in_string + + .local string string_s + string_s = in_string + string_s .= ' FOO ' + + .return( string_s ) +.end +END_PIR +ok( $eval, 'compile_string() should compile PIR code and return a PMC' ); + +ok( ! Parrot::Embed::compile_string( $i2, 'blah' ), + '... but only for valid PIR' ); + +my $foo = Parrot::Embed::find_global( $interp, 'foo' ); +$pmc = Parrot::Embed::call_sub( $interp, $foo, 'PS', 'BAR' ); +is( Parrot::Embed::get_string_from_pmc( $interp, $pmc ), 'BAR FOO ', + '... and compiled sub should work just like any other Sub pmc' ); Property changes on: ext/Parrot-Embed/t/embed.t ___________________________________________________________________ Name: svn:mime-type +text/plain --- ext/Parrot-Embed/t/greet.pir (revision 20216) +++ ext/Parrot-Embed/t/greet.pir (local) @@ -0,0 +1,20 @@ +.sub greet + .param pmc name + + .local string name_str + name_str = name + + .local pmc greeting + greeting = new .String + greeting = 'Hello, ' + greeting .= name_str + greeting .= '!' + + .return( greeting ) +.end + +.namespace [ 'Elsewhere' ] + +.sub greet + .return( 'Hiya!' ) +.end --- ext/Parrot-Embed/typemap (revision 20216) +++ ext/Parrot-Embed/typemap (local) @@ -0,0 +1,5 @@ +TYPEMAP +Parrot_Interp T_PTR +Parrot_PackFile T_PTR +Parrot_STRING T_PTR +Parrot_PMC T_PTR