You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucy.apache.org by ma...@apache.org on 2009/08/18 02:02:00 UTC

svn commit: r805232 - in /lucene/lucy/trunk/boilerplater: lib/Boilerplater/Parser.pm lib/Boilerplater/Type/Composite.pm t/108-composite_type.t

Author: marvin
Date: Tue Aug 18 00:02:00 2009
New Revision: 805232

URL: http://svn.apache.org/viewvc?rev=805232&view=rev
Log:
Commit LUCY-17, adding Boilerplater::Type::Composite.

Added:
    lucene/lucy/trunk/boilerplater/lib/Boilerplater/Type/Composite.pm   (with props)
    lucene/lucy/trunk/boilerplater/t/108-composite_type.t   (with props)
Modified:
    lucene/lucy/trunk/boilerplater/lib/Boilerplater/Parser.pm

Modified: lucene/lucy/trunk/boilerplater/lib/Boilerplater/Parser.pm
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/boilerplater/lib/Boilerplater/Parser.pm?rev=805232&r1=805231&r2=805232&view=diff
==============================================================================
--- lucene/lucy/trunk/boilerplater/lib/Boilerplater/Parser.pm (original)
+++ lucene/lucy/trunk/boilerplater/lib/Boilerplater/Parser.pm Tue Aug 18 00:02:00 2009
@@ -13,6 +13,7 @@
 use Boilerplater::Type::VAList;
 use Boilerplater::Type::Arbitrary;
 use Boilerplater::Type::Object;
+use Boilerplater::Type::Composite;
 use Carp;
 
 our $grammar = <<'END_GRAMMAR';
@@ -37,6 +38,23 @@
     /([A-Z][A-Za-z0-9]+)(?!\w)/
     { $1 }
 
+type:
+      composite_type
+    | simple_type
+    { $item[1] }
+
+simple_type:
+      object_type
+    | primitive_type
+    | void_type
+    | va_list_type
+    | arbitrary_type
+    { $item[1] }
+
+composite_type:
+    simple_type type_postfix(s)
+    { Boilerplater::Parser->new_composite_type(\%item) }
+
 primitive_type:
       c_integer_type
     | chy_integer_type
@@ -103,6 +121,18 @@
 object_type_specifier:
     /[A-Z]+[A-Z0-9]*[a-z]+[A-Za-z0-9]*(?!\w)/
 
+type_postfix:
+      '*'
+      { '*' }
+    | '[' ']'
+      { '[]' }
+    | '[' constant_expression ']'
+      { "[$item[2]]" }
+
+constant_expression:
+      /\d+/
+    | /[A-Z_]+/
+
 END_GRAMMAR
 
 sub new { return shift->SUPER::new($grammar) }
@@ -151,6 +181,24 @@
     return Boilerplater::Type::Object->new(%args);
 }
 
+sub new_composite_type {
+    my ( undef, $item ) = @_;
+    my %args = (
+        child       => $item->{simple_type},
+        indirection => 0,
+    );
+    for my $postfix ( @{ $item->{'type_postfix(s)'} } ) {
+        if ( $postfix =~ /\[/ ) {
+            $args{array} ||= '';
+            $args{array} .= $postfix;
+        }
+        elsif ( $postfix eq '*' ) {
+            $args{indirection}++;
+        }
+    }
+    return Boilerplater::Type::Composite->new(%args);
+}
+
 sub new_parcel {
     my ( undef, $item ) = @_;
     Boilerplater::Parcel->singleton(

Added: lucene/lucy/trunk/boilerplater/lib/Boilerplater/Type/Composite.pm
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/boilerplater/lib/Boilerplater/Type/Composite.pm?rev=805232&view=auto
==============================================================================
--- lucene/lucy/trunk/boilerplater/lib/Boilerplater/Type/Composite.pm (added)
+++ lucene/lucy/trunk/boilerplater/lib/Boilerplater/Type/Composite.pm Tue Aug 18 00:02:00 2009
@@ -0,0 +1,125 @@
+use strict;
+use warnings;
+
+package Boilerplater::Type::Composite;
+use base qw( Boilerplater::Type );
+use Boilerplater::Util qw( verify_args a_isa_b );
+use Scalar::Util qw( blessed );
+use Carp;
+
+our %new_PARAMS = (
+    child       => undef,
+    indirection => undef,
+    array       => undef,
+);
+
+sub new {
+    my ( $either, %args ) = @_;
+    my $array = delete $args{array};
+    my $child = delete $args{child};
+    confess("Missing required param 'child'")
+        unless a_isa_b( $child, "Boilerplater::Type" );
+    verify_args( \%new_PARAMS, %args ) or confess $@;
+    my $self = $either->SUPER::new(%args);
+    $self->{child} = $child;
+    $self->{array} = $array;
+
+    # Default indirection to 0.
+    $self->{indirection} ||= 0;
+
+    # Cache C representation.
+    # NOTE: Array postfixes are NOT included.
+    my $string = $self->{child}->to_c;
+    for ( my $i = 0; $i < $self->{indirection}; $i++ ) {
+        $string .= '*';
+    }
+    $self->set_c_string($string);
+
+    return $self;
+}
+
+sub get_specifier { shift->{child}->get_specifier }
+sub get_array     { shift->{array} }
+sub is_composite  {1}
+
+sub equals {
+    my ( $self, $other ) = @_;
+    return 0 unless $self->{indirection} == $other->{indirection};
+    return 0 unless $self->{child}->equals( $other->{child} );
+    return 0 if ( $self->{array} xor $other->{array} );
+    return 0 if ( $self->{array} and $self->{array} ne $other->{array} );
+    return 1;
+}
+
+1;
+
+__END__
+
+__POD__
+
+=head1 NAME
+
+Boilerplater::Type::Composite - A composite type, e.g. Obj**.
+
+=head1 METHODS
+
+=head2 new
+
+    my $type = Boilerplater::Type::Composite->new(
+        specifier   => 'char',    # required
+        indirection => undef,     # default 0
+        array       => '[]',      # default undef,
+        const       => 1,         # default undef
+    );
+
+=over
+
+=item *
+
+B<specifier> - The name of the type, not including any indirection or array
+subscripts.  If the type begins with a capital letter, it will be assumed to
+be an object type.
+
+=item *
+
+B<indirection> - integer indicating level of indirection. Example: the C type
+"float**" has a specifier of "float" and indirection 2.
+
+=item *
+
+B<array> - A string describing an array postfix.  
+
+=item *
+
+B<const> - should be 1 if the type is const.
+
+=back
+
+=head2 get_array
+
+Accessor for the array string.
+
+=head2 get_specifier
+
+Overridden to return the child Type's specifier.
+
+=head1 COPYRIGHT AND LICENSE
+
+    /**
+     * Copyright 2009 The Apache Software Foundation
+     *
+     * Licensed under the Apache License, Version 2.0 (the "License");
+     * you may not use this file except in compliance with the License.
+     * You may obtain a copy of the License at
+     *
+     *     http://www.apache.org/licenses/LICENSE-2.0
+     *
+     * Unless required by applicable law or agreed to in writing, software
+     * distributed under the License is distributed on an "AS IS" BASIS,
+     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+     * implied.  See the License for the specific language governing
+     * permissions and limitations under the License.
+     */
+
+=cut
+

Propchange: lucene/lucy/trunk/boilerplater/lib/Boilerplater/Type/Composite.pm
------------------------------------------------------------------------------
    svn:eol-style = native

Added: lucene/lucy/trunk/boilerplater/t/108-composite_type.t
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/boilerplater/t/108-composite_type.t?rev=805232&view=auto
==============================================================================
--- lucene/lucy/trunk/boilerplater/t/108-composite_type.t (added)
+++ lucene/lucy/trunk/boilerplater/t/108-composite_type.t Tue Aug 18 00:02:00 2009
@@ -0,0 +1,78 @@
+use strict;
+use warnings;
+
+use Test::More tests => 24;
+use Boilerplater::Type::Object;
+use Boilerplater::Parser;
+
+my $parser = Boilerplater::Parser->new;
+
+is( $parser->type_postfix($_), $_, "postfix: $_" )
+    for ( '[]', '[A_CONSTANT]', '*' );
+is( $parser->type_postfix('[ FOO ]'), '[FOO]', "type_postfix: [ FOO ]" );
+
+my @composite_type_strings = (
+    qw(
+        char*
+        char**
+        char***
+        i32_t*
+        Obj**
+        boil_method_t[]
+        boil_method_t[1]
+        multi_dimensional_t[SOME][A_FEW]
+        ),
+    'char * * ',
+    'const Obj**',
+    'const void*',
+);
+
+for my $input (@composite_type_strings) {
+    isa_ok( $parser->composite_type($input),
+        "Boilerplater::Type::Composite", $input );
+}
+
+eval { my $type = Boilerplater::Type::Composite->new };
+like( $@, qr/child/i, "child required" );
+
+my $foo_type = Boilerplater::Type::Object->new( specifier => 'Foo' );
+my $composite_type = Boilerplater::Type::Composite->new(
+    child       => $foo_type,
+    indirection => 1,
+);
+is( $composite_type->get_specifier,
+    'Foo', "get_specifier delegates to child" );
+
+my $other = Boilerplater::Type::Composite->new(
+    child       => $foo_type,
+    indirection => 1,
+);
+ok( $composite_type->equals($other), "equals" );
+ok( $composite_type->is_composite,   "is_composite" );
+
+my $bar_type = Boilerplater::Type::Object->new( specifier => 'Bar' );
+my $bar_composite = Boilerplater::Type::Composite->new(
+    child       => $bar_type,
+    indirection => 1,
+);
+ok( !$composite_type->equals($bar_composite),
+    "equals spoiled by different child"
+);
+
+my $foo_array = $parser->composite_type("foo_t[]")
+    or die "Can't parse foo_t[]";
+is( $foo_array->get_array, '[]', "get_array" );
+unlike( $foo_array->to_c, qr/\[\]/, "array subscripts not included by to_c" );
+
+my $foo_array_array = $parser->composite_type("foo_t[][]")
+    or die "Can't parse foo_t[][]";
+ok( !$foo_array->equals($foo_array_array),
+    "equals spoiled by different array postfixes"
+);
+
+my $foo_star = $parser->composite_type("foo_t*")
+    or die "Can't parse foo_t*";
+my $foo_star_star = $parser->composite_type("foo_t**")
+    or die "Can't parse foo_t**";
+ok( !$foo_star->equals($foo_star_star),
+    "equals spoiled by different levels of indirection" );

Propchange: lucene/lucy/trunk/boilerplater/t/108-composite_type.t
------------------------------------------------------------------------------
    svn:eol-style = native