Re: DBDI Status
[email protected] (Sentra Systems) Fri, 10 Jul 2009 23:45:46 +0100
| Newsgroups | perl.dbdi.dev |
|---|---|
| Message-ID | <[email protected]> |
--------------080602020509010106030806
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
Tim
Attached is a modified copy of the Generator::Std that emits current
perl6. It's been amended to add the correct sigils and 'use' statements.
Do you want to give it a try and see if it does what you want?
:)
Dave
Tim Bunce wrote:
> On Mon, Jul 06, 2009 at 02:08:17PM +0100, Sentra Systems wrote:
>
>> Tim
>>
>> Is there a particular reference implementation of java.sql(x) you're
>> planning on running the java2perl on? A quick google shows a reference API
>> but no obvious reference implementation.
>>
>
> Any implementation that has the classes will do. java2perl6 is only
> concerned with the class interfaces. It just runs javap on the class
> you give it, parses the class and interfaces definitions it outputs, and
> writes corresponding perl6 clasess and roles definitions.
>
> Try running
>
> java2perl6 --outdir jdbc --recurse --nest java.sql.Connection
>
> I've just checked in a file I had on my disk that lists all the
> java.sql and javax.sql classess, so you can run
>
> java2perl6 --outdir jdbc --recurse --nest $(cat jdbc_classes.txt)
>
> Tim.
>
>
>> Regards
>> Dave
>>
>>
>> Tim Bunce wrote:
>>
>>> On Sat, Jul 04, 2009 at 07:09:20PM +0100, Sentra Systems wrote:
>>>
>>>
>>>> Hi
>>>>
>>>>
>>> Hi Dave.
>>>
>>>
>>>
>>>> Has anything happened with a Parrot JDBC implementation?
>>>> Is Parrot stable enough yet?
>>>> Has anyone mapped out the minimun subset of JDBC that would be required
>>>> to get DBI working in Perl6?
>>>>
>>>>
>>> Here's the (current) plan...
>>>
>>> 1. Dust off java2perl6
>>> http://search.cpan.org/perldoc?java2perl6
>>> http://code.google.com/p/java2perl6/
>>> and update it to generate valid current perl6 code.
>>>
>>> 2. Add a type aliasing mechanism (ie "for the Java URL type use a Perl
>>> Str type") to java2perl6 so we don't have to implement loads of Java
>>> types before we can get started.
>>>
>>> 3. Write some kind of very dumb "Hello World" skeleton JDBC driver,
>>> as a proof of concept that uses the interfaces generated by java2perl
>>>
>>> 4. Refactor Simon Cozens's SQLite3 DBDI driver to use ('consume') the
>>> generated JDBC interfaces.
>>> http://dev.simon-cozens.org/6pan/browser/trunk/DBDI/DBDI/Driver/SQLite3.pm
>>> That's not working right now, so here's a cached version:
>>> http://google.com/search?q=cache:T8FN2WYvgm0J:dev.simon-cozens.org/6pan/browser/trunk/DBDI/DBDI/Driver/SQLite3.pm
>>>
>>> Making a move on this has been high on my list of pre-OSCON tasks
>>> but working on NYTProf has remained a higher priority (there are some
>>> great new features in the next release).
>>>
>>> If anyone wants to help out with 1 and 2, you'd be more than welcome!
>>> Send me your email address and I'll give you a commit bit.
>>>
>>> Tim.
>>>
>>>
>>>
>
>
--------------080602020509010106030806
Content-Type: application/x-perl;
name="Std.pm"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="Std.pm"
package Java::Javap::Generator::Std;
use strict; use warnings;
our $VERSION = 0.0.5;
use Template;
use Java::Javap;
use Java::Javap::TypeCast;
sub new {
my $class = shift;
my $tt_args = { POST_CHOMP => 1 };
my $self = bless { }, $class;
$self->tt_args_set( $tt_args );
return $self;
}
sub tt_args_set {
my $self = shift;
my $args = shift;
$self->{__TT_ARGS__} = $args;
}
sub tt_args {
my $self = shift;
return $self->{__TT_ARGS__};
}
sub generate {
my $self = shift;
my $params = shift;
my $class_file = $params->{ class_file };
my $ast = $params->{ ast };
my $javap_flags = $params->{ javap_flags };
my $template = $self->_get_template( $ast );
my $tt = Template->new( $self->tt_args );
my @modules = $self->_get_modules($ast);
my $tt_vars = {
ast => $ast,
gen_time => scalar localtime(),
version => $Java::Javap::VERSION,
class_file => $class_file,
type_caster=> Java::Javap::TypeCast->new(),
javap_flags=> $javap_flags,
modules => \@modules,
};
my $retval;
$tt->process( \$template, $tt_vars, \$retval ) || die $tt->error();
return $retval;
}
sub _get_template {
my $self = shift;
my $ast = shift;
my $method = "_get_template_for_$ast->{ class_or_interface }";
return $self->$method( $ast );
}
sub _get_modules {
my $self = shift;
my $ast = shift;
my %mod;
my %ignore = ( Str => 1, Int => 1, Bool => 1, void => 1);
use Data::Dumper::Simple;
#print STDERR Dumper($ast);
my $target;
foreach my $element (@{$ast->{contents}}) {
#print STDERR Dumper($element);
next unless $element->{body_element} eq 'method';
$target = Java::Javap::TypeCast->new()->cast($element->{returns}->{name});
next if $ignore{$target};
next if $target =~ /^$ast->{perl_qualified_name}\s*$/;
$mod{$target}++;
foreach my $arg (@{$element->{args}}) {
$target = Java::Javap::TypeCast->new()->cast($arg->{name});
next if $ignore{$target};
$mod{$target}++;
}
}
return keys %mod;
}
sub _get_template_for_interface {
return << 'EO_Template';
# This file was automatically generated [% gen_time +%]
# by java2perl6 [% version %] from decompiling
# [% class_file %] using command line flags:
# [% javap_flags +%]
[% FOREACH package IN modules %]
use [% package -%];
[% END %]
role [% ast.perl_qualified_name %] {
[% FOREACH element IN ast.contents %]
[% IF element.body_element == 'method' %]
[% IF ast.methods.${ element.name } > 1 %]
multi method [% element.name %](
[% ELSE %]
method [% element.name %](
[% END %][% arg_counter = 0 %]
[% FOREACH arg IN element.args %][% arg_counter = arg_counter + 1 %]
[% arg.array_text %][% type_caster.cast( arg.name ) %] [% arg.array_text.search('Array of') ? '@' : '$' %]v[% arg_counter %],
[% END %]
[% IF element.returns.name != 'void' %] --> [% element.returns.array_text %][% type_caster.cast( element.returns.name ) %][% END %] ) { ... }
[% END %]
[% END %]
}
EO_Template
}
sub _get_template_for_class {
return << 'EO_Class_Template';
# This file was automatically generated [% gen_time +%]
# by java2perl6 [% version %] from decompliling
# [% class_file %] using command line flags:
# [% javap_flags +%]
[% FOREACH package IN modules %]
use [% package -%];
[% END %]
class [% ast.perl_qualified_name %] {
[% FOREACH element IN ast.contents %]
[% IF element.body_element == 'method' %]
[% IF ast.methods.${ element.name } > 1 %]
multi method [% element.name %](
[% ELSE %]
method [% element.name %](
[% END %][% arg_counter = 0 %]
[% FOREACH arg IN element.args %][% arg_counter = arg_counter + 1 %]
[% arg.array_text %][% type_caster.cast( arg.name ) %] [% arg.array_text.search('Array of') ? '@' : '$' %]v[% arg_counter %],
[% END %]
[% IF element.returns.name != 'void' %] --> [% element.returns.array_text %][% type_caster.cast( element.returns.name ) %][% END %] ) { ... }
[% ELSE %]
[%# I spy with my little eye, I spy a constructor %]
[% END %]
[% END %]
}
EO_Class_Template
}
1;
=head1 NAME
Java::Javap::Generator::Std - uses TT to spit out Perl 6
=head1 SYNOPSIS
useJava::Javap::Generator;
my $gen = Java::Javap::Generator->get_generator( 'Std' );
my $output = $gen->generate(
{
$class_file => 'com.example.InterfaceName',
$ast => $tree,
$javap_flags => $javap_flags,
}
);
where C<$tree> is a Java::Javap abstract syntax tree (AST). Note that
parameters are named.
=head1 DESCRIPTION
This is a generator which uses TT to make output. It's templates are
strings inside this module. To change templates, subclass and override
C<_get_template_for_interface> and/or C<_get_template_for_class>.
=head1 METHODS
=over 4
=item get_generator
Call this as a class method on C<Java::Javap::Generator>. Pass it
C<Std> to ask it for an instance of this class.
=item generate
This is the workhorse of this module. It takes information about your
java .class file and generates Perl 6 code.
Parameters (these are named, pass them in a hashref, see below):
=over 4
=item class_file
for documentation, the name of the java .class file
=item ast
the syntax tree you got from the parser
=item javap_flags
for documentation, the flags used on the javap command line
=back
Use C<Java::Javap::Grammar> to generate the ast.
Example:
my $parser = Java::Javap::Grammar->new();
my $decomp = `javap com.example.SomeInterface`;
my $tree = $parser->comp_unit( $decomp );
my $jenny = Java::Javap::Generator->get_generator( 'Std' );
my $output = $jenny->generate(
{
class_file => $class_file,
ast => $tree,
}
);
=item new
For use by C<Java::Javap::Generator>. You could call it directly, that
would bypass the factory.
=item tt_args_set
By default, the TT objects used internally will have this TT constructor
parameter:
{ POST_CHOMP => 1 }
Use this accessor to change the TT constructor arguments. You may call this
at any time. The C<new> method uses this accessor.
Since C<generate> makes a new TT object for each call, any changes you
make via this method will apply to subsequent calls.
=item tt_args
Accessr for getting the TT constructor arguments. Mainly for internal
use.
=back
=head1 EXPORT
Nothing, it's all OO
=head2 SEE ALSO
Java::Javap::Generator
Java::Javap
Java::Javap::Grammar
java2perl6
=head1 AUTHOR
=head1 COPYRIGHT AND LICENSE
Copyright (C) 2007, Phil Crow
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.8.6 or,
at your option, any later version of Perl 5 you may have available.
=cut
--------------080602020509010106030806--